Autopsy  4.21.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
SummaryHelpers.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.discovery.search;
20 
21 import com.google.common.io.Files;
22 import java.awt.Image;
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileReader;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.Reader;
29 import java.nio.file.Paths;
30 import java.util.Collection;
31 import java.util.logging.Level;
32 import org.apache.commons.lang.StringUtils;
33 import org.openide.util.Lookup;
34 import org.openide.util.NbBundle;
46 import org.sleuthkit.datamodel.AbstractFile;
47 import org.sleuthkit.datamodel.Content;
48 import org.sleuthkit.datamodel.TskCoreException;
49 
53 class SummaryHelpers {
54 
55  private static final int PREVIEW_SIZE = 256;
56  private final static Logger logger = Logger.getLogger(SummaryHelpers.class.getName());
57  private static volatile TextSummarizer summarizerToUse = null;
58 
59  private SummaryHelpers() {
60  // Class should not be instantiated
61  }
62 
70  static TextSummary getDefaultSummary(AbstractFile file) {
71  Image image = null;
72  int countOfImages = 0;
73  try {
74  Content largestChild = null;
75  for (Content child : file.getChildren()) {
76  if (child instanceof AbstractFile && ImageUtils.isImageThumbnailSupported((AbstractFile) child)) {
77  countOfImages++;
78  if (largestChild == null || child.getSize() > largestChild.getSize()) {
79  largestChild = child;
80  }
81  }
82  }
83  if (largestChild != null) {
84  image = ImageUtils.getThumbnail(largestChild, ImageUtils.ICON_SIZE_LARGE);
85  }
86  } catch (TskCoreException ex) {
87  logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex);
88  }
89  image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM,
90  Image.SCALE_SMOOTH);
91  String summaryText = null;
92  if (file.getMd5Hash() != null) {
93  try {
94  summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
95  } catch (NoCurrentCaseException ex) {
96  logger.log(Level.WARNING, "Unable to retrieve saved summary. No case is open.", ex);
97  }
98  }
99  if (StringUtils.isBlank(summaryText)) {
100  String firstLines = getFirstLines(file);
101  String translatedFirstLines = getTranslatedVersion(firstLines);
102  if (!StringUtils.isBlank(translatedFirstLines)) {
103  summaryText = translatedFirstLines;
104  if (file.getMd5Hash() != null) {
105  try {
106  saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
107  } catch (NoCurrentCaseException ex) {
108  logger.log(Level.WARNING, "Unable to save translated summary. No case is open.", ex);
109  }
110  }
111  } else {
112  summaryText = firstLines;
113  }
114  }
115  return new TextSummary(summaryText, image, countOfImages);
116  }
117 
127  static String getTranslatedVersion(String documentString) {
128  try {
129  TextTranslationService translatorInstance = TextTranslationService.getInstance();
130  if (translatorInstance.hasProvider()) {
131  String translatedResult = translatorInstance.translate(documentString);
132  if (translatedResult.isEmpty() == false) {
133  return translatedResult;
134  }
135  }
136  } catch (NoServiceProviderException | TranslationException ex) {
137  logger.log(Level.INFO, "Error translating string for summary", ex);
138  }
139  return null;
140  }
141 
151  static String getSavedSummary(String summarySavePath) {
152  if (summarySavePath == null) {
153  return null;
154  }
155  File savedFile = new File(summarySavePath);
156  if (savedFile.exists()) {
157  try (BufferedReader bReader = new BufferedReader(new FileReader(savedFile))) {
158  // pass the path to the file as a parameter
159  StringBuilder sBuilder = new StringBuilder(PREVIEW_SIZE);
160  String sCurrentLine = bReader.readLine();
161  while (sCurrentLine != null) {
162  sBuilder.append(sCurrentLine).append('\n');
163  sCurrentLine = bReader.readLine();
164  }
165  return sBuilder.toString();
166  } catch (IOException ingored) {
167  //summary file may not exist or may be incomplete in which case return null so a summary can be generated
168  return null; //no saved summary was able to be found
169  }
170  } else {
171  try { //if the file didn't exist make sure the parent directories exist before we move on to creating a summary
172  Files.createParentDirs(savedFile);
173  } catch (IOException ex) {
174  logger.log(Level.WARNING, "Unable to create summaries directory in case folder for file at: " + summarySavePath, ex);
175  }
176  return null; //no saved summary was able to be found
177  }
178 
179  }
180 
187  static void saveSummary(String summary, String summarySavePath) {
188  if (summarySavePath == null) {
189  return; //can't save a summary if we don't have a path
190  }
191  try (FileWriter myWriter = new FileWriter(summarySavePath)) {
192  myWriter.write(summary);
193  } catch (IOException ex) {
194  logger.log(Level.WARNING, "Unable to save summary at: " + summarySavePath, ex);
195  }
196  }
197 
198  @NbBundle.Messages({"SummaryHelper.documentSummary.unable.to.read=Error trying to extract text from file."})
206  static String getFirstLines(AbstractFile file) {
207  TextExtractor extractor;
208  try {
209  extractor = TextExtractorFactory.getExtractor(file, null);
210  } catch (TextExtractorFactory.NoTextExtractorFound ignored) {
211  //no extractor found, use Strings Extractor
212  extractor = TextExtractorFactory.getStringsExtractor(file, null);
213  }
214 
215  try (Reader reader = extractor.getReader()) {
216  char[] cbuf = new char[PREVIEW_SIZE];
217  reader.read(cbuf, 0, PREVIEW_SIZE);
218  return new String(cbuf);
219  } catch (IOException ex) {
220  return Bundle.FileSearch_documentSummary_noBytes();
221  } catch (TextExtractor.InitReaderException ex) {
222  return Bundle.SummaryHelper_documentSummary_unable_to_read();
223  }
224  }
225 
233  static TextSummarizer getLocalSummarizer() {
234  if (summarizerToUse == null) {
235  Collection<? extends TextSummarizer> summarizers
236  = Lookup.getDefault().lookupAll(TextSummarizer.class
237  );
238  if (!summarizers.isEmpty()) {
239  summarizerToUse = summarizers.iterator().next();
240  }
241  }
242  return summarizerToUse;
243  }
244 
245 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Feb 6 2024
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.