mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' into 6412-standardInterestingFileSetRules
This commit is contained in:
commit
c35303f71a
@ -43,6 +43,8 @@ import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesKey;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -94,6 +96,25 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
|| eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|
||||
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|
||||
|| eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
||||
|
||||
/**
|
||||
* If a new file has been added but does not have an extension
|
||||
* there is nothing to do.
|
||||
*/
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
|
||||
if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
|
||||
return;
|
||||
}
|
||||
ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
|
||||
if ((moduleContentEvent.getSource() instanceof AbstractFile) == false) {
|
||||
return;
|
||||
}
|
||||
AbstractFile abstractFile = (AbstractFile) moduleContentEvent.getSource();
|
||||
if (abstractFile.getNameExtension().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking for a current case is a stop gap measure until a
|
||||
* different way of handling the closing of cases is worked
|
||||
@ -415,7 +436,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
refresh(true);
|
||||
refresh(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
@ -252,7 +253,12 @@ public class Tags implements AutopsyVisitableItem {
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse(filteringDSObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse();
|
||||
}
|
||||
Collections.sort(tagNamesInUse);
|
||||
Collections.sort(tagNamesInUse, new Comparator<TagName>() {
|
||||
@Override
|
||||
public int compare(TagName o1, TagName o2) {
|
||||
return TagUtils.getDecoratedTagDisplayName(o1).compareTo(TagUtils.getDecoratedTagDisplayName(o2));
|
||||
}
|
||||
});
|
||||
keys.addAll(tagNamesInUse);
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
Logger.getLogger(TagNameNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
|
||||
|
@ -26,6 +26,7 @@ import javafx.util.Pair;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationParseResult;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.Track;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder;
|
||||
@ -70,25 +71,33 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called after all of the MapWaypoints are created from all of the
|
||||
* TSK_GPS_XXX objects.
|
||||
*
|
||||
* @param mapWaypoints List of filtered MapWaypoints.
|
||||
* @param tracks The tracks that were successfully parsed.
|
||||
* @param wasEntirelySuccessful True if no errors occurred while processing.
|
||||
*/
|
||||
abstract void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks);
|
||||
abstract void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks,
|
||||
boolean wasEntirelySuccessful);
|
||||
|
||||
@Override
|
||||
public void process(List<Waypoint> waypoints) {
|
||||
List<Track> tracks = new ArrayList<>();
|
||||
public void process(GeoLocationParseResult<Waypoint> waypointResults) {
|
||||
GeoLocationParseResult<Track> trackResults = null;
|
||||
if (filters.getArtifactTypes().contains(ARTIFACT_TYPE.TSK_GPS_TRACK)) {
|
||||
try {
|
||||
tracks = Track.getTracks(Case.getCurrentCase().getSleuthkitCase(), filters.getDataSources());
|
||||
trackResults = Track.getTracks(Case.getCurrentCase().getSleuthkitCase(), filters.getDataSources());
|
||||
} catch (GeoLocationDataException ex) {
|
||||
logger.log(Level.WARNING, "Exception thrown while retrieving list of Tracks", ex);
|
||||
}
|
||||
}
|
||||
Pair<List<Waypoint>, List<List<Waypoint>>> waypointsAndTracks = createWaypointList(waypoints, tracks);
|
||||
|
||||
Pair<List<Waypoint>, List<List<Waypoint>>> waypointsAndTracks = createWaypointList(
|
||||
waypointResults.getItems(),
|
||||
(trackResults == null) ? new ArrayList<Track>() : trackResults.getItems());
|
||||
|
||||
|
||||
final Set<MapWaypoint> pointSet = MapWaypoint.getWaypoints(waypointsAndTracks.getKey());
|
||||
final List<Set<MapWaypoint>> trackSets = new ArrayList<>();
|
||||
@ -96,7 +105,9 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter
|
||||
trackSets.add(MapWaypoint.getWaypoints(t));
|
||||
}
|
||||
|
||||
handleFilteredWaypointSet(pointSet, trackSets);
|
||||
handleFilteredWaypointSet(
|
||||
pointSet, trackSets,
|
||||
(trackResults == null || trackResults.isSuccessfullyParsed()) && waypointResults.isSuccessfullyParsed());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,8 @@ GeolocationTC_connection_failure_message_title=Connection Failure
|
||||
GeolocationTC_empty_waypoint_message=Unable to generate KML report due to a lack of waypoints.\nPlease make sure there are waypoints visible before generating the KML report
|
||||
GeolocationTC_KML_report_title=KML Report
|
||||
GeolocationTC_report_progress_title=KML Report Progress
|
||||
GeolocationTopComponent.WaypointFetcher.onErrorDescription=There was an error gathering some GPS Track Data. Some results have been excluded.
|
||||
GeolocationTopComponent.WaypointFetcher.onErrorTitle=Error gathering GPS Track Data
|
||||
GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.
|
||||
GeoTopComponent_filer_data_invalid_Title=Filter Failure
|
||||
GeoTopComponent_filter_exception_msg=Exception occurred during waypoint filtering.
|
||||
|
@ -494,6 +494,10 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
* Extends AbstractWaypointFetcher to handle the returning of
|
||||
* the filters set of MapWaypoints.
|
||||
*/
|
||||
@Messages({
|
||||
"GeolocationTopComponent.WaypointFetcher.onErrorTitle=Error gathering GPS Track Data",
|
||||
"GeolocationTopComponent.WaypointFetcher.onErrorDescription=There was an error gathering some GPS Track Data. Some results have been excluded."
|
||||
})
|
||||
final private class WaypointFetcher extends AbstractWaypointFetcher {
|
||||
|
||||
WaypointFetcher(GeoFilter filters) {
|
||||
@ -501,8 +505,16 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks) {
|
||||
void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks, boolean wasEntirelySuccessful) {
|
||||
addWaypointsToMap(mapWaypoints, tracks);
|
||||
|
||||
// if there is an error, present to the user.
|
||||
if (!wasEntirelySuccessful) {
|
||||
JOptionPane.showMessageDialog(GeolocationTopComponent.this,
|
||||
Bundle.GeolocationTopComponent_WaypointFetcher_onErrorDescription(),
|
||||
Bundle.GeolocationTopComponent_WaypointFetcher_onErrorTitle(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 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.geolocation.datamodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.python.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* The result of attempting to parse GeoLocation objects.
|
||||
*/
|
||||
public class GeoLocationParseResult<T> {
|
||||
|
||||
private boolean successfullyParsed;
|
||||
private final List<T> items = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Returns a GeoLocationParseResult with no items and declared successfully
|
||||
* parsed.
|
||||
*/
|
||||
public GeoLocationParseResult() {
|
||||
successfullyParsed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new GeoLocationParseResult.
|
||||
*
|
||||
* @param items The items to copy to this result (can be null).
|
||||
* @param successfullyParsed Whether or not the operation was entirely
|
||||
* successful.
|
||||
*/
|
||||
public GeoLocationParseResult(List<T> items, boolean successfullyParsed) {
|
||||
this.successfullyParsed = successfullyParsed;
|
||||
|
||||
if (items != null) {
|
||||
this.items.addAll(items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the content of the GeoLocationParseResult parameter to this. Items
|
||||
* will be concatenated and this object's successfullyParsed status will be
|
||||
* true if it is already true and the object is true as well.
|
||||
*
|
||||
* @param toAdd The GeoLocationParseResult to add.
|
||||
*/
|
||||
public void add(GeoLocationParseResult<T> toAdd) {
|
||||
this.successfullyParsed = this.successfullyParsed && toAdd.isSuccessfullyParsed();
|
||||
this.items.addAll(toAdd.getItems());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the GeoLocation object has been successfully parsed.
|
||||
*
|
||||
* @return Whether or not the GeoLocation object has been successfully
|
||||
* parsed.
|
||||
*/
|
||||
public boolean isSuccessfullyParsed() {
|
||||
return successfullyParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The successfully parsed GeoLocation objects.
|
||||
*/
|
||||
public List<T> getItems() {
|
||||
return ImmutableList.copyOf(items);
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* Class representing a series of waypoints that form a path.
|
||||
*/
|
||||
public class GeoPath {
|
||||
|
||||
private final List<Waypoint> waypointList;
|
||||
private final String pathName;
|
||||
private final BlackboardArtifact artifact;
|
||||
@ -74,21 +73,26 @@ public class GeoPath {
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
static public List<Track> getTracks(SleuthkitCase skCase, List<? extends Content> sourceList) throws GeoLocationDataException {
|
||||
public static GeoLocationParseResult<Track> getTracks(SleuthkitCase skCase, List<? extends Content> sourceList) throws GeoLocationDataException {
|
||||
List<BlackboardArtifact> artifacts = null;
|
||||
boolean allParsedSuccessfully = true;
|
||||
List<Track> tracks = new ArrayList<>();
|
||||
try {
|
||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK);
|
||||
for (BlackboardArtifact artifact : artifacts) {
|
||||
if (sourceList == null || sourceList.contains(artifact.getDataSource())) {
|
||||
Track route = new Track(artifact);
|
||||
tracks.add(route);
|
||||
try {
|
||||
tracks.add(new Track(artifact));
|
||||
|
||||
} catch (GeoLocationDataException e) {
|
||||
allParsedSuccessfully = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_BOOKMARK", ex);
|
||||
}
|
||||
return tracks;
|
||||
return new GeoLocationParseResult<Track>(tracks, allParsedSuccessfully);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,17 +22,20 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil.InvalidJsonException;
|
||||
import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* A GPS track with which wraps the TSK_GPS_TRACK artifact.
|
||||
*/
|
||||
public final class Track extends GeoPath {
|
||||
private static final Logger LOGGER = Logger.getLogger(Track.class.getName());
|
||||
|
||||
private final Long startTimestamp;
|
||||
private final Long endTimeStamp;
|
||||
@ -130,15 +133,18 @@ public final class Track extends GeoPath {
|
||||
*/
|
||||
private GeoTrackPoints getPointsList(Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) throws GeoLocationDataException {
|
||||
BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS);
|
||||
if (attribute != null) {
|
||||
if (attribute == null) {
|
||||
LOGGER.log(Level.SEVERE, "No TSK_GEO_TRACKPOINTS attribute was present on the artifact.");
|
||||
throw new GeoLocationDataException("No TSK_GEO_TRACKPOINTS attribute present in attribute map to parse.");
|
||||
}
|
||||
|
||||
try {
|
||||
return BlackboardJsonAttrUtil.fromAttribute(attribute, GeoTrackPoints.class);
|
||||
} catch (InvalidJsonException ex) {
|
||||
LOGGER.log(Level.SEVERE, "TSK_GEO_TRACKPOINTS could not be properly parsed from TSK_GEO_TRACKPOINTS attribute.");
|
||||
throw new GeoLocationDataException("Unable to parse track points in TSK_GEO_TRACKPOINTS attribute", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Waypoint subclass for the points of a track.
|
||||
|
@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.geolocation.datamodel;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -96,9 +97,10 @@ public final class WaypointBuilder {
|
||||
/**
|
||||
* This function will be called after the waypoints have been filtered.
|
||||
*
|
||||
* @param waypoints The list of waypoints.
|
||||
* @param waypoints The list of waypoints and whether they were all
|
||||
* successfully parsed.
|
||||
*/
|
||||
void process(List<Waypoint> waypoints);
|
||||
void process(GeoLocationParseResult<Waypoint> waypoints);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -478,7 +480,7 @@ public final class WaypointBuilder {
|
||||
skCase.getCaseDbAccessManager().select(query, new CaseDbAccessManager.CaseDbAccessQueryCallback() {
|
||||
@Override
|
||||
public void process(ResultSet rs) {
|
||||
List<Waypoint> waypoints = new ArrayList<>();
|
||||
GeoLocationParseResult<Waypoint> waypointResults = new GeoLocationParseResult<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
int artifact_type_id = rs.getInt("artifact_type_id"); //NON-NLS
|
||||
@ -486,12 +488,13 @@ public final class WaypointBuilder {
|
||||
|
||||
ARTIFACT_TYPE type = ARTIFACT_TYPE.fromID(artifact_type_id);
|
||||
if (artifactTypes.contains(type)) {
|
||||
waypoints.addAll(getWaypointForArtifact(skCase.getBlackboardArtifact(artifact_id), type));
|
||||
waypointResults.add(getWaypointForArtifact(skCase.getBlackboardArtifact(artifact_id), type));
|
||||
}
|
||||
|
||||
}
|
||||
queryCallBack.process(waypoints);
|
||||
} catch (GeoLocationDataException | SQLException | TskCoreException ex) {
|
||||
|
||||
queryCallBack.process(waypointResults);
|
||||
} catch (SQLException | TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to filter waypoint.", ex); //NON-NLS
|
||||
}
|
||||
|
||||
@ -522,7 +525,7 @@ public final class WaypointBuilder {
|
||||
// FROM blackboard_attributes
|
||||
// WHERE attribute_type_id IN (%d, %d)
|
||||
return String.format(SELECT_WO_TIMESTAMP,
|
||||
String.format(GEO_ARTIFACT_QUERY_ID_ONLY,TIME_TYPE_IDS),
|
||||
String.format(GEO_ARTIFACT_QUERY_ID_ONLY, TIME_TYPE_IDS),
|
||||
getWaypointListQuery(dataSources));
|
||||
}
|
||||
|
||||
@ -619,6 +622,51 @@ public final class WaypointBuilder {
|
||||
dataSourceList);
|
||||
}
|
||||
|
||||
/**
|
||||
* A parser that could throw a GeoLocationDataException when there is a
|
||||
* parse issue.
|
||||
*
|
||||
* @param <T> The return type.
|
||||
*/
|
||||
private interface ParserWithError<T> {
|
||||
|
||||
T parse(BlackboardArtifact artifact) throws GeoLocationDataException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses one waypoint.
|
||||
*
|
||||
* @param parser The parser to use.
|
||||
* @param artifact The artifact to be parsed.
|
||||
*
|
||||
* @return Returns a parse result that is either successful with a parsed
|
||||
* waypoint or unsuccessful with an exception.
|
||||
*/
|
||||
private static GeoLocationParseResult<Waypoint> parseWaypoint(ParserWithError<Waypoint> parser, BlackboardArtifact artifact) {
|
||||
try {
|
||||
return new GeoLocationParseResult<>(Arrays.asList(parser.parse(artifact)), true);
|
||||
} catch (GeoLocationDataException ex) {
|
||||
return new GeoLocationParseResult<>(null, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a list of waypoints.
|
||||
*
|
||||
* @param parser The parser to use.
|
||||
* @param artifact The artifact to be parsed.
|
||||
*
|
||||
* @return Returns a parse result that is either successful with a parsed
|
||||
* waypoint or unsuccessful with an exception.
|
||||
*/
|
||||
private static GeoLocationParseResult<Waypoint> parseWaypoints(ParserWithError<List<Waypoint>> parser, BlackboardArtifact artifact) {
|
||||
try {
|
||||
return new GeoLocationParseResult<>(parser.parse(artifact), true);
|
||||
} catch (GeoLocationDataException ignored) {
|
||||
return new GeoLocationParseResult<>(null, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Waypoint object for the given Blackboard artifact.
|
||||
*
|
||||
@ -626,37 +674,33 @@ public final class WaypointBuilder {
|
||||
* @param type The type of artifact
|
||||
*
|
||||
* @return A new waypoint object
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
static private List<Waypoint> getWaypointForArtifact(BlackboardArtifact artifact, ARTIFACT_TYPE type) throws GeoLocationDataException {
|
||||
List<Waypoint> waypoints = new ArrayList<>();
|
||||
private static GeoLocationParseResult<Waypoint> getWaypointForArtifact(BlackboardArtifact artifact, ARTIFACT_TYPE type) {
|
||||
GeoLocationParseResult<Waypoint> waypoints = new GeoLocationParseResult<>();
|
||||
switch (type) {
|
||||
case TSK_METADATA_EXIF:
|
||||
waypoints.add(new EXIFWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(EXIFWaypoint::new, artifact));
|
||||
break;
|
||||
case TSK_GPS_BOOKMARK:
|
||||
waypoints.add(new BookmarkWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(BookmarkWaypoint::new, artifact));
|
||||
break;
|
||||
case TSK_GPS_TRACKPOINT:
|
||||
waypoints.add(new TrackpointWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(TrackpointWaypoint::new, artifact));
|
||||
break;
|
||||
case TSK_GPS_SEARCH:
|
||||
waypoints.add(new SearchWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(SearchWaypoint::new, artifact));
|
||||
break;
|
||||
case TSK_GPS_ROUTE:
|
||||
Route route = new Route(artifact);
|
||||
waypoints.addAll(route.getRoute());
|
||||
waypoints.add(parseWaypoints((a) -> new Route(a).getRoute(), artifact));
|
||||
break;
|
||||
case TSK_GPS_LAST_KNOWN_LOCATION:
|
||||
waypoints.add(new LastKnownWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(LastKnownWaypoint::new, artifact));
|
||||
break;
|
||||
case TSK_GPS_TRACK:
|
||||
Track track = new Track(artifact);
|
||||
waypoints.addAll(track.getPath());
|
||||
waypoints.add(parseWaypoints((a) -> new Track(a).getPath(), artifact));
|
||||
break;
|
||||
default:
|
||||
waypoints.add(new CustomArtifactWaypoint(artifact));
|
||||
waypoints.add(parseWaypoint(CustomArtifactWaypoint::new, artifact));
|
||||
}
|
||||
|
||||
return waypoints;
|
||||
|
@ -2,6 +2,7 @@ KMLReport.bookmarkError=Could not extract Bookmark information.
|
||||
# {0} - filePath
|
||||
KMLReport.errorGeneratingReport=Error adding {0} to case as a report.
|
||||
KMLReport.exifPhotoError=Could not extract photos with EXIF metadata.
|
||||
KMLReport.failedToCompleteReport=Failed to complete report.
|
||||
KMLReport.gpsBookmarkError=Could not get GPS Bookmarks from database.
|
||||
KMLReport.gpsRouteDatabaseError=Could not get GPS Routes from database.
|
||||
KMLReport.gpsRouteError=Could not extract GPS Route information.
|
||||
@ -9,6 +10,7 @@ KMLReport.gpsSearchDatabaseError=Could not get GPS Searches from database.
|
||||
KMLReport.kmlFileWriteError=Could not write the KML file.
|
||||
KMLReport.locationDatabaseError=Could not get GPS Last Known Location from database.
|
||||
KMLReport.locationError=Could not extract Last Known Location information.
|
||||
KMLReport.partialFailure=There was an error creating the report. Some items were not exported.
|
||||
KMLReport.stylesheetError=Error placing KML stylesheet. The .KML file will not function properly.
|
||||
KMLReport.trackpointDatabaseError=Could not get GPS Trackpoints from database.
|
||||
KMLReport.trackpointError=Could not extract Trackpoint information.
|
||||
|
@ -46,6 +46,7 @@ import org.openide.filesystems.FileUtil;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationParseResult;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.Route;
|
||||
import org.sleuthkit.autopsy.geolocation.datamodel.Track;
|
||||
@ -126,6 +127,8 @@ public final class KMLReport implements GeneralReportModule {
|
||||
* @param waypointList
|
||||
*/
|
||||
@Messages({
|
||||
"KMLReport.failedToCompleteReport=Failed to complete report.",
|
||||
"KMLReport.partialFailure=There was an error creating the report. Some items were not exported.",
|
||||
"KMLReport.unableToExtractPhotos=Could not extract photo information.",
|
||||
"KMLReport.exifPhotoError=Could not extract photos with EXIF metadata.",
|
||||
"KMLReport.bookmarkError=Could not extract Bookmark information.",
|
||||
@ -208,10 +211,15 @@ public final class KMLReport implements GeneralReportModule {
|
||||
|
||||
try {
|
||||
makeRoutes(skCase);
|
||||
makeTracks(skCase);
|
||||
boolean entirelySuccessful = makeTracks(skCase);
|
||||
if (!entirelySuccessful) {
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
errorMessage = Bundle.KMLReport_partialFailure();
|
||||
}
|
||||
|
||||
addLocationsToReport(skCase, baseReportDir);
|
||||
} catch (GeoLocationDataException | IOException | TskCoreException ex) {
|
||||
errorMessage = "Failed to complete report.";
|
||||
errorMessage = Bundle.KMLReport_failedToCompleteReport();
|
||||
logger.log(Level.SEVERE, errorMessage, ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
@ -515,14 +523,18 @@ public final class KMLReport implements GeneralReportModule {
|
||||
* Add the track to the track folder in the document.
|
||||
*
|
||||
* @param skCase Currently open case.
|
||||
* @return The operation was entirely successful.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
void makeTracks(SleuthkitCase skCase) throws GeoLocationDataException, TskCoreException {
|
||||
boolean makeTracks(SleuthkitCase skCase) throws GeoLocationDataException, TskCoreException {
|
||||
List<Track> tracks = null;
|
||||
boolean successful = true;
|
||||
|
||||
if (waypointList == null) {
|
||||
tracks = Track.getTracks(skCase, null);
|
||||
GeoLocationParseResult<Track> result = Track.getTracks(skCase, null);
|
||||
tracks = result.getItems();
|
||||
successful = result.isSuccessfullyParsed();
|
||||
} else {
|
||||
tracks = WaypointBuilder.getTracks(waypointList);
|
||||
}
|
||||
@ -533,6 +545,8 @@ public final class KMLReport implements GeneralReportModule {
|
||||
}
|
||||
addTrackToReport(track);
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,6 +82,12 @@ public class CategorizeAction extends Action {
|
||||
this.tagName = tagName;
|
||||
setGraphic(getGraphic(tagName));
|
||||
setEventHandler(actionEvent -> addCatToFiles(selectedFileIDs));
|
||||
|
||||
int rank = tagName.getRank();
|
||||
// Only map to a key if the rank is less than 10
|
||||
if(rank < 10) {
|
||||
setAccelerator(new KeyCodeCombination(KeyCode.getKeyCode(Integer.toString(rank))));
|
||||
}
|
||||
}
|
||||
|
||||
static public Menu getCategoriesMenu(ImageGalleryController controller) {
|
||||
|
@ -21,12 +21,19 @@ package org.sleuthkit.autopsy.imagegallery.gui;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ButtonBase;
|
||||
import javafx.scene.control.CustomMenuItem;
|
||||
import javafx.scene.control.Dialog;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import org.controlsfx.control.action.Action;
|
||||
import org.controlsfx.control.action.ActionUtils;
|
||||
@ -67,7 +74,31 @@ public final class GuiUtils {
|
||||
* @return
|
||||
*/
|
||||
public static MenuItem createAutoAssigningMenuItem(ButtonBase button, Action action) {
|
||||
MenuItem menuItem = new CustomMenuItem(new Label(action.getText(), action.getGraphic()));
|
||||
Label mainLabel = new Label(action.getText(), action.getGraphic());
|
||||
|
||||
String hkDisplayText = action.getAccelerator() != null ? action.getAccelerator().getDisplayText() : "";
|
||||
Label hotKeyLabel = new Label(hkDisplayText);
|
||||
|
||||
hotKeyLabel.setMaxWidth(100);
|
||||
|
||||
GridPane grid = new GridPane();
|
||||
grid.setAlignment(Pos.CENTER);
|
||||
grid.setHgap(10);
|
||||
|
||||
ColumnConstraints column1 = new ColumnConstraints();
|
||||
column1.setHalignment(HPos.LEFT);
|
||||
grid.getColumnConstraints().add(column1);
|
||||
|
||||
ColumnConstraints column2 = new ColumnConstraints();
|
||||
column2.setHalignment(HPos.RIGHT);
|
||||
column2.setMaxWidth(Double.MAX_VALUE);
|
||||
grid.getColumnConstraints().add(column2);
|
||||
|
||||
grid.add(mainLabel, 0, 0);
|
||||
grid.add(hotKeyLabel, 1, 0);
|
||||
grid.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
MenuItem menuItem = new CustomMenuItem(grid);
|
||||
ActionUtils.configureMenuItem(action, menuItem);
|
||||
menuItem.setOnAction(actionEvent -> {
|
||||
action.handle(actionEvent);
|
||||
|
@ -183,6 +183,7 @@ class GPXParserFileIngestModule(FileIngestModule):
|
||||
point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp))
|
||||
|
||||
try:
|
||||
if not geoPointList.isEmpty():
|
||||
geoArtifactHelper.addTrack("Track", geoPointList, None)
|
||||
except Blackboard.BlackboardException as e:
|
||||
self.log(Level.SEVERE, "Error posting GPS track artifact for " +
|
||||
@ -236,6 +237,7 @@ class GPXParserFileIngestModule(FileIngestModule):
|
||||
Waypoint(point.latitude, point.longitude, point.elevation, point.name))
|
||||
|
||||
try:
|
||||
if not geoWaypoints.isEmpty():
|
||||
geoArtifactHelper.addRoute(None, None, geoWaypoints, None)
|
||||
except Blackboard.BlackboardException as e:
|
||||
self.log("Error posting GPS route artifact for " + file.getUniquePath() +
|
||||
|
Loading…
x
Reference in New Issue
Block a user