"); //NON-NLS
sb.append(key);
sb.append(" | "); //NON-NLS
sb.append(value);
@@ -238,6 +237,18 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.timezone"), image.getTimeZone());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.deviceId"), image.getDeviceId());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.internalid"), Long.toString(image.getId()));
+
+ // Add all the data source paths to the "Local Path" value cell.
+ String[] imagePaths = image.getPaths();
+ StringBuilder pathValues = new StringBuilder(" ");
+ pathValues.append(imagePaths[0]);
+ pathValues.append(" ");
+ for (int i=1; i < imagePaths.length; i++) {
+ pathValues.append("");
+ pathValues.append(imagePaths[i]);
+ pathValues.append(" ");
+ }
+ addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
}
setText(sb.toString());
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
index f2db7c2532..104c70ef6b 100755
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
@@ -457,10 +457,10 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
*/
private void initReader() {
viewReader = new SQLiteTableReader.Builder(sqliteDbFile)
- .onColumnNames((columnName) -> {
+ .forAllColumnNames((columnName) -> {
currentTableHeader.add(columnName);
})
- .forAll(getForAllStrategy()).build();
+ .forAllTableValues(getForAllStrategy()).build();
}
/**
@@ -510,8 +510,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
String tableName = (String) this.tablesDropdownList.getSelectedItem();
try (FileOutputStream out = new FileOutputStream(csvFile, false)) {
try (SQLiteTableReader sqliteStream = new SQLiteTableReader.Builder(sqliteDbFile)
- .onColumnNames(getColumnNameCSVStrategy(out))
- .forAll(getForAllCSVStrategy(out)).build()) {
+ .forAllColumnNames(getColumnNameCSVStrategy(out))
+ .forAllTableValues(getForAllCSVStrategy(out)).build()) {
totalColumnCount = sqliteStream.getColumnCount(tableName);
sqliteStream.read(tableName);
}
diff --git a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java
index 6272cc9ab7..36cf5a503c 100644
--- a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java
+++ b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java
@@ -357,6 +357,24 @@ public final class CoordinationService {
}
}
+ /**
+ * Deletes a specified node.
+ *
+ * @param category The desired category in the namespace.
+ * @param nodePath The node to be deleted.
+ *
+ * @throws CoordinationServiceException If there is an error deleting the
+ * node.
+ */
+ void deleteNode(CategoryNode category, String nodePath) throws CoordinationServiceException {
+ String fullNodePath = getFullyQualifiedNodePath(category, nodePath);
+ try {
+ curator.delete().forPath(fullNodePath);
+ } catch (Exception ex) {
+ throw new CoordinationServiceException(String.format("Failed to delete node %s", fullNodePath), ex);
+ }
+ }
+
/**
* Gets a list of the child nodes of a category in the namespace.
*
diff --git a/Core/src/org/sleuthkit/autopsy/core/Installer.java b/Core/src/org/sleuthkit/autopsy/core/Installer.java
index e45055b077..2f65b6099b 100644
--- a/Core/src/org/sleuthkit/autopsy/core/Installer.java
+++ b/Core/src/org/sleuthkit/autopsy/core/Installer.java
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.core;
import java.awt.Cursor;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -29,6 +30,8 @@ import java.util.logging.Handler;
import java.util.logging.Level;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
+import org.apache.commons.io.FileUtils;
+import org.openide.modules.InstalledFileLocator;
import org.openide.modules.ModuleInstall;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
@@ -285,12 +288,34 @@ public class Installer extends ModuleInstall {
File pythonModulesDir = new File(PlatformUtil.getUserPythonModulesPath());
pythonModulesDir.mkdir();
}
+
+ /**
+ * Make a folder in the config directory for Ocr Language Packs if one does
+ * not exist.
+ */
+ private static void ensureOcrLanguagePacksFolderExists() {
+ File ocrLanguagePacksDir = new File(PlatformUtil.getOcrLanguagePacksPath());
+ boolean createDirectory = ocrLanguagePacksDir.mkdir();
+
+ //If the directory did not exist, copy the tessdata folder over so we
+ //support english.
+ if(createDirectory) {
+ File tessdataDir = InstalledFileLocator.getDefault().locate(
+ "Tesseract-OCR/tessdata", Installer.class.getPackage().getName(), false);
+ try {
+ FileUtils.copyDirectory(tessdataDir, ocrLanguagePacksDir);
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Copying over default language packs for Tesseract failed.", ex);
+ }
+ }
+ }
@Override
public void restored() {
super.restored();
ensurePythonModulesFolderExists();
ensureClassifierFolderExists();
+ ensureOcrLanguagePacksFolderExists();
initJavaFx();
for (ModuleInstall mi : packageInstallers) {
try {
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index cdc54a12b6..299b0e18d4 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -173,9 +173,8 @@ ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Se
ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results
ViewPreferencesPanel.selectFileLabel.text=When selecting a file:
ViewPreferencesPanel.globalSettingsPanel.border.title=Global Settings
-ViewPreferencesPanel.translateNamesInTableRadioButton.text=Table
ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text=to reduce loading times
-ViewPreferencesPanel.translateTextLabel.text=Translate text in the:
+ViewPreferencesPanel.translateTextLabel.text=Translate text:
ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text=C(omments) and O(ccurences) columns
ViewPreferencesPanel.centralRepoLabel.text=Do not use Central Repository for:
ViewPreferencesPanel.hideOtherUsersTagsLabel.text=Hide other users' tags in the:
@@ -193,3 +192,4 @@ ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=For example, stay
ViewPreferencesPanel.keepCurrentViewerRadioButton.text=Stay on the same file viewer
ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=For example, change from Hex to Media when a JPEG is selected.
ViewPreferencesPanel.useBestViewerRadioButton.text=Change to the most specific file viewer
+ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text=Add column in result viewer for file name translation
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
index 8b56df7929..a348b49368 100755
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
@@ -144,11 +144,11 @@
+
-
@@ -203,7 +203,7 @@
-
+
@@ -397,14 +397,14 @@
-
+
-
+
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
index 4900a48a78..cdea98caf6 100755
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
@@ -80,10 +80,10 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
commentsOccurencesColumnsCheckbox.setSelected(UserPreferences.hideCentralRepoCommentsAndOccurrences());
hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags());
- translateNamesInTableRadioButton.setSelected(UserPreferences.displayTranslatedFileNames());
+ fileNameTranslationColumnCheckbox.setSelected(UserPreferences.displayTranslatedFileNames());
TextTranslationService tts = TextTranslationService.getInstance();
- translateNamesInTableRadioButton.setEnabled(tts.hasProvider());
+ fileNameTranslationColumnCheckbox.setEnabled(tts.hasProvider());
// Current Case Settings
boolean caseIsOpen = Case.isCaseOpen();
@@ -113,7 +113,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected());
UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected());
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
- UserPreferences.setDisplayTranslatedFileNames(translateNamesInTableRadioButton.isSelected());
+ UserPreferences.setDisplayTranslatedFileNames(fileNameTranslationColumnCheckbox.isSelected());
storeGroupItemsInTreeByDataSource();
@@ -166,7 +166,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
timeZoneList = new javax.swing.JList<>();
translateTextLabel = new javax.swing.JLabel();
commentsOccurencesColumnWrapAroundText = new javax.swing.JLabel();
- translateNamesInTableRadioButton = new javax.swing.JRadioButton();
+ fileNameTranslationColumnCheckbox = new javax.swing.JCheckBox();
currentCaseSettingsPanel = new javax.swing.JPanel();
groupByDataSourceCheckbox = new javax.swing.JCheckBox();
currentSessionSettingsPanel = new javax.swing.JPanel();
@@ -277,10 +277,10 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
org.openide.awt.Mnemonics.setLocalizedText(commentsOccurencesColumnWrapAroundText, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.commentsOccurencesColumnWrapAroundText.text")); // NOI18N
- org.openide.awt.Mnemonics.setLocalizedText(translateNamesInTableRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.translateNamesInTableRadioButton.text")); // NOI18N
- translateNamesInTableRadioButton.addActionListener(new java.awt.event.ActionListener() {
+ org.openide.awt.Mnemonics.setLocalizedText(fileNameTranslationColumnCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.fileNameTranslationColumnCheckbox.text")); // NOI18N
+ fileNameTranslationColumnCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
- translateNamesInTableRadioButtonActionPerformed(evt);
+ fileNameTranslationColumnCheckboxActionPerformed(evt);
}
});
@@ -329,11 +329,11 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGap(10, 10, 10)
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(fileNameTranslationColumnCheckbox)
.addComponent(keepCurrentViewerRadioButton)
.addComponent(useBestViewerRadioButton)
.addComponent(useLocalTimeRadioButton)
- .addComponent(useAnotherTimeRadioButton)
- .addComponent(translateNamesInTableRadioButton))))))
+ .addComponent(useAnotherTimeRadioButton))))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
globalSettingsPanelLayout.setVerticalGroup(
@@ -380,7 +380,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(translateTextLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(translateNamesInTableRadioButton)))
+ .addComponent(fileNameTranslationColumnCheckbox)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
@@ -487,14 +487,6 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
}
}//GEN-LAST:event_hideRejectedResultsCheckboxActionPerformed
- private void translateNamesInTableRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_translateNamesInTableRadioButtonActionPerformed
- if (immediateUpdates) {
- UserPreferences.setDisplayTranslatedFileNames(translateNamesInTableRadioButton.isSelected());
- } else {
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- }
- }//GEN-LAST:event_translateNamesInTableRadioButtonActionPerformed
-
private void timeZoneListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_timeZoneListValueChanged
if (immediateUpdates && useAnotherTimeRadioButton.isSelected()) {
UserPreferences.setTimeZoneForDisplays(timeZoneList.getSelectedValue().substring(11).trim());
@@ -593,6 +585,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
}
}//GEN-LAST:event_useBestViewerRadioButtonActionPerformed
+ private void fileNameTranslationColumnCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileNameTranslationColumnCheckboxActionPerformed
+ if (immediateUpdates) {
+ UserPreferences.setDisplayTranslatedFileNames(fileNameTranslationColumnCheckbox.isSelected());
+ } else {
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ }
+ }//GEN-LAST:event_fileNameTranslationColumnCheckboxActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel centralRepoLabel;
@@ -603,6 +603,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
private javax.swing.JCheckBox dataSourcesHideKnownCheckbox;
private javax.swing.JCheckBox dataSourcesHideSlackCheckbox;
private javax.swing.JLabel displayTimeLabel;
+ private javax.swing.JCheckBox fileNameTranslationColumnCheckbox;
private javax.swing.JPanel globalSettingsPanel;
private javax.swing.JCheckBox groupByDataSourceCheckbox;
private javax.swing.JLabel hideKnownFilesLabel;
@@ -614,7 +615,6 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
private javax.swing.JRadioButton keepCurrentViewerRadioButton;
private javax.swing.JLabel selectFileLabel;
private javax.swing.JList timeZoneList;
- private javax.swing.JRadioButton translateNamesInTableRadioButton;
private javax.swing.JLabel translateTextLabel;
private javax.swing.JRadioButton useAnotherTimeRadioButton;
private javax.swing.JRadioButton useBestViewerRadioButton;
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java
index f0a3086588..a785bdf638 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java
@@ -52,6 +52,7 @@ public class PlatformUtil {
private static final String PYTHON_MODULES_SUBDIRECTORY = "python_modules"; //NON-NLS
private static final String CLASSIFIERS_SUBDIRECTORY = "object_detection_classifiers"; //NON-NLS
+ private static final String OCR_LANGUAGE_SUBDIRECTORY = "ocr_language_packs"; //NON-NLS
private static String javaPath = null;
public static final String OS_NAME_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.nameUnknown");
public static final String OS_VERSION_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.verUnknown");
@@ -116,6 +117,15 @@ public class PlatformUtil {
public static String getUserPythonModulesPath() {
return getUserDirectory().getAbsolutePath() + File.separator + PYTHON_MODULES_SUBDIRECTORY;
}
+
+ /**
+ * Get root path where the user's Ocr language packs are stored.
+ *
+ * @return Absolute path to the Ocr language packs root directory.
+ */
+ public static String getOcrLanguagePacksPath() {
+ return getUserDirectory().getAbsolutePath() + File.separator + OCR_LANGUAGE_SUBDIRECTORY;
+ }
/**
* Get root path where the user's object detection classifiers are stored.
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java
index 2be988c7ed..59940d9e4c 100755
--- a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java
@@ -42,30 +42,14 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
- * Reads row by row through SQLite tables and performs user-defined actions on
- * the row values. Table values are processed by data type. Users configure
- * these actions for certain data types in the Builder. Example usage:
- *
- * SQLiteTableReader reader = new SQLiteTableReader.Builder(file)
- * .onInteger((i)
- * -> { System.out.println(i); })
- * .build();
- *
- * reader.read(tableName);
- *
- * or
- *
- * SQLiteTableReader reader = new SQLiteTableReader.Builder(file)
- * .onInteger(new Consumer() {
- * (atSymbol)Override public void accept(Integer i) {
- * System.out.println(i);
- * }
- * }).build();
+ * Reads through SQLite tables row by row. Functions performed on the
+ * data must be declared up front to the Builder. For example:
*
- * reader.reader(tableName);
- *
- * Invocation of read(String tableName) reads row by row. When an Integer is
- * encountered, its value will be passed to the Consumer that was defined above.
+ * tableReader = new SQLiteTableReader.Builder(file).forAllColumnNames(System.out::println);
+ * tableReader.read("Sample Table X");
+ *
+ * By declaring the functions up front, the SQLiteTableReader instance can stream the
+ * table contents in the most memory efficient manner.
*/
public class SQLiteTableReader implements AutoCloseable {
@@ -76,13 +60,13 @@ public class SQLiteTableReader implements AutoCloseable {
private final AbstractFile file;
- private Consumer onColumnNameAction;
- private Consumer onStringAction;
- private Consumer onLongAction;
- private Consumer onIntegerAction;
- private Consumer onFloatAction;
- private Consumer onBlobAction;
- private Consumer |