1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00

Refactor local datasources (exif, xattr, file)

This commit is contained in:
Reinhard Pointner 2018-08-03 19:22:42 +07:00
parent 2ac98af09d
commit dbf88c62f3
10 changed files with 155 additions and 154 deletions

View File

@ -22,7 +22,7 @@ import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.stream.Stream;
import net.filebot.media.XattrMetaInfoProvider;
import net.filebot.media.LocalDatasource;
import net.filebot.similarity.MetricAvg;
import net.filebot.web.AcoustIDClient;
import net.filebot.web.AnidbClient;
@ -70,11 +70,10 @@ public final class WebServices {
// other sources
public static final FanartTVClient FanartTV = new FanartTVClient(getApiKey("fanart.tv"));
public static final AcoustIDClient AcoustID = new AcoustIDClient(getApiKey("acoustid"));
public static final XattrMetaInfoProvider XattrMetaData = new XattrMetaInfoProvider();
public static final ID3Lookup MediaInfoID3 = new ID3Lookup();
public static Datasource[] getServices() {
return new Datasource[] { TheMovieDB, OMDb, TheTVDB, AniDB, TheMovieDB_TV, TVmaze, AcoustID, MediaInfoID3, XattrMetaData, OpenSubtitles, Shooter, FanartTV };
return new Datasource[] { TheMovieDB, OMDb, TheTVDB, AniDB, TheMovieDB_TV, TVmaze, AcoustID, MediaInfoID3, LocalDatasource.EXIF, LocalDatasource.XATTR, LocalDatasource.FILE, OpenSubtitles, Shooter, FanartTV };
}
public static MovieIdentificationService[] getMovieIdentificationServices() {
@ -89,6 +88,10 @@ public final class WebServices {
return new MusicIdentificationService[] { AcoustID, MediaInfoID3 };
}
public static LocalDatasource[] getLocalDatasources() {
return new LocalDatasource[] { LocalDatasource.EXIF, LocalDatasource.XATTR, LocalDatasource.FILE };
}
public static SubtitleProvider[] getSubtitleProviders(Locale locale) {
return new SubtitleProvider[] { OpenSubtitles };
}

View File

@ -55,8 +55,8 @@ import net.filebot.hash.VerificationFileWriter;
import net.filebot.media.AutoDetection;
import net.filebot.media.AutoDetection.Group;
import net.filebot.media.AutoDetection.Type;
import net.filebot.media.LocalDatasource;
import net.filebot.media.VideoQuality;
import net.filebot.media.XattrMetaInfoProvider;
import net.filebot.similarity.CommonSequenceMatcher;
import net.filebot.similarity.EpisodeMatcher;
import net.filebot.similarity.Match;
@ -101,9 +101,9 @@ public class CmdlineOperations implements CmdlineInterface {
return renameMusic(files, action, conflict, output, format, singletonList((MusicIdentificationService) db), exec);
}
// generic file / xattr mode
if (db instanceof XattrMetaInfoProvider) {
return renameFiles(files, action, conflict, output, format, (XattrMetaInfoProvider) db, filter, strict, exec);
// photo / xattr / plain file mode
if (db instanceof LocalDatasource) {
return renameFiles(files, action, conflict, output, format, (LocalDatasource) db, filter, strict, exec);
}
// auto-detect mode for each fileset
@ -513,7 +513,7 @@ public class CmdlineOperations implements CmdlineInterface {
return renameAll(formatMatches(matches, format, outputDir), renameAction, conflictAction, null, exec);
}
public List<File> renameFiles(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, XattrMetaInfoProvider service, ExpressionFilter filter, boolean strict, ExecCommand exec) throws Exception {
public List<File> renameFiles(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, LocalDatasource service, ExpressionFilter filter, boolean strict, ExecCommand exec) throws Exception {
log.config(format("Rename files using [%s]", service.getName()));
Map<File, File> renameMap = new LinkedHashMap<File, File>();

View File

@ -0,0 +1,91 @@
package net.filebot.media;
import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*;
import static net.filebot.util.FileUtilities.*;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.Icon;
import net.filebot.ResourceManager;
import net.filebot.web.Datasource;
public enum LocalDatasource implements Datasource {
XATTR, EXIF, FILE;
@Override
public String getIdentifier() {
switch (this) {
case XATTR:
return "xattr";
case EXIF:
return "exif";
default:
return "file";
}
}
@Override
public String getName() {
switch (this) {
case XATTR:
return "Extended Attributes";
case EXIF:
return "Exif Metadata";
default:
return "Plain File";
}
}
@Override
public Icon getIcon() {
switch (this) {
case XATTR:
return ResourceManager.getIcon("search.xattr");
case EXIF:
return ResourceManager.getIcon("search.exif");
default:
return ResourceManager.getIcon("search.generic");
}
}
public Map<File, Object> match(Collection<File> files, boolean strict) {
switch (this) {
case XATTR:
Map<File, Object> xattrMap = new LinkedHashMap<File, Object>(files.size());
for (File f : files) {
Object object = xattr.getMetaInfo(f);
if (object != null) {
xattrMap.put(f, object);
} else if (!strict) {
xattrMap.put(f, f);
}
}
return xattrMap;
case EXIF:
Map<File, Object> exifMap = new LinkedHashMap<File, Object>(files.size());
for (File f : filter(files, ImageMetadata.SUPPORTED_FILE_TYPES)) {
try {
ImageMetadata metadata = new ImageMetadata(f);
if (metadata.getDateTaken().isPresent()) {
exifMap.put(f, f); // photo mode is the same as generic file mode (but only select photo files)
}
} catch (Exception e) {
debug.warning(format("%s [%s]", e, f));
}
}
return exifMap;
default:
return files.stream().collect(toMap(f -> f, f -> f, (a, b) -> a, LinkedHashMap::new));
}
}
// enable xattr regardless of -DuseExtendedFileAttributes system properties
private static final XattrMetaInfo xattr = new XattrMetaInfo(true, false);
}

View File

@ -0,0 +1,36 @@
package net.filebot.media;
import static java.util.stream.Collectors.*;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.Icon;
import net.filebot.ResourceManager;
import net.filebot.web.Datasource;
public class PlainFileMatcher implements Datasource {
@Override
public String getIdentifier() {
return "file";
}
@Override
public String getName() {
return "Plain File";
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.generic");
}
public Map<File, Object> match(Collection<File> files, boolean strict) {
return files.stream().collect(toMap(f -> f, f -> f, (a, b) -> a, LinkedHashMap::new));
}
}

View File

@ -1,49 +0,0 @@
package net.filebot.media;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.Icon;
import net.filebot.ResourceManager;
import net.filebot.web.Datasource;
public class XattrMetaInfoProvider implements Datasource {
@Override
public String getIdentifier() {
return "xattr";
}
@Override
public String getName() {
return "Extended Attributes";
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.xattr");
}
public Map<File, Object> match(Collection<File> files, boolean strict) {
// enable xattr regardless of -DuseExtendedFileAttributes system properties
XattrMetaInfo xattr = new XattrMetaInfo(true, false);
Map<File, Object> result = new LinkedHashMap<File, Object>();
for (File f : files) {
Object object = xattr.getMetaInfo(f);
if (object != null) {
result.put(f, object);
} else if (!strict) {
result.put(f, f);
}
}
return result;
}
}

View File

@ -10,32 +10,39 @@ import java.util.Locale;
import javax.swing.Icon;
import net.filebot.ResourceManager;
import net.filebot.media.LocalDatasource;
import net.filebot.similarity.Match;
import net.filebot.web.Datasource;
import net.filebot.web.SortOrder;
public class PlainFileMatcher implements Datasource, AutoCompleteMatcher {
public class LocalFileMatcher implements Datasource, AutoCompleteMatcher {
private final LocalDatasource datasource;
public LocalFileMatcher(LocalDatasource datasource) {
this.datasource = datasource;
}
@Override
public String getIdentifier() {
return "file";
return datasource.getIdentifier();
}
@Override
public String getName() {
return "Plain File";
return datasource.getName();
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.generic");
return datasource.getIcon();
}
@Override
public List<Match<File, ?>> match(Collection<File> files, boolean strict, SortOrder order, Locale locale, boolean autodetection, Component parent) throws Exception {
return files.stream().map(f -> {
return new Match<File, File>(f, f);
// always use strict mode internally to make behavior more simple and consistent for GUI users
return datasource.match(files, true).entrySet().stream().map(it -> {
return new Match<File, Object>(it.getKey(), it.getValue());
}).collect(toList());
}

View File

@ -1,56 +0,0 @@
package net.filebot.ui.rename;
import static net.filebot.Logging.*;
import static net.filebot.util.FileUtilities.*;
import java.awt.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.swing.Icon;
import net.filebot.ResourceManager;
import net.filebot.media.ImageMetadata;
import net.filebot.similarity.Match;
import net.filebot.web.Datasource;
import net.filebot.web.SortOrder;
public class PhotoFileMatcher implements Datasource, AutoCompleteMatcher {
@Override
public String getIdentifier() {
return "exif";
}
@Override
public String getName() {
return "Exif Metadata";
}
@Override
public Icon getIcon() {
return ResourceManager.getIcon("search.exif");
}
@Override
public List<Match<File, ?>> match(Collection<File> files, boolean strict, SortOrder order, Locale locale, boolean autodetection, Component parent) throws Exception {
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
for (File f : filter(files, ImageMetadata.SUPPORTED_FILE_TYPES)) {
try {
ImageMetadata metadata = new ImageMetadata(f);
if (metadata.getDateTaken().isPresent()) {
matches.add(new Match<File, File>(f, f)); // photo mode is the same as generic file mode (but only select photo files)
}
} catch (Exception e) {
debug.warning(format("%s [%s]", e, f));
}
}
return matches;
}
}

View File

@ -141,11 +141,7 @@ public class Preset {
}
public static Datasource[] getSupportedServices() {
return Stream.of(getEpisodeListProviders(), getMovieIdentificationServices(), getMusicIdentificationServices(), getGenericFileMatcherServices()).flatMap(Stream::of).toArray(Datasource[]::new);
}
public static Datasource[] getGenericFileMatcherServices() {
return new Datasource[] { new PhotoFileMatcher(), new XattrFileMatcher(), new PlainFileMatcher() };
return Stream.of(getEpisodeListProviders(), getMovieIdentificationServices(), getMusicIdentificationServices(), getLocalDatasources()).flatMap(Stream::of).toArray(Datasource[]::new);
}
public static StandardRenameAction[] getSupportedActions() {

View File

@ -65,6 +65,7 @@ import net.filebot.UserFiles;
import net.filebot.WebServices;
import net.filebot.format.ExpressionFileFormat;
import net.filebot.format.MediaBindingBean;
import net.filebot.media.LocalDatasource;
import net.filebot.media.MetaAttributes;
import net.filebot.platform.mac.MacAppUtilities;
import net.filebot.similarity.Match;
@ -323,7 +324,7 @@ public class RenamePanel extends JComponent {
withWaitCursor(evt.getSource(), () -> {
if (namesList.getModel().isEmpty()) {
// match to xattr metadata object or the file itself
Map<File, Object> xattr = WebServices.XattrMetaData.match(renameModel.files(), false);
Map<File, Object> xattr = LocalDatasource.XATTR.match(renameModel.files(), false);
renameModel.clear();
renameModel.addAll(xattr.values(), xattr.keySet());

View File

@ -1,28 +0,0 @@
package net.filebot.ui.rename;
import java.awt.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import net.filebot.media.XattrMetaInfoProvider;
import net.filebot.similarity.Match;
import net.filebot.web.SortOrder;
public class XattrFileMatcher extends XattrMetaInfoProvider implements AutoCompleteMatcher {
@Override
public List<Match<File, ?>> match(Collection<File> files, boolean strict, SortOrder order, Locale locale, boolean autodetection, Component parent) throws Exception {
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
// use strict mode to exclude files that are not xattr tagged
match(files, true).forEach((k, v) -> {
matches.add(new Match<File, Object>(k, v));
});
return matches;
}
}