package photato.core.metadata.exif;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import photato.helpers.SerialisationGsonBuilder;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import photato.helpers.OsHelper;
public class ExifToolParser {
private static final int batchSize = 50;
public static Map<Path, ExifMetadata> readMetadata(List<Path> filenames) {
String applicationName = OsHelper.isWindows() ? "exiftool.exe" : "exiftool";
Map<Path, ExifMetadata> result = new ConcurrentHashMap<>();
Stream<List<Path>> parallelStream = IntStream.range(0, (filenames.size() + batchSize - 1) / batchSize)
.mapToObj(i -> filenames.subList(i * batchSize, Math.min(filenames.size(), (i + 1) * batchSize)))
.parallel(); // Splitting entry list into batches
parallelStream.forEach((List<Path> filenamesSublist) -> {
try {
String filenamesCommandLineParameter = filenamesSublist.stream() // Concat all the filenames together, after surrounding them with quotes
.map((Path filename) -> "\"" + filename.toString() + "\"")
.collect(Collectors.joining(" "));
String commandLine = applicationName + " " + filenamesCommandLineParameter + " -charset utf-8 -charset filename=Latin -j -c \"%.8f\"";
Process p = Runtime.getRuntime().exec(commandLine);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream(), "UTF-8"));
String line;
StringBuilder builder = new StringBuilder();
while ((line = input.readLine()) != null) {
builder.append(line).append("\n");
}
p.waitFor();
List<ExifMetadata> metadataList = new Gson().fromJson(builder.toString(), new TypeToken<List<ExifMetadata>>() {
}.getType());
result.putAll(metadataList.stream().collect(Collectors.toMap(x -> Paths.get(x.getSourceFile()), x -> x)));
} catch (Exception ex) {
ex.printStackTrace();
}
});
return result;
}
}