mirror of
https://github.com/elisspace/autopsy.git
synced 2026-09-05 18:14:30 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into smaller-installer
This commit is contained in:
@@ -52,7 +52,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
int dotIndex = name.lastIndexOf(".");
|
||||
if (dotIndex > 0) {
|
||||
String ext = name.substring(dotIndex).toLowerCase();
|
||||
|
||||
|
||||
// If this is an archive file we will listen for ingest events
|
||||
// that will notify us when new content has been identified.
|
||||
for (String s : FileTypeExtensions.getArchiveExtensions()) {
|
||||
@@ -69,7 +69,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
|
||||
@@ -375,58 +375,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
switch (type) {
|
||||
case TSK_WEB_BOOKMARK:
|
||||
return "ExtractedBookmarks";
|
||||
case TSK_WEB_COOKIE:
|
||||
return "ExtractedCookies";
|
||||
case TSK_WEB_HISTORY:
|
||||
return "ExtractedHistory";
|
||||
case TSK_WEB_DOWNLOAD:
|
||||
return "ExtractedDownloads";
|
||||
case TSK_INSTALLED_PROG:
|
||||
return "ExtractedPrograms";
|
||||
case TSK_RECENT_OBJECT:
|
||||
return "ExtractedRecent";
|
||||
case TSK_DEVICE_ATTACHED:
|
||||
return "ExtractedAttachedDevices";
|
||||
case TSK_WEB_SEARCH_QUERY:
|
||||
return "ExtractedSearch";
|
||||
case TSK_METADATA_EXIF:
|
||||
return "ExtractedMetadataExif";
|
||||
case TSK_EMAIL_MSG:
|
||||
return "ExtractedEmailMsg";
|
||||
case TSK_CONTACT:
|
||||
return "ExtractedContants";
|
||||
case TSK_MESSAGE:
|
||||
return "ExtractedMessages";
|
||||
case TSK_CALLLOG:
|
||||
return "ExtractedCallLog";
|
||||
case TSK_CALENDAR_ENTRY:
|
||||
return "ExtractedCalendar";
|
||||
case TSK_SPEED_DIAL_ENTRY:
|
||||
return "ExtractedSpeedDial";
|
||||
case TSK_BLUETOOTH_PAIRING:
|
||||
return "ExtractedBluetooth";
|
||||
case TSK_GPS_BOOKMARK:
|
||||
return "ExtractedGPSBookmarks";
|
||||
case TSK_GPS_LAST_KNOWN_LOCATION:
|
||||
return "ExtractedGPSLastLocation";
|
||||
case TSK_GPS_SEARCH:
|
||||
return "ExtractedGPSSearch";
|
||||
case TSK_SERVICE_ACCOUNT:
|
||||
return "ExtractedServiceAccount";
|
||||
case TSK_ENCRYPTION_DETECTED:
|
||||
return "ExtractedEncryption";
|
||||
case TSK_EXT_MISMATCH_DETECTED:
|
||||
return "ExtractedExtMismatch";
|
||||
case TSK_OS_INFO:
|
||||
return "ExtractedOS";
|
||||
case TSK_FACE_DETECTED:
|
||||
return "ExtractedFaceDetected";
|
||||
|
||||
}
|
||||
return "ExtractedContentType";
|
||||
return type.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -396,19 +396,18 @@ class SevenZipExtractor {
|
||||
if (colonIndex != -1) {
|
||||
// If alternate data stream is found, fix the name
|
||||
// so Windows doesn't choke on the colon character.
|
||||
useName = base + ext.substring(0, colonIndex);
|
||||
} else {
|
||||
switch (ext) {
|
||||
case ".gz": //NON-NLS
|
||||
useName = base;
|
||||
break;
|
||||
case ".tgz": //NON-NLS
|
||||
useName = base + ".tar"; //NON-NLS
|
||||
break;
|
||||
case ".bz2": //NON-NLS
|
||||
useName = base + ".bz2"; //NON-NLS
|
||||
break;
|
||||
}
|
||||
ext = ext.substring(0, colonIndex);
|
||||
}
|
||||
switch (ext) {
|
||||
case ".gz": //NON-NLS
|
||||
useName = base;
|
||||
break;
|
||||
case ".tgz": //NON-NLS
|
||||
useName = base + ".tar"; //NON-NLS
|
||||
break;
|
||||
case ".bz2": //NON-NLS
|
||||
useName = base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,41 +18,76 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.imagegallery;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableSet;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/** Singleton that manages set of fileIds, as well as last selected fileID.
|
||||
/**
|
||||
* Manages set of selected fileIds, as well as last selected fileID. Since some
|
||||
* actions (e.g. {@link ExtractAction} ) invoked through Image Gallery depend on
|
||||
* what is available in the Utilities.actionsGlobalContext() lookup, we maintain
|
||||
* that in sync with the local ObservableList based selection, via the
|
||||
* ImageGalleryTopComponent's ExplorerManager.
|
||||
*
|
||||
* NOTE: When we had synchronization on selected and lastSelectedProp we got
|
||||
* deadlocks with the tiles during selection
|
||||
*
|
||||
* TODO: should this be singleton? selections are only within a single group
|
||||
* now... -jm
|
||||
*/
|
||||
public class FileIDSelectionModel {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(FileIDSelectionModel.class.getName());
|
||||
|
||||
private static FileIDSelectionModel instance;
|
||||
|
||||
private final ObservableSet<Long> selected = FXCollections.observableSet();
|
||||
|
||||
private final ReadOnlyObjectWrapper<Long> lastSelectedProp = new ReadOnlyObjectWrapper<>();
|
||||
|
||||
public static synchronized FileIDSelectionModel getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FileIDSelectionModel();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
public FileIDSelectionModel(ImageGalleryController controller) {
|
||||
/**
|
||||
* Since some actions (e.g. {@link ExtractAction} ) invoked through
|
||||
* Image Gallery depend on what is available in the
|
||||
* Utilities.actionsGlobalContext() lookup, we maintain that in sync
|
||||
* with the local ObservableList based selection, via the
|
||||
* ImageGalleryTopComponent's ExplorerManager.
|
||||
*/
|
||||
selected.addListener((Observable observable) -> {
|
||||
Set<Long> fileIDs = ImmutableSet.copyOf(selected);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
ArrayList<FileNode> fileNodes = new ArrayList<>();
|
||||
for (Long id : fileIDs) {
|
||||
try {
|
||||
fileNodes.add(new FileNode(controller.getSleuthKitCase().getAbstractFileById(id)));
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to get abstract file by its ID", ex);
|
||||
}
|
||||
}
|
||||
FileNode[] fileNodeArray = fileNodes.stream().toArray(FileNode[]::new);
|
||||
Children.Array children = new Children.Array();
|
||||
children.add(fileNodeArray);
|
||||
|
||||
public FileIDSelectionModel() {
|
||||
super();
|
||||
ImageGalleryTopComponent etc = (ImageGalleryTopComponent) WindowManager.getDefault().findTopComponent(ImageGalleryTopComponent.PREFERRED_ID);
|
||||
etc.getExplorerManager().setRootContext(new AbstractNode(children));
|
||||
try {
|
||||
etc.getExplorerManager().setSelectedNodes(fileNodeArray);
|
||||
} catch (PropertyVetoException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Explorer manager selection was vetoed.", ex);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void toggleSelection(Long id) {
|
||||
@@ -110,6 +145,10 @@ public class FileIDSelectionModel {
|
||||
lastSelectedProp.set(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* expose the list of selected ids so that clients can listen for changes
|
||||
*/
|
||||
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||
public ObservableSet<Long> getSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public final class ImageGalleryController {
|
||||
|
||||
private final ReadOnlyBooleanWrapper metaDataCollapsed = new ReadOnlyBooleanWrapper(false);
|
||||
|
||||
private final FileIDSelectionModel selectionModel = FileIDSelectionModel.getInstance();
|
||||
private final FileIDSelectionModel selectionModel = new FileIDSelectionModel(this);
|
||||
|
||||
private DBWorkerThread dbWorkerThread;
|
||||
|
||||
@@ -167,7 +167,6 @@ public final class ImageGalleryController {
|
||||
}
|
||||
|
||||
public synchronized FileIDSelectionModel getSelectionModel() {
|
||||
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import javafx.scene.control.Menu;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.util.Utilities;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.imagegallery.FileIDSelectionModel;
|
||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableTagsManager;
|
||||
@@ -66,7 +65,7 @@ public class AddDrawableTagAction extends AddTagAction {
|
||||
|
||||
@Override
|
||||
public void addTag(TagName tagName, String comment) {
|
||||
Set<Long> selectedFiles = new HashSet<>(FileIDSelectionModel.getInstance().getSelected());
|
||||
Set<Long> selectedFiles = new HashSet<>(controller.getSelectionModel().getSelected());
|
||||
addTagsToFiles(tagName, comment, selectedFiles);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.imagegallery.FileIDSelectionModel;
|
||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
|
||||
@@ -69,13 +68,12 @@ public class CategorizeAction extends AddTagAction {
|
||||
|
||||
@Override
|
||||
public void addTag(TagName tagName, String comment) {
|
||||
Set<Long> selectedFiles = new HashSet<>(FileIDSelectionModel.getInstance().getSelected());
|
||||
Set<Long> selectedFiles = new HashSet<>(controller.getSelectionModel().getSelected());
|
||||
addTagsToFiles(tagName, comment, selectedFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles) {
|
||||
|
||||
Logger.getAnonymousLogger().log(Level.INFO, "categorizing{0} as {1}", new Object[]{selectedFiles.toString(), tagName.getDisplayName()});
|
||||
|
||||
for (Long fileID : selectedFiles) {
|
||||
@@ -129,7 +127,6 @@ public class CategorizeAction extends AddTagAction {
|
||||
final CategoryManager categoryManager = controller.getCategoryManager();
|
||||
final DrawableTagsManager tagsManager = controller.getTagsManager();
|
||||
|
||||
|
||||
try {
|
||||
DrawableFile<?> file = controller.getFileFromId(fileID); //drawable db
|
||||
final List<ContentTag> fileTags = tagsManager.getContentTagsByContent(file);
|
||||
|
||||
@@ -54,6 +54,8 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupManager;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupSortBy;
|
||||
import static org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupSortBy.GROUP_BY_VALUE;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentTag;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@@ -475,6 +477,32 @@ public final class DrawableDB {
|
||||
return con.isClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the names of the hashsets that the given fileID belongs to
|
||||
*
|
||||
* @param fileID the fileID to get all the Hashset names for
|
||||
*
|
||||
* @return a set of hash set names, each of which the given file belongs to
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*
|
||||
*
|
||||
* //TODO: this is mostly a cut and paste from *
|
||||
* AbstractContent.getHashSetNames, is there away to dedupe?
|
||||
*/
|
||||
Set<String> getHashSetsForFile(long fileID) throws TskCoreException {
|
||||
Set<String> hashNames = new HashSet<>();
|
||||
ArrayList<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, fileID);
|
||||
|
||||
for (BlackboardArtifact a : artifacts) {
|
||||
List<BlackboardAttribute> attributes = a.getAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
|
||||
for (BlackboardAttribute attr : attributes) {
|
||||
hashNames.add(attr.getValueString());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(hashNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all the hash set names used in the db
|
||||
*
|
||||
|
||||
@@ -44,7 +44,7 @@ public class HashSetManager {
|
||||
*/
|
||||
private Set<String> getHashSetsForFileHelper(long fileID) {
|
||||
try {
|
||||
return db.getFileFromID(fileID).getHashSetNames();
|
||||
return db.getHashSetsForFile(fileID);
|
||||
} catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashSetManager.class.getName()).log(Level.SEVERE, "Failed to get Hash Sets for file", ex);
|
||||
return Collections.emptySet();
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
|
||||
import static org.sleuthkit.autopsy.imagegallery.gui.drawableviews.DrawableTileBase.globalSelectionModel;
|
||||
import org.sleuthkit.datamodel.AbstractContent;
|
||||
|
||||
/**
|
||||
@@ -63,7 +62,7 @@ public class DrawableTile extends DrawableTileBase {
|
||||
imageView.fitHeightProperty().bind(Toolbar.getDefault(getController()).sizeSliderValue());
|
||||
imageView.fitWidthProperty().bind(Toolbar.getDefault(getController()).sizeSliderValue());
|
||||
|
||||
globalSelectionModel.lastSelectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
selectionModel.lastSelectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
try {
|
||||
setEffect(Objects.equals(newValue, getFileID()) ? LAST_SELECTED_EFFECT : null);
|
||||
} catch (java.lang.IllegalStateException ex) {
|
||||
@@ -84,7 +83,7 @@ public class DrawableTile extends DrawableTileBase {
|
||||
@Override
|
||||
protected void updateSelectionState() {
|
||||
super.updateSelectionState();
|
||||
final boolean lastSelected = Objects.equals(globalSelectionModel.lastSelectedProperty().get(), getFileID());
|
||||
final boolean lastSelected = Objects.equals(selectionModel.lastSelectedProperty().get(), getFileID());
|
||||
Platform.runLater(() -> {
|
||||
setEffect(lastSelected ? LAST_SELECTED_EFFECT : null);
|
||||
});
|
||||
|
||||
@@ -92,7 +92,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
protected static final Image followUpIcon = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_red.png");
|
||||
protected static final Image followUpGray = new Image("org/sleuthkit/autopsy/imagegallery/images/flag_gray.png");
|
||||
|
||||
protected static final FileIDSelectionModel globalSelectionModel = FileIDSelectionModel.getInstance();
|
||||
protected final FileIDSelectionModel selectionModel;
|
||||
private static ContextMenu contextMenu;
|
||||
|
||||
/**
|
||||
@@ -143,9 +143,9 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
*/
|
||||
protected DrawableTileBase(GroupPane groupPane, final ImageGalleryController controller) {
|
||||
super(controller);
|
||||
|
||||
this.groupPane = groupPane;
|
||||
globalSelectionModel.getSelected().addListener((Observable observable) -> updateSelectionState());
|
||||
selectionModel = controller.getSelectionModel();
|
||||
selectionModel.getSelected().addListener((Observable observable) -> updateSelectionState());
|
||||
|
||||
//set up mouse listener
|
||||
//TODO: split this between DrawableTile and SingleDrawableViewBase
|
||||
@@ -159,7 +159,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
case PRIMARY:
|
||||
if (t.getClickCount() == 1) {
|
||||
if (t.isControlDown()) {
|
||||
globalSelectionModel.toggleSelection(fileID);
|
||||
selectionModel.toggleSelection(fileID);
|
||||
} else {
|
||||
groupPane.makeSelection(t.isShiftDown(), fileID);
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
break;
|
||||
case SECONDARY:
|
||||
if (t.getClickCount() == 1) {
|
||||
if (globalSelectionModel.isSelected(fileID) == false) {
|
||||
if (selectionModel.isSelected(fileID) == false) {
|
||||
groupPane.makeSelection(false, fileID);
|
||||
}
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
getFile().ifPresent(file -> {
|
||||
if (followUpToggle.isSelected() == true) {
|
||||
try {
|
||||
globalSelectionModel.clearAndSelect(file.getId());
|
||||
selectionModel.clearAndSelect(file.getId());
|
||||
new AddDrawableTagAction(getController()).addTag(getController().getTagsManager().getFollowUpTagName(), "");
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Failed to add Follow Up tag. Could not load TagName.", ex);
|
||||
@@ -339,7 +339,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
||||
*/
|
||||
protected void updateSelectionState() {
|
||||
getFile().ifPresent(file -> {
|
||||
final boolean selected = globalSelectionModel.isSelected(file.getId());
|
||||
final boolean selected = selectionModel.isSelected(file.getId());
|
||||
Platform.runLater(() -> setBorder(selected ? SELECTED_BORDER : UNSELECTED_BORDER));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class GroupPane extends BorderPane {
|
||||
new KeyFrame(Duration.millis(400), new KeyValue(DROP_SHADOW.radiusProperty(), 15, Interpolator.LINEAR))
|
||||
);
|
||||
|
||||
private static final FileIDSelectionModel globalSelectionModel = FileIDSelectionModel.getInstance();
|
||||
private final FileIDSelectionModel selectionModel;
|
||||
private static final List<KeyCode> categoryKeyCodes = Arrays.asList(KeyCode.NUMPAD0, KeyCode.NUMPAD1, KeyCode.NUMPAD2, KeyCode.NUMPAD3, KeyCode.NUMPAD4, KeyCode.NUMPAD5,
|
||||
KeyCode.DIGIT0, KeyCode.DIGIT1, KeyCode.DIGIT2, KeyCode.DIGIT3, KeyCode.DIGIT4, KeyCode.DIGIT5);
|
||||
|
||||
@@ -257,6 +257,7 @@ public class GroupPane extends BorderPane {
|
||||
|
||||
public GroupPane(ImageGalleryController controller) {
|
||||
this.controller = controller;
|
||||
this.selectionModel = controller.getSelectionModel();
|
||||
nextGroupAction = new NextUnseenGroup(controller);
|
||||
backAction = new Back(controller);
|
||||
forwardAction = new Forward(controller);
|
||||
@@ -303,7 +304,7 @@ public class GroupPane extends BorderPane {
|
||||
slideShowPane.disposeContent();
|
||||
}
|
||||
slideShowPane = null;
|
||||
this.scrollToFileID(globalSelectionModel.lastSelectedProperty().get());
|
||||
this.scrollToFileID(selectionModel.lastSelectedProperty().get());
|
||||
}
|
||||
|
||||
public DrawableGroup getGroup() {
|
||||
@@ -311,7 +312,7 @@ public class GroupPane extends BorderPane {
|
||||
}
|
||||
|
||||
private void selectAllFiles() {
|
||||
globalSelectionModel.clearAndSelectAll(getGroup().fileIds());
|
||||
selectionModel.clearAndSelectAll(getGroup().fileIds());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,7 +364,7 @@ public class GroupPane extends BorderPane {
|
||||
if (slideShowPane != null) {
|
||||
slideShowPane.getFileID().ifPresent(fileID -> {
|
||||
if (newValue) {
|
||||
FileIDSelectionModel.getInstance().clearAndSelect(fileID);
|
||||
selectionModel.clearAndSelect(fileID);
|
||||
new CategorizeAction(controller).addTag(controller.getTagsManager().getTagName(cat), "");
|
||||
}
|
||||
});
|
||||
@@ -428,10 +429,10 @@ public class GroupPane extends BorderPane {
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
spacer.setMinWidth(Region.USE_PREF_SIZE);
|
||||
|
||||
FileIDSelectionModel.getInstance().getSelected().addListener((Observable o) -> {
|
||||
selectionModel.getSelected().addListener((Observable o) -> {
|
||||
Platform.runLater(() -> {
|
||||
catSelectedSplitMenu.setDisable(FileIDSelectionModel.getInstance().getSelected().isEmpty());
|
||||
tagSelectedSplitMenu.setDisable(FileIDSelectionModel.getInstance().getSelected().isEmpty());
|
||||
catSelectedSplitMenu.setDisable(selectionModel.getSelected().isEmpty());
|
||||
tagSelectedSplitMenu.setDisable(selectionModel.getSelected().isEmpty());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -491,7 +492,7 @@ public class GroupPane extends BorderPane {
|
||||
|
||||
//listen to toggles and update view state
|
||||
slideShowToggle.setOnAction((ActionEvent t) -> {
|
||||
activateSlideShowViewer(globalSelectionModel.lastSelectedProperty().get());
|
||||
activateSlideShowViewer(selectionModel.lastSelectedProperty().get());
|
||||
});
|
||||
|
||||
tileToggle.setOnAction((ActionEvent t) -> {
|
||||
@@ -543,7 +544,7 @@ public class GroupPane extends BorderPane {
|
||||
switch (t.getButton()) {
|
||||
case PRIMARY:
|
||||
if (t.getClickCount() == 1) {
|
||||
globalSelectionModel.clearSelection();
|
||||
selectionModel.clearSelection();
|
||||
if (contextMenu != null) {
|
||||
contextMenu.hide();
|
||||
}
|
||||
@@ -554,7 +555,7 @@ public class GroupPane extends BorderPane {
|
||||
if (t.getClickCount() == 1) {
|
||||
selectAllFiles();
|
||||
}
|
||||
if (globalSelectionModel.getSelected().isEmpty() == false) {
|
||||
if (selectionModel.getSelected().isEmpty() == false) {
|
||||
if (contextMenu == null) {
|
||||
contextMenu = buildContextMenu();
|
||||
}
|
||||
@@ -590,7 +591,7 @@ public class GroupPane extends BorderPane {
|
||||
|
||||
//listen to tile selection and make sure it is visible in scroll area
|
||||
//TODO: make sure we are testing complete visability not just bounds intersection
|
||||
globalSelectionModel.lastSelectedProperty().addListener((observable, oldFileID, newFileId) -> {
|
||||
selectionModel.lastSelectedProperty().addListener((observable, oldFileID, newFileId) -> {
|
||||
if (groupViewMode.get() == GroupViewMode.SLIDE_SHOW) {
|
||||
slideShowPane.setFile(newFileId);
|
||||
} else {
|
||||
@@ -736,11 +737,11 @@ public class GroupPane extends BorderPane {
|
||||
endIndex = IntStream.of(0, selectionAnchorIndex, endIndex).max().getAsInt();
|
||||
List<Long> subList = grouping.get().fileIds().subList(Math.max(0, startIndex), Math.min(endIndex, grouping.get().fileIds().size()) + 1);
|
||||
|
||||
globalSelectionModel.clearAndSelectAll(subList.toArray(new Long[subList.size()]));
|
||||
globalSelectionModel.select(newFileID);
|
||||
selectionModel.clearAndSelectAll(subList.toArray(new Long[subList.size()]));
|
||||
selectionModel.select(newFileID);
|
||||
} else {
|
||||
selectionAnchorIndex = null;
|
||||
globalSelectionModel.clearAndSelect(newFileID);
|
||||
selectionModel.clearAndSelect(newFileID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +797,7 @@ public class GroupPane extends BorderPane {
|
||||
switch (t.getCode()) {
|
||||
case SHIFT:
|
||||
if (selectionAnchorIndex == null) {
|
||||
selectionAnchorIndex = grouping.get().fileIds().indexOf(globalSelectionModel.lastSelectedProperty().get());
|
||||
selectionAnchorIndex = grouping.get().fileIds().indexOf(selectionModel.lastSelectedProperty().get());
|
||||
}
|
||||
t.consume();
|
||||
break;
|
||||
@@ -827,7 +828,7 @@ public class GroupPane extends BorderPane {
|
||||
break;
|
||||
case SPACE:
|
||||
if (groupViewMode.get() == GroupViewMode.TILE) {
|
||||
activateSlideShowViewer(globalSelectionModel.lastSelectedProperty().get());
|
||||
activateSlideShowViewer(selectionModel.lastSelectedProperty().get());
|
||||
} else {
|
||||
activateTileViewer();
|
||||
}
|
||||
@@ -839,7 +840,7 @@ public class GroupPane extends BorderPane {
|
||||
selectAllFiles();
|
||||
t.consume();
|
||||
}
|
||||
if (globalSelectionModel.getSelected().isEmpty() == false) {
|
||||
if (selectionModel.getSelected().isEmpty() == false) {
|
||||
switch (t.getCode()) {
|
||||
case NUMPAD0:
|
||||
case DIGIT0:
|
||||
@@ -871,7 +872,7 @@ public class GroupPane extends BorderPane {
|
||||
}
|
||||
|
||||
private void handleArrows(KeyEvent t) {
|
||||
Long lastSelectFileId = globalSelectionModel.lastSelectedProperty().get();
|
||||
Long lastSelectFileId = selectionModel.lastSelectedProperty().get();
|
||||
|
||||
int lastSelectedIndex = lastSelectFileId != null
|
||||
? grouping.get().fileIds().indexOf(lastSelectFileId)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
@@ -89,7 +89,7 @@ To this:
|
||||
Note the removal of the leading number symbol-this uncomments that entry.
|
||||
<br><br>
|
||||
|
||||
8. Still in <i>"C:\Program Files\PostgreSQL\9.4\data\postgresql.conf"</i>, find the entry named _max_connections_ and set it to the number of suggested connections for your configuration. A rule of thumb is add 100 connections for each Automated Ingest Node and 100 connections for each Reviewer node you plan to have in the network. More information is available at 5.1.1. See the screenshot below.
|
||||
8. Still in <i id="max_connections">"C:\Program Files\PostgreSQL\9.4\data\postgresql.conf"</i>, find the entry named _max_connections_ and set it to the number of suggested connections for your configuration. A rule of thumb is add 100 connections for each Automated Ingest Node and 100 connections for each Reviewer node you plan to have in the network. More information is available at 5.1.1. See the screenshot below.
|
||||
<br><br>
|
||||
\image html maxConnections.PNG
|
||||
<br><br>
|
||||
|
||||
@@ -35,12 +35,11 @@ The following steps will configure Solr to run using an account that will have a
|
||||
5. When the installation completes, clear the "Launch Bitnami Apache Solr Stack Now?" checkbox and click _Finish_.
|
||||
|
||||
\subsection install_solr_config Solr Configuration
|
||||
1. Stop _solrApache_ and _solrJetty_ services by pressing _Start_, typing _services.msc_, pressing _Enter_, and locating the _solrApache_ and _solrJetty_ Windows services. Select the services one at a time, and press _Stop the service_ once for each of them. If the service is already stopped and there is no _Stop the service_ available, this is okay.
|
||||
1. Stop the _solrJetty_ service by pressing _Start_, typing _services.msc_, pressing _Enter_, and locating the _solrJetty_ Windows service. Select the service and press _Stop the service_. If the service is already stopped and there is no _Stop the service_ available, this is okay.
|
||||
2. Edit the <i>C:\\Bitnami\\solr-4.10.3-0\\apache-solr\\scripts\\serviceinstall.bat</i> script. You need administrator permission to change this file. The easiest way around this is to save a copy on the Desktop, edit the Desktop version, and copy the new one back over the top of the old. Windows will ask for permission to overwrite the old file; allow it. You should make the following changes to this file:
|
||||
<br>
|
||||
<br>
|
||||
- Add the following options in the _JvmOptions_ section of the line that begins with <i>"C:\Bitnami\solr-4.10.3-0/apache-solr\scripts\prunsrv.exe"</i> :
|
||||
+ <i>++JvmOptions=-DzkRun</i>
|
||||
+ <i>++JvmOptions=-Dcollection.configName=AutopsyConfig</i>
|
||||
+ <i>++JvmOptions=-Dbootstrap_confdir="C:\Bitnami\solr-4.10.3-0\apache-solr\solr\configsets\AutopsyConfig\conf"</i>
|
||||
- Replace the path to <i>JavaHome</i> with the path to your 64-bit version of the JRE. If you do not know the path, the correct _JavaHome_ path can be obtained by running the command <i>"where java"</i> from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the <i>"bin"</i> folder in the path you place into the _JavaHome_ variable. A correct example of the final result will look something like this: <i>--JavaHome="C:\Program Files\Java\jre1.8.0_45"</i>
|
||||
@@ -66,24 +65,7 @@ The added part is highlighted in yellow below. Ensure that it is inside the <i>\
|
||||
<br>
|
||||
\image html transientcache.PNG
|
||||
<br><br>
|
||||
4. Edit the file <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr\zoo.cfg"</i> to increase the _tickTime_ value to 15000 as shown in the screenshot below.
|
||||
<br><br>
|
||||
\image html tickTime.PNG
|
||||
<br><br>
|
||||
5. Create a folder on your local hard drive named _C:/Bitnami/zookeeper_
|
||||
6. Edit the file <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr\zoo.cfg"</i> to set the value <i>dataDir=C:/Bitnami/zookeeper</i> as shown in the screenshot below.
|
||||
<br><br>
|
||||
\image html dataDir.PNG
|
||||
<br><br>
|
||||
7. Edit the file <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr\zoo.cfg"</i> to add the lines <i>autopurge.snapRetainCount=3</i> and <i>autopurge.purgeInterval=1</i> as shown in the screenshot below.
|
||||
<br><br>
|
||||
\image html autoPurge.PNG
|
||||
<br><br>
|
||||
8. Install _ZkJanitor_ by right clicking on _InstallJanitor.bat_, and selecting "Run as administrator". You should see a confirmation that ZkJanitor is installed, as shown in the screenshot below.
|
||||
<br><br>
|
||||
\image html InstallZkJanitor.PNG
|
||||
<br><br>
|
||||
9. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\resources/log4j.properties"</i> to configure Solr log settings:
|
||||
4. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\resources/log4j.properties"</i> to configure Solr log settings:
|
||||
- Increase the log rotation size threshold (_log4j\.appender\.file\.MaxFileSize_) from 4MB to 100MB.
|
||||
- Remove the _CONSOLE_ appender from the _log4j\.rootLogger_ line.
|
||||
<br><br>
|
||||
@@ -93,9 +75,9 @@ The log file should end up looking like this (modified lines are highlighted in
|
||||
<br><br>
|
||||
\image html log4j.PNG
|
||||
<br><br>
|
||||
10. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
11. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
12. Start a Windows command prompt as administrator by pressing _Start_, typing _command_, right clicking on _Command Prompt_, and clicking on _Run as administrator_. Then run the following command to install the _solrJetty_ service:
|
||||
5. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
6. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
7. Start a Windows command prompt as administrator by pressing _Start_, typing _command_, right clicking on _Command Prompt_, and clicking on _Run as administrator_. Then run the following command to install the _solrJetty_ service:
|
||||
<br><br>
|
||||
<i>cmd /c C:\\Bitnami\\solr-4.10.3-0\\apache-solr\\scripts\\serviceinstall.bat INSTALL</i>
|
||||
<br><br>
|
||||
@@ -103,13 +85,13 @@ The log file should end up looking like this (modified lines are highlighted in
|
||||
<br><br>
|
||||
\image html solrinstall1.PNG
|
||||
<br><br>
|
||||
13. Press _Start_, type _services.msc_, and press _Enter_. Find _solrJetty_. If the service is running, press _Stop the service_, then double click it, and switch to the _Log On_ tab to change the logon credentials to a user who will have access to read and write the primary shared drive. If the machine is on a domain, the Account Name will be in the form of _DOMAINNAME\\username_ as shown in the example below. Note that in the screenshot below, the domain name is _DOMAIN_ and the user name is _username_. These are just examples, not real values.
|
||||
8. Press _Start_, type _services.msc_, and press _Enter_. Find _solrJetty_. If the service is running, press _Stop the service_, then double click it, and switch to the _Log On_ tab to change the logon credentials to a user who will have access to read and write the primary shared drive. If the machine is on a domain, the Account Name will be in the form of _DOMAINNAME\\username_ as shown in the example below. Note that in the screenshot below, the domain name is _DOMAIN_ and the user name is _username_. These are just examples, not real values.
|
||||
<br><br>
|
||||
\image html solrinstall2.PNG
|
||||
<br>
|
||||
If the machine is on a domain, **make sure** to select the domain with the mouse by going to the _Log On_ tab, clicking _Browse_, then clicking _Locations_ and selecting the domain of interest. Then enter the user name desired and press _Check Names_. When that completes, press _OK_, type in the password once for each box and press _OK_. You may see "The user has been granted the log on as a service right."
|
||||
|
||||
14. You should be able to see the Solr service in a web browser via the URL <i>http://localhost:8983/solr/#/</i> as shown in the screenshot below.
|
||||
9. You should be able to see the Solr service in a web browser via the URL <i>http://localhost:8983/solr/#/</i> as shown in the screenshot below.
|
||||
<br><br>
|
||||
\image html solrinstall3.PNG
|
||||
<br><br>
|
||||
|
||||
@@ -2,11 +2,24 @@
|
||||
<!--
|
||||
This file is an example configuration file for regression.py.
|
||||
|
||||
List of tags:
|
||||
image: An image to be ingested
|
||||
build: the path to the build.xml file
|
||||
indir: the path to input directory
|
||||
outdir: the path to output directory
|
||||
global_csv: path to global csv file
|
||||
golddir: the path to gold directory
|
||||
jenkins: can be set to True or False. If enabled, check for diffdir
|
||||
diffdir: (only if jenkins tag is true) the diff directory
|
||||
timing: can be set to True or False. If enabled, record the timing.
|
||||
|
||||
NOTE: Make sure to use windows style for paths!
|
||||
|
||||
None of these tags are mandatory, and if nothing is provided the file will be
|
||||
looked over and ignored.
|
||||
|
||||
If the -i tag is not set as an argument, images from the input directory will
|
||||
be tested after the images provided in this file are.
|
||||
If the -i flag is not set as an argument to regression.py, images from
|
||||
the input directory will be tested after the images provided in this file are.
|
||||
By default the input directory will be ./input, however if the indir tag
|
||||
is set, that value will become the new input directory. This directory must
|
||||
have the required hash/keyword search files, and if -i is not set, this
|
||||
@@ -23,6 +36,7 @@ All paths given to the script have to be full paths from the root directoy.
|
||||
NOTE: Some image formats can only be parsed by Autopsy using a Windows path
|
||||
(i.e. X:\this\is\a\windows\path /this/is/not/a/windows/path)
|
||||
It is up to the user to distinguish between the paths when adding to this file.
|
||||
|
||||
-->
|
||||
|
||||
<Properties>
|
||||
|
||||
@@ -84,15 +84,16 @@ Day = 0
|
||||
|
||||
|
||||
def usage():
|
||||
print ("-f PATH single file")
|
||||
print ("-r rebuild")
|
||||
print ("-l PATH path to config file")
|
||||
print ("-u Ignore unallocated space")
|
||||
print ("-k Do not delete SOLR index")
|
||||
print ("-o PATH path to output folder for Diff files")
|
||||
print ("-v verbose mode")
|
||||
print ("-e ARG Enable exception mode with given string")
|
||||
print ("-h help")
|
||||
print ("-f PATH single file")
|
||||
print ("-r rebuild")
|
||||
print ("-b run both compare and rebuild")
|
||||
print ("-l PATH path to config file")
|
||||
print ("-u Ignore unallocated space")
|
||||
print ("-k Do not delete SOLR index")
|
||||
print ("-o PATH path to output folder for Diff files")
|
||||
print ("-v verbose mode")
|
||||
print ("-e ARG Enable exception mode with given string")
|
||||
print ("-h help")
|
||||
|
||||
#----------------------#
|
||||
# Main #
|
||||
@@ -103,10 +104,12 @@ def main():
|
||||
parse_result = args.parse()
|
||||
# The arguments were given wrong:
|
||||
if not parse_result:
|
||||
return
|
||||
Errors.print_error("The arguments were given wrong")
|
||||
exit(1)
|
||||
test_config = TestConfiguration(args)
|
||||
|
||||
TestRunner.run_tests(test_config)
|
||||
exit(0)
|
||||
|
||||
|
||||
class TestRunner(object):
|
||||
@@ -125,6 +128,7 @@ class TestRunner(object):
|
||||
Reports.html_add_images(test_config.html_log, test_config.images)
|
||||
|
||||
# Test each image
|
||||
gold_exists = False
|
||||
logres =[]
|
||||
for test_data in test_data_list:
|
||||
Errors.clear_print_logs()
|
||||
@@ -133,6 +137,11 @@ class TestRunner(object):
|
||||
Errors.print_error(msg)
|
||||
Errors.print_error(test_data.gold_archive)
|
||||
continue
|
||||
|
||||
# At least one test has gold
|
||||
gold_exists = True
|
||||
|
||||
|
||||
|
||||
# Analyze the given image
|
||||
TestRunner._run_autopsy_ingest(test_data)
|
||||
@@ -140,9 +149,12 @@ class TestRunner(object):
|
||||
# Generate HTML report
|
||||
Reports.write_html_foot(test_config.html_log)
|
||||
|
||||
# Either copy the data or compare the data
|
||||
# Either copy the data or compare the data or both
|
||||
if test_config.args.rebuild:
|
||||
TestRunner.rebuild(test_data)
|
||||
elif test_config.args.both:
|
||||
logres.append(TestRunner._compare_results(test_data))
|
||||
TestRunner.rebuild(test_data)
|
||||
else:
|
||||
logres.append(TestRunner._compare_results(test_data))
|
||||
|
||||
@@ -152,9 +164,11 @@ class TestRunner(object):
|
||||
time.sleep(10)
|
||||
TestRunner._cleanup(test_data)
|
||||
|
||||
if all([ test_data.overall_passed for test_data in test_data_list ]):
|
||||
pass
|
||||
else:
|
||||
if not gold_exists:
|
||||
Errors.print_error("No image had any gold; Regression did not run")
|
||||
exit(1)
|
||||
|
||||
if not all([ test_data.overall_passed for test_data in test_data_list ]):
|
||||
html = open(test_config.html_log)
|
||||
Errors.add_errors_out(html.name)
|
||||
html.close()
|
||||
@@ -179,13 +193,17 @@ class TestRunner(object):
|
||||
TestRunner._run_ant(test_data)
|
||||
time.sleep(2) # Give everything a second to process
|
||||
|
||||
# exit if .db was not created
|
||||
if not file_exists(test_data.get_db_path(DBType.OUTPUT)):
|
||||
Errors.print_error("Autopsy did not run properly; No .db file was created")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
# Dump the database before we diff or use it for rebuild
|
||||
TskDbDiff.dump_output_db(test_data.get_db_path(DBType.OUTPUT), test_data.get_db_dump_path(DBType.OUTPUT),
|
||||
test_data.get_sorted_data_path(DBType.OUTPUT))
|
||||
except sqlite3.OperationalError as e:
|
||||
print("Ingest did not run properly.",
|
||||
"Make sure no other instances of Autopsy are open and try again.")
|
||||
Errors.print_error("Ingest did not run properly.\nMake sure no other instances of Autopsy are open and try again.")
|
||||
sys.exit(1)
|
||||
|
||||
# merges logs into a single log for later diff / rebuild
|
||||
@@ -396,8 +414,7 @@ class TestRunner(object):
|
||||
test_data.ant.append("-Dkeyword_path=" + test_config.keyword_path)
|
||||
test_data.ant.append("-Dnsrl_path=" + test_config.nsrl_path)
|
||||
test_data.ant.append("-Dgold_path=" + test_config.gold)
|
||||
test_data.ant.append("-Dout_path=" +
|
||||
make_local_path(test_data.output_path))
|
||||
test_data.ant.append("-Dout_path=" + make_local_path(test_data.output_path))
|
||||
if test_config.jenkins:
|
||||
test_data.ant.append("-Ddiff_dir="+ test_config.diff_dir)
|
||||
test_data.ant.append("-Dignore_unalloc=" + "%s" % test_config.args.unallocated)
|
||||
@@ -657,6 +674,7 @@ class TestConfiguration(object):
|
||||
"""
|
||||
self.args = args
|
||||
# Paths:
|
||||
self.output_parent_dir = make_path("..", "output", "results")
|
||||
self.output_dir = ""
|
||||
self.input_dir = make_local_path("..","input")
|
||||
self.gold = make_path("..", "output", "gold")
|
||||
@@ -703,17 +721,19 @@ class TestConfiguration(object):
|
||||
counts = {}
|
||||
if parsed_config.getElementsByTagName("indir"):
|
||||
self.input_dir = parsed_config.getElementsByTagName("indir")[0].getAttribute("value").encode().decode("utf_8")
|
||||
if parsed_config.getElementsByTagName("outdir"):
|
||||
self.output_parent_dir = parsed_config.getElementsByTagName("outdir")[0].getAttribute("value").encode().decode("utf_8")
|
||||
if parsed_config.getElementsByTagName("global_csv"):
|
||||
self.global_csv = parsed_config.getElementsByTagName("global_csv")[0].getAttribute("value").encode().decode("utf_8")
|
||||
self.global_csv = make_local_path(self.global_csv)
|
||||
if parsed_config.getElementsByTagName("golddir"):
|
||||
self.gold = parsed_config.getElementsByTagName("golddir")[0].getAttribute("value").encode().decode("utf_8")
|
||||
if parsed_config.getElementsByTagName("jenkins"):
|
||||
self.jenkins = True
|
||||
if parsed_config.getElementsByTagName("diffdir"):
|
||||
self.jenkins = parsed_config.getElementsByTagName("jenkins")[0].getAttribute("value").encode().decode("utf_8")
|
||||
if self.jenkins and parsed_config.getElementsByTagName("diffdir"):
|
||||
self.diff_dir = parsed_config.getElementsByTagName("diffdir")[0].getAttribute("value").encode().decode("utf_8")
|
||||
else:
|
||||
self.jenkins = False
|
||||
else:
|
||||
self.jenkins = False
|
||||
if parsed_config.getElementsByTagName("timing"):
|
||||
self.timing = parsed_config.getElementsByTagName("timing")[0].getAttribute("value").encode().decode("utf_8")
|
||||
self._init_imgs(parsed_config)
|
||||
@@ -727,9 +747,9 @@ class TestConfiguration(object):
|
||||
|
||||
def _init_logs(self):
|
||||
"""Setup output folder, logs, and reporting infrastructure."""
|
||||
if(not dir_exists(make_path("..", "output", "results"))):
|
||||
os.makedirs(make_path("..", "output", "results",))
|
||||
self.output_dir = make_path("..", "output", "results", time.strftime("%Y.%m.%d-%H.%M.%S"))
|
||||
if not dir_exists(self.output_parent_dir):
|
||||
os.makedirs(self.output_parent_dir)
|
||||
self.output_dir = make_path(self.output_parent_dir, time.strftime("%Y.%m.%d-%H.%M.%S"))
|
||||
os.makedirs(self.output_dir)
|
||||
self.csv = make_local_path(self.output_dir, "CSV.txt")
|
||||
self.html_log = make_path(self.output_dir, "AutopsyTestCase.html")
|
||||
@@ -757,6 +777,9 @@ class TestConfiguration(object):
|
||||
image_count = len(self.images)
|
||||
|
||||
# Sanity check to see if there are obvious gold images that we are not testing
|
||||
if not dir_exists(self.gold):
|
||||
Errors.print_error("Gold folder does not exist")
|
||||
sys.exit(1)
|
||||
gold_count = 0
|
||||
for file in os.listdir(self.gold):
|
||||
if not(file == 'tmp'):
|
||||
@@ -885,7 +908,7 @@ class TestResultsDiffer(object):
|
||||
(subprocess.check_output(["diff", '-r', '-N', '-x', '*.png', '-x', '*.ico', '--ignore-matching-lines',
|
||||
'HTML Report Generated on \|Autopsy Report for case \|Case:\|Case Number:'
|
||||
'\|Examiner:', gold_report_path, output_report_path]))
|
||||
print_report("", "REPORT COMPARISON", "The test reports matched the gold reports")
|
||||
print_report("", "REPORT COMPARISON", "The test html reports matched the gold reports")
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
if e.returncode == 1:
|
||||
@@ -1644,6 +1667,7 @@ class Args(object):
|
||||
self.single = False
|
||||
self.single_file = ""
|
||||
self.rebuild = False
|
||||
self.both = False
|
||||
self.list = False
|
||||
self.config_file = ""
|
||||
self.unallocated = False
|
||||
@@ -1672,6 +1696,9 @@ class Args(object):
|
||||
elif(arg == "-r" or arg == "--rebuild"):
|
||||
print("Running in rebuild mode.\n")
|
||||
self.rebuild = True
|
||||
elif(arg == "-b" or arg == "--both"):
|
||||
print("Comparing then creating gold")
|
||||
self.both = True
|
||||
elif(arg == "-l" or arg == "--list"):
|
||||
try:
|
||||
arg = sys.argv.pop(0)
|
||||
@@ -1709,7 +1736,7 @@ class Args(object):
|
||||
elif arg == "-o" or arg == "--output":
|
||||
try:
|
||||
arg = sys.argv.pop(0)
|
||||
if not os.path.exists(arg):
|
||||
if not dir_exists(arg):
|
||||
print("Invalid output folder given.\n")
|
||||
return False
|
||||
nxtproc.append(arg)
|
||||
@@ -1995,3 +2022,4 @@ if __name__ == "__main__":
|
||||
main()
|
||||
else:
|
||||
print("We only support Windows and Cygwin at this time.")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -44,8 +44,6 @@ class TskDbDiff(object):
|
||||
self.output_dir = output_dir
|
||||
self.gold_bb_dump = gold_bb_dump
|
||||
self.gold_dump = gold_dump
|
||||
self._generate_gold_dump = True
|
||||
self._generate_gold_bb_dump = True
|
||||
self._bb_dump_diff = ""
|
||||
self._dump_diff = ""
|
||||
self._bb_dump = ""
|
||||
@@ -61,12 +59,6 @@ class TskDbDiff(object):
|
||||
|
||||
self._init_diff()
|
||||
|
||||
# generate the gold database dumps if necessary
|
||||
if self._generate_gold_dump:
|
||||
TskDbDiff._dump_output_db_nonbb(self.gold_db_file, self.gold_dump)
|
||||
if self._generate_gold_bb_dump:
|
||||
TskDbDiff._dump_output_db_bb(self.gold_db_file, self.gold_bb_dump)
|
||||
|
||||
# generate the output database dumps (both DB and BB)
|
||||
TskDbDiff._dump_output_db_nonbb(self.output_db_file, self._dump)
|
||||
TskDbDiff._dump_output_db_bb(self.output_db_file, self._bb_dump)
|
||||
|
||||
Reference in New Issue
Block a user