Extract FileTypeUtils from ImageGalleryModule

remove FileTypeIcons
remove deprecated method from GroupManager
This commit is contained in:
jmillman
2015-07-01 15:58:37 -04:00
parent 64e887b098
commit beb8efaa6a
8 changed files with 248 additions and 302 deletions
@@ -1,106 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.imagegallery;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.net.URL;
import java.util.Objects;
import java.util.logging.Level;
import javafx.scene.image.Image;
import org.apache.commons.lang3.StringUtils;
import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
import org.sleuthkit.autopsy.imagegallery.datamodel.ImageFile;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
*/
public class FileTypeIcons {
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png");
private static final Image IMAGE_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png");
public static Image getGenericVideoThumbnail() {
return VIDEO_ICON;
}
private Image getGenericImageIcon() {
return IMAGE_ICON;
}
static private FileTypeIcons instance;
static public synchronized FileTypeIcons FileTypeIconsgetInstance() {
if (Objects.isNull(instance)) {
instance = new FileTypeIcons();
}
return instance;
}
private final LoadingCache<String, Image> iconCache = CacheBuilder.newBuilder().build(CacheLoader.from(this::getImageForMimeType));
Image getImageForMimeType(String mimeType) {
try {
final MimeType forName = MimeTypes.getDefaultMimeTypes().forName(mimeType);
for (String extension : forName.getExtensions()) {
final URL iconURL = ImageFile.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/mimeTypes/"
+ StringUtils.strip(extension, ".") + "-icon-16x16.png");
if (Objects.isNull(iconURL)) {
return new Image(iconURL.toExternalForm(), true);
}
}
} catch (MimeTypeException ex) {
Logger.getLogger(FileTypeIcons.class.getName()).log(Level.WARNING, "Failed to get MimeType for " + mimeType);
}
return null;
}
Image getFileTypeIcon(DrawableFile<?> file) {
if (Objects.nonNull(fileTypeDetector)) {
try {
String fileType1 = fileTypeDetector.getFileType(file.getAbstractFile());
return iconCache.getUnchecked(fileType1);
} catch (TskCoreException ex) {
Logger.getLogger(FileTypeIcons.class.getName()).log(Level.WARNING, "Failed to get file type for " + file.getName());
}
}
return file.isVideo() ? getGenericVideoThumbnail() : getGenericImageIcon();
}
private final FileTypeDetector fileTypeDetector;
private FileTypeIcons() {
FileTypeDetector ftd = null;
try {
ftd = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
Exceptions.printStackTrace(ex);
}
fileTypeDetector = ftd;
}
}
@@ -0,0 +1,161 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.imagegallery;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
*/
public enum FileTypeUtils {
instance;
private static final Set<String> supportedMimeTypes = new HashSet<>();
public static Set<String> getAllSupportedMimeTypes() {
return Collections.unmodifiableSet(supportedMimeTypes);
}
private static final Set<String> imageExtensions = new HashSet<>();
static final Set<String> videoExtensions = new HashSet<>();
static final Set<String> supportedExtensions;
static {
imageExtensions.addAll(Stream.of(ImageIO.getReaderFileSuffixes())
.map(String::toLowerCase)
.collect(Collectors.toList()));
imageExtensions.addAll(Arrays.asList("bmp", "gif", "jpg", "jpeg",
"png", "tga", "psd", "tif", "tiff", "yuv", "ico", "ai", "svg"));
videoExtensions.addAll(Arrays.asList("fxm", "aaf", "3gp", "asf", "avi", "m1v", "m2v", "m4v",
"mp4", "mov", "mpeg", "mpg", "mpe", "mp4", "rm", "wmv",
"mpv", "flv", "swf"));
supportedExtensions = Sets.union(imageExtensions, videoExtensions);
supportedMimeTypes.addAll(Stream.of(ImageIO.getReaderMIMETypes())
.map(String::toLowerCase)
.collect(Collectors.toList()));
supportedMimeTypes.addAll(Arrays.asList("application/x-shockwave-flash"));
}
private static FileTypeDetector FILE_TYPE_DETECTOR;
private static final Logger LOGGER = Logger.getLogger(FileTypeUtils.class.getName());
static Set<String> getAllSupportedExtensions() {
return Collections.unmodifiableSet(supportedExtensions);
}
static synchronized FileTypeDetector getFileTypeDetector() {
if (isNull(FILE_TYPE_DETECTOR)) {
try {
FILE_TYPE_DETECTOR = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize File Type Detector, will fall back on extensions in some situations.", ex);
}
}
return FILE_TYPE_DETECTOR;
}
/** is the given file supported by image analyzer? ie, does it have a
* supported mime type (image/*, or video/*). if no mime type is found, does
* it have a supported extension or a jpeg/png header?
*
* @param file
*
* @return true if this file is supported or false if not
*/
public static Boolean isDrawable(AbstractFile file) {
return hasDrawableMimeType(file).orElseGet(() -> {
return FileTypeUtils.supportedExtensions.contains(file.getNameExtension())
|| ImageUtils.isJpegFileHeader(file)
|| ImageUtils.isPngFileHeader(file);
});
}
/**
*
*
* @param file
*
* @return an Optional containg:
* True if the file has an image or video mime type.
* False if a non image/video mimetype.
* null empty Optional if a mimetype could not be detected.
*/
static Optional<Boolean> hasDrawableMimeType(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String mimeType = fileTypeDetector.getFileType(file);
if (isNull(mimeType)) {
return Optional.empty();
} else {
mimeType = mimeType.toLowerCase();
return Optional.of(mimeType.startsWith("image/")
|| mimeType.startsWith("video/")
|| supportedMimeTypes.contains(mimeType));
}
}
} catch (TskCoreException ex) {
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex);
}
return Optional.empty();
}
/** @param file
*
* @return true if the given file has a video mime type (video/*,
* application/x-shockwave-flash, etc) or, if no mimetype is
* available, a video extension.
*/
public static boolean isVideoFile(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String mimeType = fileTypeDetector.getFileType(file);
if (nonNull(mimeType)) {
mimeType = mimeType.toLowerCase();
return mimeType.startsWith("video/") || supportedMimeTypes.contains(mimeType);
}
}
} catch (TskCoreException ex) {
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex);
}
return FileTypeUtils.videoExtensions.contains(file.getNameExtension());
}
}
@@ -22,6 +22,7 @@ import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
@@ -204,7 +205,7 @@ public final class ImageGalleryController {
//if we just turned on listening and a case is open and that case is not up to date
if (newValue && !oldValue && Case.existsCurrentCase() && ImageGalleryModule.isDrawableDBStale(Case.getCurrentCase())) {
//populate the db
queueDBWorkerTask(new CopyAnalyzedFiles());
queueDBWorkerTask(new CopyAnalyzedFiles(instance, db, sleuthKitCase));
}
});
@@ -456,11 +457,11 @@ public final class ImageGalleryController {
if (isListeningEnabled()) {
if (ImageGalleryModule.isDrawableAndNotKnown(file)) {
//this file should be included and we don't already know about it from hash sets (NSRL)
queueDBWorkerTask(new UpdateFileTask(file));
} else if (ImageGalleryModule.getAllSupportedExtensions().contains(file.getNameExtension())) {
queueDBWorkerTask(new UpdateFileTask(file, db));
} else if (FileTypeUtils.getAllSupportedExtensions().contains(file.getNameExtension())) {
//doing this check results in fewer tasks queued up, and faster completion of db update
//this file would have gotten scooped up in initial grab, but actually we don't need it
queueDBWorkerTask(new RemoveFileTask(file));
queueDBWorkerTask(new RemoveFileTask(file, db));
}
} else { //TODO: keep track of what we missed for later
setStale(true);
@@ -501,7 +502,7 @@ public final class ImageGalleryController {
getTagsManager().fireTagDeletedEvent(tagDeletedEvent);
}
break;
}
});
}
@@ -518,8 +519,6 @@ public final class ImageGalleryController {
return tagsManager;
}
// @@@ REVIEW IF THIS SHOLD BE STATIC...
//TODO: concept seems like the controller deal with how much work to do at a given time
// @@@ review this class for synchronization issues (i.e. reset and cancel being called, add, etc.)
@@ -651,14 +650,20 @@ public final class ImageGalleryController {
static public abstract class FileTask extends InnerTask {
private final AbstractFile file;
private final DrawableDB taskDB;
public DrawableDB getTaskDB() {
return taskDB;
}
public AbstractFile getFile() {
return file;
}
public FileTask(AbstractFile f) {
public FileTask(AbstractFile f, DrawableDB taskDB) {
super();
this.file = f;
this.taskDB = taskDB;
}
}
@@ -666,10 +671,10 @@ public final class ImageGalleryController {
/**
* task that updates one file in database with results from ingest
*/
private class UpdateFileTask extends FileTask {
static private class UpdateFileTask extends FileTask {
public UpdateFileTask(AbstractFile f) {
super(f);
public UpdateFileTask(AbstractFile f, DrawableDB taskDB) {
super(f, taskDB);
}
/**
@@ -678,8 +683,8 @@ public final class ImageGalleryController {
@Override
public void run() {
try {
DrawableFile<?> drawableFile = DrawableFile.create(getFile(), true, db.isVideoFile(getFile()));
db.updateFile(drawableFile);
DrawableFile<?> drawableFile = DrawableFile.create(getFile(), true, getTaskDB().isVideoFile(getFile()));
getTaskDB().updateFile(drawableFile);
} catch (NullPointerException ex) {
// This is one of the places where we get many errors if the case is closed during processing.
// We don't want to print out a ton of exceptions if this is the case.
@@ -693,10 +698,10 @@ public final class ImageGalleryController {
/**
* task that updates one file in database with results from ingest
*/
private class RemoveFileTask extends FileTask {
static private class RemoveFileTask extends FileTask {
public RemoveFileTask(AbstractFile f) {
super(f);
public RemoveFileTask(AbstractFile f, DrawableDB taskDB) {
super(f, taskDB);
}
/**
@@ -705,7 +710,7 @@ public final class ImageGalleryController {
@Override
public void run() {
try {
db.removeFile(getFile().getId());
getTaskDB().removeFile(getFile().getId());
} catch (NullPointerException ex) {
// This is one of the places where we get many errors if the case is closed during processing.
// We don't want to print out a ton of exceptions if this is the case.
@@ -720,13 +725,42 @@ public final class ImageGalleryController {
/**
* Task that runs when image gallery listening is (re) enabled.
*
* Uses the presence of TSK_FILE_TYPE_SIG attributes as a approximation to
* 'analyzed'. Grabs all files with supported image/video mime types, and
* adds them to the Drawable DB
* Grabs all files with supported image/video mime types or extensions, and
* adds them to the Drawable DB. Uses the presence of TSK_FILE_TYPE_SIG
* attributes as a approximation to 'analyzed'.
*
*/
private class CopyAnalyzedFiles extends InnerTask {
static private class CopyAnalyzedFiles extends InnerTask {
final private String DRAWABLE_QUERY = "name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "'";
private final ImageGalleryController controller;
private final DrawableDB taskDB;
private final SleuthkitCase tskCase;
public CopyAnalyzedFiles(ImageGalleryController controller, DrawableDB taskDB, SleuthkitCase tskCase) {
this.controller = controller;
this.taskDB = taskDB;
this.tskCase = tskCase;
}
static private final String FILE_EXTESNION_CLAUSE = "(name LIKE '%."
+ StringUtils.join(FileTypeUtils.getAllSupportedExtensions(),
"' or name LIKE '%.")
+ "')";
static private final String MIMETYPE_CLAUSE
= "blackboard_attributes.value_text LIKE "
+ StringUtils.join(FileTypeUtils.getAllSupportedMimeTypes(),
" OR blackboard_attributes.value_text LIKE ");
static private final String DRAWABLE_QUERY = FILE_EXTESNION_CLAUSE + " OR tsk_files.obj_id IN ("
+ "SELECT tsk_files.obj_id from tsk_files , blackboard_artifacts, blackboard_attributes"
+ " WHERE blackboard_artifacts.obj_id = tsk_files.obj_id"
+ " AND blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id"
+ " AND blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()
+ " AND (blackboard_attributes.value_text LIKE 'video/%'"
+ " OR blackboard_attributes.value_text LIKE 'image/%'"
+ " OR " + MIMETYPE_CLAUSE
+ " )";
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("populating analyzed image/video database");
@@ -737,21 +771,13 @@ public final class ImageGalleryController {
try {
//grab all files with supported extension or detected mime types
final List<AbstractFile> files = getSleuthKitCase().findAllFilesWhere(DRAWABLE_QUERY + " OR tsk_files.obj_id IN ("
+ "SELECT tsk_files.obj_id from tsk_files , blackboard_artifacts, blackboard_attributes"
+ " WHERE blackboard_artifacts.obj_id = tsk_files.obj_id"
+ " AND blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id"
+ " AND blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID()
+ " AND (blackboard_attributes.value_text LIKE 'video/%'"
+ " OR blackboard_attributes.value_text LIKE 'image/%'"
+ " OR blackboard_attributes.value_text LIKE 'application/x-shockwave-flash'))");
final List<AbstractFile> files = tskCase.findAllFilesWhere(DRAWABLE_QUERY);
progressHandle.switchToDeterminate(files.size());
updateProgress(0.0);
//do in transaction
DrawableDB.DrawableTransaction tr = db.beginTransaction();
DrawableDB.DrawableTransaction tr = taskDB.beginTransaction();
int units = 0;
for (final AbstractFile f : files) {
if (cancelled) {
@@ -763,22 +789,22 @@ public final class ImageGalleryController {
final boolean known = f.getKnown() == TskData.FileKnown.KNOWN;
if (known) {
db.removeFile(f.getId(), tr); //remove known files
taskDB.removeFile(f.getId(), tr); //remove known files
} else {
final Boolean hasMimeType = ImageGalleryModule.hasDrawableMimeType(f);
if (hasMimeType == null) {
if (ImageGalleryModule.isDrawable(f)) {
//no mime type but supported => add as not analyzed
db.insertFile(DrawableFile.create(f, false, db.isVideoFile(f)), tr);
} else {
//no mime type, not supported => remove ( should never get here)
db.removeFile(f.getId(), tr);
final Optional<Boolean> hasMimeType = FileTypeUtils.hasDrawableMimeType(f);
if (hasMimeType.isPresent()) {
if (hasMimeType.get()) { // supported mimetype => analyzed
taskDB.updateFile(DrawableFile.create(f, true, taskDB.isVideoFile(f)), tr);
} else { //unsupported mimtype => analyzed but shouldn't include
taskDB.removeFile(f.getId(), tr);
}
} else {
if (hasMimeType) { // supported mimetype => analyzed
db.updateFile(DrawableFile.create(f, true, db.isVideoFile(f)), tr);
} else { //unsupported mimtype => analyzed but shouldn't include
db.removeFile(f.getId(), tr);
if (FileTypeUtils.isDrawable(f)) {
//no mime type but supported => add as not analyzed
taskDB.insertFile(DrawableFile.create(f, false, taskDB.isVideoFile(f)), tr);
} else {
//no mime type, not supported => remove ( should never get here)
taskDB.removeFile(f.getId(), tr);
}
}
}
@@ -797,7 +823,7 @@ public final class ImageGalleryController {
updateProgress(1.0);
progressHandle.start();
db.commitTransaction(tr, true);
taskDB.commitTransaction(tr, true);
} catch (TskCoreException ex) {
Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex);
@@ -809,9 +835,8 @@ public final class ImageGalleryController {
updateMessage("");
updateProgress(-1.0);
setStale(false);
controller.setStale(false);
}
}
/**
@@ -831,7 +856,7 @@ public final class ImageGalleryController {
* check for supported images
*/
// (name like '.jpg' or name like '.png' ...)
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(ImageGalleryModule.getAllSupportedExtensions(), "' or name LIKE '%.") + "') ";
private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' or name LIKE '%.") + "') ";
private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database");
@@ -50,27 +50,6 @@ public class ImageGalleryModule {
return MODULE_NAME;
}
private static final Set<String> videoExtensions
= Sets.newHashSet("aaf", "3gp", "asf", "avi", "m1v", "m2v", "m4v", "mp4",
"mov", "mpeg", "mpg", "mpe", "mp4", "rm", "wmv", "mpv",
"flv", "swf");
private static final Set<String> imageExtensions = Sets.newHashSet(ImageIO.getReaderFileSuffixes());
private static final Set<String> supportedExtensions = Sets.union(imageExtensions, videoExtensions);
private static FileTypeDetector FILE_TYPE_DETECTOR;
private static synchronized FileTypeDetector getFileTypeDetector() {
if (isNull(FILE_TYPE_DETECTOR)) {
try {
FILE_TYPE_DETECTOR = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize File Type Detector, will fall back on extensions in some situations.", ex);
}
}
return FILE_TYPE_DETECTOR;
}
/**
* get the Path to the Case's ImageGallery ModuleOutput subfolder; ie
@@ -120,69 +99,9 @@ public class ImageGalleryModule {
}
}
static Set<String> getAllSupportedExtensions() {
return Collections.unmodifiableSet(supportedExtensions);
}
/** is the given file suported by image analyzer: ie, does it have a
* supported mime type (image/*, or video/*). if no mime type is found, does
* it have a supported extension or a jpeg/png header.
*
* @param file
*
* @return true if this file is supported or false if not
*/
static Boolean isDrawable(AbstractFile file) {
//if there were no file type attributes, fall back on extension and jpeg header
return Optional.ofNullable(hasDrawableMimeType(file)).orElseGet(() -> {
return supportedExtensions.contains(file.getNameExtension())
|| ImageUtils.isJpegFileHeader(file) || ImageUtils.isPngFileHeader(file);
});
}
/**
*
* @param file
*
* @return true if the file has an image or video mime type.
* false if a non image/video mimetype.
* null if a mimetype could not be detected.
*/
static Boolean hasDrawableMimeType(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String mimeType = fileTypeDetector.getFileType(file);
return isNull(mimeType) ? null
: mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.equalsIgnoreCase("application/x-shockwave-flash");
}
} catch (TskCoreException ex) {
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex);
}
return null;
}
/** @param file
*
* @return true if the given file has a video mime type (video/* or
* application/x-shockwave-flash) or if no mimetype is available a video
* extension
*/
public static boolean isVideoFile(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String mimeType = fileTypeDetector.getFileType(file);
if (nonNull(mimeType)) {
return mimeType.startsWith("video/") || mimeType.equalsIgnoreCase("application/x-shockwave-flash");
}
}
} catch (TskCoreException ex) {
LOGGER.log(Level.INFO, "failed to get mime type for " + file.getName(), ex);
}
return videoExtensions.contains(file.getNameExtension());
}
/**
* Is the given file 'supported' and not 'known'(nsrl hash hit). If so we
@@ -194,6 +113,6 @@ public class ImageGalleryModule {
* 'known', else false
*/
public static boolean isDrawableAndNotKnown(AbstractFile abstractFile) {
return (abstractFile.getKnown() != TskData.FileKnown.KNOWN) && ImageGalleryModule.isDrawable(abstractFile);
return (abstractFile.getKnown() != TskData.FileKnown.KNOWN) && FileTypeUtils.isDrawable(abstractFile);
}
}
@@ -46,8 +46,8 @@ import org.apache.commons.lang3.StringUtils;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagegallery.FileTypeUtils;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupKey;
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupManager;
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupSortBy;
@@ -1199,7 +1199,7 @@ public final class DrawableDB {
private final Map<AbstractFile, Boolean> videoFileMap = new ConcurrentHashMap<>();
public boolean isVideoFile(AbstractFile f) {
return videoFileMap.computeIfAbsent(f, ImageGalleryModule::isVideoFile);
return videoFileMap.computeIfAbsent(f, FileTypeUtils::isVideoFile);
}
/**
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagegallery.FileTypeUtils;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
import org.sleuthkit.datamodel.AbstractFile;
@@ -62,7 +63,7 @@ import org.sleuthkit.datamodel.TskCoreException;
public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile {
public static DrawableFile<?> create(AbstractFile abstractFileById, boolean analyzed) {
if (ImageGalleryModule.isVideoFile(abstractFileById)) {
if (FileTypeUtils.isVideoFile(abstractFileById)) {
return new VideoFile<>(abstractFileById, analyzed);
} else {
return new ImageFile<>(abstractFileById, analyzed);
@@ -83,7 +84,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
public static DrawableFile<?> create(Long id, boolean analyzed) throws TskCoreException, IllegalStateException {
AbstractFile abstractFileById = Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id);
if (ImageGalleryModule.isVideoFile(abstractFileById)) {
if (FileTypeUtils.isVideoFile(abstractFileById)) {
return new VideoFile<>(abstractFileById, analyzed);
} else {
return new ImageFile<>(abstractFileById, analyzed);
@@ -27,19 +27,24 @@ import javafx.scene.media.Media;
import javafx.scene.media.MediaException;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.imagegallery.FileTypeIcons;
import org.sleuthkit.datamodel.AbstractFile;
public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png");
VideoFile(T file, Boolean analyzed) {
super(file, analyzed);
}
public static Image getGenericVideoThumbnail() {
return VIDEO_ICON;
}
@Override
public Image getThumbnail() {
//TODO: implement video thumbnailing here?
return FileTypeIcons.getGenericVideoThumbnail();
return getGenericVideoThumbnail();
}
SoftReference<Media> mediaRef;
@@ -19,8 +19,6 @@
package org.sleuthkit.autopsy.imagegallery.datamodel.grouping;
import com.google.common.eventbus.Subscribe;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -58,7 +56,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.LoggedTask;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
@@ -66,7 +63,6 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined.ThreadType;
import org.sleuthkit.autopsy.events.ContentTagAddedEvent;
import org.sleuthkit.autopsy.events.ContentTagDeletedEvent;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule;
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
import org.sleuthkit.autopsy.imagegallery.datamodel.CategoryManager;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableAttribute;
@@ -74,8 +70,6 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableDB;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableTagsManager;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagName;
@@ -302,59 +296,6 @@ public class GroupManager {
return group;
}
/**
* the implementation of this should be moved to DrawableDB
*
* @param hashDbName
*
* @return
*
* @deprecated
*/
@Deprecated
private List<Long> getFileIDsWithHashSetName(String hashDbName) {
List<Long> files = new ArrayList<>();
try {
final SleuthkitCase sleuthkitCase = ImageGalleryController.getDefault().getSleuthKitCase();
String query = "SELECT obj_id FROM blackboard_attributes,blackboard_artifacts WHERE "
+ "attribute_type_id=" + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id"
+ " AND blackboard_attributes.value_text='" + hashDbName + "'"
+ " AND blackboard_artifacts.artifact_type_id=" + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID();
ResultSet rs = null;
try {
rs = sleuthkitCase.runQuery(query);
while (rs.next()) {
long id = rs.getLong("obj_id");
try {
if (ImageGalleryModule.isDrawableAndNotKnown(Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id))) {
files.add(id);
}
} catch (TskCoreException ex) {
Exceptions.printStackTrace(ex);
}
}
} catch (SQLException ex) {
Exceptions.printStackTrace(ex);
} finally {
if (rs != null) {
try {
Case.getCurrentCase().getSleuthkitCase().closeRunQuery(rs);
} catch (SQLException ex) {
LOGGER.log(Level.WARNING, "Error closing result set after getting hashset hits", ex);
}
}
}
return files;
} catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Can't get the current case; there is no case open!", ex);
return files;
}
}
/**
* find the distinct values for the given column (DrawableAttribute)
*