Refactor MediaTypes

This commit is contained in:
Reinhard Pointner 2017-01-12 22:18:10 +08:00
parent e5de459a9c
commit aec56019e8
15 changed files with 133 additions and 283 deletions

View File

@ -151,9 +151,6 @@ public class Main {
SwingEventBus.getInstance().post(new FileTransferable(files));
}
// preload media.types (when loaded during DnD it will freeze the UI for a few hundred milliseconds)
MediaTypes.getDefault();
// JavaFX is used for ProgressMonitor and GettingStartedDialog
try {
initJavaFX();

View File

@ -1,118 +1,73 @@
package net.filebot;
import static java.util.Collections.*;
import static net.filebot.util.XPathUtilities.*;
import static net.filebot.util.RegularExpressions.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.util.ResourceBundle;
import net.filebot.util.FileUtilities.ExtensionFileFilter;
public class MediaTypes {
private static MediaTypes defaultInstance;
private static Map<String, ExtensionFileFilter> types = getKnownMediaTypes();
public static synchronized MediaTypes getDefault() {
if (defaultInstance == null) {
defaultInstance = parseDefault();
}
return defaultInstance;
}
private static Map<String, ExtensionFileFilter> getKnownMediaTypes() {
Map<String, ExtensionFileFilter> types = new LinkedHashMap<String, ExtensionFileFilter>(64);
private static MediaTypes parseDefault() {
try {
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(MediaTypes.class.getResourceAsStream("media.types"));
Map<String, List<String>> types = new LinkedHashMap<String, List<String>>();
ResourceBundle bundle = ResourceBundle.getBundle(MediaTypes.class.getName());
for (Enumeration<String> keys = bundle.getKeys(); keys.hasMoreElements();) {
String type = keys.nextElement();
String[] extensions = SPACE.split(bundle.getString(type));
for (Node it : getChildren("type", dom.getFirstChild())) {
List<String> extensions = new ArrayList<String>(2);
for (Node ie : getChildren("extension", it)) {
extensions.add(getTextContent(ie));
}
types.put(getAttribute("name", it), extensions);
}
return new MediaTypes(types);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Map<String, List<String>> types;
private Map<String, ExtensionFileFilter> filters = synchronizedMap(new HashMap<String, ExtensionFileFilter>());
public MediaTypes(Map<String, List<String>> types) {
this.types = types;
}
public List<String> getExtensionList(String name) {
List<String> list = new ArrayList<String>();
for (Entry<String, List<String>> type : types.entrySet()) {
if (type.getKey().startsWith(name)) {
list.addAll(type.getValue());
}
types.put(type, new ExtensionFileFilter(extensions));
}
return list;
}
public ExtensionFileFilter getFilter(String name) {
ExtensionFileFilter filter = filters.get(name);
if (filter == null) {
filter = new ExtensionFileFilter(getExtensionList(name));
filters.put(name, filter);
}
return filter;
}
public Map<String, List<String>> getTypes() {
return types;
}
public String getMediaType(String extension) {
for (Entry<String, List<String>> it : getTypes().entrySet()) {
if (it.getValue().contains(extension)) {
public static void main(String[] args) {
System.out.println(MediaTypes.types);
}
public static String getMediaType(String extension) {
for (Entry<String, ExtensionFileFilter> it : types.entrySet()) {
if (it.getValue().acceptExtension(extension)) {
return it.getKey();
}
}
return null;
}
public static ExtensionFileFilter getDefaultFilter(String name) {
return getDefault().getFilter(name);
public static ExtensionFileFilter getTypeFilter(String name) {
return types.get(name);
}
public static ExtensionFileFilter combineFilter(ExtensionFileFilter... filters) {
public static ExtensionFileFilter getCategoryFilter(String category) {
List<String> extensions = new ArrayList<String>();
for (ExtensionFileFilter it : filters) {
if (!it.acceptAny()) {
addAll(extensions, it.extensions());
for (Entry<String, ExtensionFileFilter> it : types.entrySet()) {
if (it.getKey().startsWith(category)) {
addAll(extensions, it.getValue().extensions());
}
}
return new ExtensionFileFilter(extensions);
}
// some convenience filters
public static final ExtensionFileFilter AUDIO_FILES = getDefaultFilter("audio");
public static final ExtensionFileFilter VIDEO_FILES = getDefaultFilter("video");
public static final ExtensionFileFilter SUBTITLE_FILES = getDefaultFilter("subtitle");
public static final ExtensionFileFilter ARCHIVE_FILES = getDefaultFilter("archive");
public static final ExtensionFileFilter VERIFICATION_FILES = getDefaultFilter("verification");
public static final ExtensionFileFilter NFO_FILES = getDefaultFilter("application/nfo");
public static final ExtensionFileFilter LIST_FILES = getDefaultFilter("application/list");
public static final ExtensionFileFilter TORRENT_FILES = getDefaultFilter("application/torrent");
public static final ExtensionFileFilter AUDIO_FILES = getCategoryFilter("audio");
public static final ExtensionFileFilter VIDEO_FILES = getCategoryFilter("video");
public static final ExtensionFileFilter SUBTITLE_FILES = getCategoryFilter("subtitle");
public static final ExtensionFileFilter ARCHIVE_FILES = getCategoryFilter("archive");
public static final ExtensionFileFilter VERIFICATION_FILES = getCategoryFilter("verification");
public static final ExtensionFileFilter NFO_FILES = getTypeFilter("application/nfo");
public static final ExtensionFileFilter LIST_FILES = getTypeFilter("application/list");
public static final ExtensionFileFilter TORRENT_FILES = getTypeFilter("application/torrent");
}

View File

@ -0,0 +1,49 @@
application/torrent: torrent tor
application/list: list txt
application/nfo: nfo url
verification/sfv: sfv
verification/md5sum: md5
verification/sha1sum: sha1 sha
verification/sha256sum: sha256 sha2
verification/ed2k: ed2k
archive/zip: zip
archive/rar: rar
archive/7z: 7z
archive/gzip: gzip gz
archive/tar: tar
archive/bzip2: bzip2
audio/mp3: mp3
audio/mp4: m4a aac
audio/flac: flac
audio/wma: wma
audio/ogm: ogg ogm ogv oga
audio/wav: wav aiff alac
video/avi: avi
video/mkv: mkv mk3d
video/ogm: ogm ogg
video/mp4: mp4 m4v 3gp
video/mov: mov
video/divx: divx
video/mpeg: mpg mpeg vob ts tp m2ts rec
video/wmv: wmv asf wtv
video/WebM: webm
video/flash: flv
video/realmedia: rm rmvb rmp4
video/tivo: tivo
video/NuppelVideo: nuv
video/3DSBS: 3DSBS 3DTAB
video/stream-descriptor: strm
video/audio-stream: ac3 dts
video/iso: iso
subtitle/SubRip: srt
subtitle/MicroDVD: sub
subtitle/SubViewer: sub
subtitle/SubStationAlpha: ssa ass
subtitle/SAMI: smi sami
subtitle/WebVTT: vtt
subtitle/VobSub: vobsub sub idx

View File

@ -1,6 +1,7 @@
package net.filebot.cli;
import static net.filebot.Logging.*;
import static net.filebot.MediaTypes.*;
import static net.filebot.util.ExceptionUtilities.*;
import static net.filebot.util.FileUtilities.*;
@ -13,8 +14,6 @@ import java.util.logging.Level;
import javax.script.Bindings;
import javax.script.SimpleBindings;
import net.filebot.MediaTypes;
public class ArgumentProcessor {
public int run(ArgumentBean args) {
@ -86,7 +85,7 @@ public class ArgumentProcessor {
if (args.check) {
// check verification file
if (containsOnly(files, MediaTypes.getDefaultFilter("verification"))) {
if (containsOnly(files, VERIFICATION_FILES)) {
if (!cli.check(files)) {
throw new Exception("Data corruption detected"); // one or more hashes do not match
}

View File

@ -42,7 +42,6 @@ import java.util.stream.Stream;
import net.filebot.HistorySpooler;
import net.filebot.Language;
import net.filebot.MediaTypes;
import net.filebot.RenameAction;
import net.filebot.StandardRenameAction;
import net.filebot.archive.Archive;
@ -871,7 +870,7 @@ public class CmdlineOperations implements CmdlineInterface {
// only check existing hashes
boolean result = true;
for (File it : filter(files, MediaTypes.getDefaultFilter("verification"))) {
for (File it : filter(files, VERIFICATION_FILES)) {
result &= check(it, it.getParentFile());
}
@ -959,8 +958,9 @@ public class CmdlineOperations implements CmdlineInterface {
try {
for (File it : files) {
if (it.isHidden() || MediaTypes.getDefaultFilter("verification").accept(it))
if (it.isHidden() || VERIFICATION_FILES.accept(it)) {
continue;
}
String relativePath = normalizePathSeparators(it.getPath().substring(root.getPath().length() + 1)); // skip root and first slash
String hash = computeHash(it, hashType);

View File

@ -111,7 +111,7 @@ public class ScriptShellMethods {
}
// check disk image
if (self.isFile() && MediaTypes.getDefaultFilter("video/iso").accept(self)) {
if (self.isFile() && MediaTypes.getTypeFilter("video/iso").accept(self)) {
try {
return MediaDetection.isVideoDiskFile(self);
} catch (Exception e) {

View File

@ -881,7 +881,7 @@ public class MediaBindingBean {
@Define("mime")
public List<String> getMediaType() throws Exception {
// format engine does not allow / in binding value
return SLASH.splitAsStream(MediaTypes.getDefault().getMediaType(getExtension())).collect(toList());
return SLASH.splitAsStream(MediaTypes.getMediaType(getExtension())).collect(toList());
}
@Define("mediaPath")

View File

@ -22,7 +22,7 @@ public enum HashType {
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("verification/sfv");
return MediaTypes.getTypeFilter("verification/sfv");
}
},
@ -41,7 +41,7 @@ public enum HashType {
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("verification/md5sum");
return MediaTypes.getTypeFilter("verification/md5sum");
}
},
@ -60,7 +60,7 @@ public enum HashType {
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("verification/sha1sum");
return MediaTypes.getTypeFilter("verification/sha1sum");
}
@Override
@ -84,7 +84,7 @@ public enum HashType {
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("verification/sha256sum");
return MediaTypes.getTypeFilter("verification/sha256sum");
}
@Override
@ -107,7 +107,7 @@ public enum HashType {
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("verification/ed2k");
return MediaTypes.getTypeFilter("verification/ed2k");
}
@Override

View File

@ -1,178 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<media-types>
<!-- Application -->
<type name="application/torrent">
<extension>torrent</extension>
<extension>tor</extension>
</type>
<type name="application/list">
<extension>list</extension>
<extension>txt</extension>
</type>
<type name="application/nfo">
<extension>nfo</extension>
<extension>url</extension>
</type>
<!-- Verification -->
<type name="verification/sfv">
<extension>sfv</extension>
</type>
<type name="verification/md5sum">
<extension>md5</extension>
</type>
<type name="verification/sha1sum">
<extension>sha1</extension>
<extension>sha</extension>
</type>
<type name="verification/sha256sum">
<extension>sha256</extension>
<extension>sha2</extension>
</type>
<type name="verification/ed2k">
<extension>ed2k</extension>
</type>
<!-- Archives -->
<type name="archive/zip">
<extension>zip</extension>
</type>
<type name="archive/rar">
<extension>rar</extension>
</type>
<type name="archive/7z">
<extension>7z</extension>
</type>
<type name="archive/gzip">
<extension>gzip</extension>
<extension>gz</extension>
</type>
<type name="archive/tar">
<extension>tar</extension>
</type>
<type name="archive/bzip2">
<extension>bzip2</extension>
</type>
<!-- Audio -->
<type name="audio/mp3">
<extension>mp3</extension>
</type>
<type name="audio/mp4">
<extension>m4a</extension>
<extension>aac</extension>
</type>
<type name="audio/flac">
<extension>flac</extension>
</type>
<type name="audio/wma">
<extension>wma</extension>
</type>
<type name="audio/ogm">
<extension>ogg</extension>
<extension>ogm</extension>
<extension>ogv</extension>
<extension>oga</extension>
</type>
<type name="audio/wav">
<extension>wav</extension>
<extension>aiff</extension>
<extension>alac</extension>
</type>
<!-- Video -->
<type name="video/avi">
<extension>avi</extension>
</type>
<type name="video/mkv">
<extension>mkv</extension>
<extension>mk3d</extension>
</type>
<type name="video/ogm">
<extension>ogm</extension>
<extension>ogg</extension>
</type>
<type name="video/mp4">
<extension>mp4</extension>
<extension>m4v</extension>
<extension>3gp</extension>
</type>
<type name="video/mov">
<extension>mov</extension>
</type>
<type name="video/divx">
<extension>divx</extension>
</type>
<type name="video/mpeg">
<extension>mpg</extension>
<extension>mpeg</extension>
<extension>vob</extension>
<extension>ts</extension>
<extension>tp</extension>
<extension>m2ts</extension>
<extension>rec</extension>
</type>
<type name="video/wmv">
<extension>wmv</extension>
<extension>asf</extension>
<extension>wtv</extension>
</type>
<type name="video/WebM">
<extension>webm</extension>
</type>
<type name="video/flash">
<extension>flv</extension>
</type>
<type name="video/realmedia">
<extension>rm</extension>
<extension>rmvb</extension>
<extension>rmp4</extension>
</type>
<type name="video/tivo">
<extension>tivo</extension>
</type>
<type name="video/NuppelVideo">
<extension>nuv</extension>
</type>
<type name="video/3DSBS">
<extension>3DSBS</extension>
<extension>3DTAB</extension>
</type>
<type name="video/stream-descriptor">
<extension>strm</extension>
</type>
<type name="video/audio-stream">
<extension>ac3</extension>
<extension>dts</extension>
</type>
<type name="video/iso">
<extension>iso</extension>
</type>
<!-- Subtitles -->
<type name="subtitle/SubRip">
<extension>srt</extension>
</type>
<type name="subtitle/MicroDVD">
<extension>sub</extension>
</type>
<type name="subtitle/SubViewer">
<extension>sub</extension>
</type>
<type name="subtitle/SubStationAlpha">
<extension>ssa</extension>
<extension>ass</extension>
</type>
<type name="subtitle/SAMI">
<extension>smi</extension>
<extension>sami</extension>
</type>
<type name="subtitle/WebVTT">
<extension>vtt</extension>
</type>
<type name="subtitle/VobSub">
<extension>vobsub</extension>
<extension>sub</extension>
<extension>idx</extension>
</type>
</media-types>

View File

@ -12,6 +12,11 @@ public enum SubtitleFormat {
public SubtitleReader newReader(Readable readable) {
return new SubRipReader(readable);
}
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getTypeFilter("subtitle/SubRip");
}
},
MicroDVD {
@ -20,6 +25,11 @@ public enum SubtitleFormat {
public SubtitleReader newReader(Readable readable) {
return new MicroDVDReader(readable);
}
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getTypeFilter("subtitle/MicroDVD");
}
},
SubViewer {
@ -28,6 +38,11 @@ public enum SubtitleFormat {
public SubtitleReader newReader(Readable readable) {
return new SubViewerReader(readable);
}
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getTypeFilter("subtitle/SubViewer");
}
},
SubStationAlpha {
@ -36,12 +51,15 @@ public enum SubtitleFormat {
public SubtitleReader newReader(Readable readable) {
return new SubStationAlphaReader(readable);
}
@Override
public ExtensionFileFilter getFilter() {
return MediaTypes.getTypeFilter("subtitle/SubStationAlpha");
}
};
public abstract SubtitleReader newReader(Readable readable);
public ExtensionFileFilter getFilter() {
return MediaTypes.getDefaultFilter("subtitle/" + name());
}
public abstract ExtensionFileFilter getFilter();
}

View File

@ -296,7 +296,7 @@ class BindingDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent evt) {
ExtensionFileFilter mediaFiles = combineFilter(VIDEO_FILES, AUDIO_FILES, SUBTITLE_FILES);
ExtensionFileFilter mediaFiles = ExtensionFileFilter.union(VIDEO_FILES, AUDIO_FILES, SUBTITLE_FILES);
List<File> selection = showLoadDialogSelectFiles(false, false, getMediaFile(), mediaFiles, (String) getValue(NAME), evt);
if (selection.size() > 0) {

View File

@ -1,7 +1,6 @@
package net.filebot.ui.rename;
import static java.awt.datatransfer.DataFlavor.*;
import static java.util.Arrays.*;
import static java.util.stream.Collectors.*;
import static net.filebot.MediaTypes.*;
import static net.filebot.hash.VerificationUtilities.*;
@ -17,6 +16,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Stream;
import net.filebot.hash.HashType;
import net.filebot.hash.VerificationFileReader;
@ -24,6 +24,7 @@ import net.filebot.torrent.Torrent;
import net.filebot.ui.transfer.ArrayTransferable;
import net.filebot.ui.transfer.FileTransferablePolicy;
import net.filebot.util.FastFile;
import net.filebot.util.FileUtilities.ExtensionFileFilter;
import net.filebot.vfs.SimpleFileInfo;
import net.filebot.web.Episode;
@ -148,7 +149,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
@Override
public List<String> getFileFilterExtensions() {
return asList(combineFilter(VIDEO_FILES, SUBTITLE_FILES, AUDIO_FILES, LIST_FILES, TORRENT_FILES, VERIFICATION_FILES).extensions());
return Stream.of(VIDEO_FILES, SUBTITLE_FILES, AUDIO_FILES, LIST_FILES, TORRENT_FILES, VERIFICATION_FILES).map(ExtensionFileFilter::extensions).flatMap(Stream::of).collect(toList());
}
}

View File

@ -19,7 +19,6 @@ import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level;
import net.filebot.MediaTypes;
import net.filebot.hash.HashType;
import net.filebot.hash.VerificationFileReader;
import net.filebot.mac.MacAppUtilities;
@ -247,7 +246,7 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<C
if (seenLevel == null) {
// folder we have never encountered before
for (File verificationFile : getChildren(folder, MediaTypes.getDefaultFilter("verification"))) {
for (File verificationFile : getChildren(folder, VERIFICATION_FILES)) {
HashType hashType = getHashType(verificationFile);
cache.put(verificationFile, importVerificationFile(verificationFile, hashType, verificationFile.getParentFile()));
types.put(verificationFile, hashType);

View File

@ -140,7 +140,7 @@ abstract class SubtitleDropTarget extends JButton {
@Override
public void actionPerformed(ActionEvent evt) {
// collect media file extensions (video and subtitle files)
List<File> files = showLoadDialogSelectFiles(true, true, null, combineFilter(VIDEO_FILES, SUBTITLE_FILES), "Select Video Folder", evt);
List<File> files = showLoadDialogSelectFiles(true, true, null, ExtensionFileFilter.union(VIDEO_FILES, SUBTITLE_FILES), "Select Video Folder", evt);
if (files.size() > 0 && getDropAction(files) != DropAction.Cancel) {
handleDrop(files);

View File

@ -796,6 +796,16 @@ public final class FileUtilities {
}
return s.toString();
}
public static ExtensionFileFilter union(ExtensionFileFilter... filters) {
List<String> extensions = new ArrayList<String>();
for (ExtensionFileFilter it : filters) {
if (!it.acceptAny()) {
addAll(extensions, it.extensions());
}
}
return new ExtensionFileFilter(extensions);
}
}
public static class RegexFileFilter implements FileFilter, FilenameFilter {