19 package org.sleuthkit.autopsy.discovery.search;
21 import com.google.common.io.Files;
22 import java.awt.Image;
23 import java.io.BufferedReader;
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;
53 class SummaryHelpers {
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;
59 private SummaryHelpers() {
70 static TextSummary getDefaultSummary(AbstractFile file) {
72 int countOfImages = 0;
74 Content largestChild = null;
75 for (Content child : file.getChildren()) {
76 if (child instanceof AbstractFile && ImageUtils.isImageThumbnailSupported((AbstractFile) child)) {
78 if (largestChild == null || child.getSize() > largestChild.getSize()) {
83 if (largestChild != null) {
84 image = ImageUtils.getThumbnail(largestChild, ImageUtils.ICON_SIZE_LARGE);
86 }
catch (TskCoreException ex) {
87 logger.log(Level.WARNING,
"Error getting children for file: " + file.getId(), ex);
89 image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM,
91 String summaryText = null;
92 if (file.getMd5Hash() != null) {
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);
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) {
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);
112 summaryText = firstLines;
115 return new TextSummary(summaryText, image, countOfImages);
127 static String getTranslatedVersion(String documentString) {
129 TextTranslationService translatorInstance = TextTranslationService.getInstance();
130 if (translatorInstance.hasProvider()) {
131 String translatedResult = translatorInstance.translate(documentString);
132 if (translatedResult.isEmpty() ==
false) {
133 return translatedResult;
136 }
catch (NoServiceProviderException | TranslationException ex) {
137 logger.log(Level.INFO,
"Error translating string for summary", ex);
151 static String getSavedSummary(String summarySavePath) {
152 if (summarySavePath == null) {
155 File savedFile =
new File(summarySavePath);
156 if (savedFile.exists()) {
157 try (BufferedReader bReader =
new BufferedReader(
new FileReader(savedFile))) {
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();
165 return sBuilder.toString();
166 }
catch (IOException ingored) {
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);
187 static void saveSummary(String summary, String summarySavePath) {
188 if (summarySavePath == null) {
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);
198 @NbBundle.Messages({
"SummaryHelper.documentSummary.unable.to.read=Unable to extract text from file."})
206 static String getFirstLines(AbstractFile file) {
207 TextExtractor extractor;
209 extractor = TextExtractorFactory.getExtractor(file, null);
210 }
catch (TextExtractorFactory.NoTextExtractorFound ignored) {
212 extractor = TextExtractorFactory.getStringsExtractor(file, null);
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();
233 static TextSummarizer getLocalSummarizer() {
234 if (summarizerToUse == null) {
235 Collection<? extends TextSummarizer> summarizers
236 = Lookup.getDefault().lookupAll(TextSummarizer.class
238 if (!summarizers.isEmpty()) {
239 summarizerToUse = summarizers.iterator().next();
242 return summarizerToUse;