mirror of
https://github.com/mitb-archive/filebot
synced 2024-11-17 06:45:06 -05:00
* use TV Series index only for TV-mode and Anime index only for Anime-mode
This commit is contained in:
parent
c4ab4e8382
commit
ef2a64003b
@ -41,7 +41,6 @@ import net.sourceforge.filebot.HistorySpooler;
|
||||
import net.sourceforge.filebot.Language;
|
||||
import net.sourceforge.filebot.MediaTypes;
|
||||
import net.sourceforge.filebot.RenameAction;
|
||||
import net.sourceforge.filebot.WebServices;
|
||||
import net.sourceforge.filebot.archive.Archive;
|
||||
import net.sourceforge.filebot.archive.FileMapper;
|
||||
import net.sourceforge.filebot.format.ExpressionFilter;
|
||||
@ -130,9 +129,9 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
|
||||
CLILogger.finest(format("Filename pattern: [%.02f] SxE, [%.02f] CWS", sxe / max, cws / max));
|
||||
if (sxe > (max * 0.65) || cws > (max * 0.65)) {
|
||||
return renameSeries(files, action, conflictAction, outputDir, format, WebServices.TheTVDB, query, SortOrder.forName(sortOrder), filter, locale, strict); // use default episode db
|
||||
return renameSeries(files, action, conflictAction, outputDir, format, TheTVDB, query, SortOrder.forName(sortOrder), filter, locale, strict); // use default episode db
|
||||
} else {
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, WebServices.TMDb, query, filter, locale, strict); // use default movie db
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, TMDb, query, filter, locale, strict); // use default movie db
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +150,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
List<Match<File, ?>> matches = new ArrayList<Match<File, ?>>();
|
||||
|
||||
// auto-determine optimal batch sets
|
||||
for (Entry<Set<File>, Set<String>> sameSeriesGroup : mapSeriesNamesByFiles(mediaFiles, locale).entrySet()) {
|
||||
for (Entry<Set<File>, Set<String>> sameSeriesGroup : mapSeriesNamesByFiles(mediaFiles, locale, db != AniDB, db == AniDB).entrySet()) {
|
||||
List<List<File>> batchSets = new ArrayList<List<File>>();
|
||||
|
||||
if (sameSeriesGroup.getValue() != null && sameSeriesGroup.getValue().size() > 0) {
|
||||
@ -168,7 +167,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
// auto-detect series name if not given
|
||||
if (query == null) {
|
||||
// detect series name by common word sequence
|
||||
seriesNames = detectSeriesNames(batch, locale);
|
||||
seriesNames = detectSeriesNames(batch, locale, db != AniDB, db == AniDB);
|
||||
CLILogger.config("Auto-detected query: " + seriesNames);
|
||||
} else {
|
||||
// use --q option
|
||||
@ -663,7 +662,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
}
|
||||
|
||||
// lookup subtitles by hash
|
||||
for (VideoHashSubtitleService service : WebServices.getVideoHashSubtitleServices()) {
|
||||
for (VideoHashSubtitleService service : getVideoHashSubtitleServices()) {
|
||||
if (remainingVideos.isEmpty() || (databaseFilter != null && !databaseFilter.matcher(service.getName()).matches())) {
|
||||
continue;
|
||||
}
|
||||
@ -687,7 +686,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
if (query == null) {
|
||||
try {
|
||||
List<File> videoFiles = filter(files, VIDEO_FILES);
|
||||
querySet.addAll(detectSeriesNames(videoFiles, language.getLocale()));
|
||||
querySet.addAll(detectSeriesNames(videoFiles, language.getLocale(), true, false));
|
||||
|
||||
// auto-detect movie names
|
||||
for (File f : videoFiles) {
|
||||
@ -708,7 +707,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||
querySet.add(query);
|
||||
}
|
||||
|
||||
for (SubtitleProvider service : WebServices.getSubtitleProviders()) {
|
||||
for (SubtitleProvider service : getSubtitleProviders()) {
|
||||
if (remainingVideos.isEmpty() || (databaseFilter != null && !databaseFilter.matcher(service.getName()).matches())) {
|
||||
continue;
|
||||
}
|
||||
|
@ -134,14 +134,14 @@ public class MediaDetection {
|
||||
return new DateMetric().parse(object);
|
||||
}
|
||||
|
||||
public static Map<Set<File>, Set<String>> mapSeriesNamesByFiles(Collection<File> files, Locale locale) throws Exception {
|
||||
public static Map<Set<File>, Set<String>> mapSeriesNamesByFiles(Collection<File> files, Locale locale, boolean useSeriesIndex, boolean useAnimeIndex) throws Exception {
|
||||
// map series names by folder
|
||||
Map<File, Set<String>> seriesNamesByFolder = new HashMap<File, Set<String>>();
|
||||
Map<File, List<File>> filesByFolder = mapByFolder(files);
|
||||
|
||||
for (Entry<File, List<File>> it : filesByFolder.entrySet()) {
|
||||
Set<String> namesForFolder = new TreeSet<String>(getLenientCollator(locale));
|
||||
namesForFolder.addAll(detectSeriesNames(it.getValue(), locale));
|
||||
namesForFolder.addAll(detectSeriesNames(it.getValue(), locale, useSeriesIndex, useAnimeIndex));
|
||||
|
||||
seriesNamesByFolder.put(it.getKey(), namesForFolder);
|
||||
}
|
||||
@ -271,6 +271,20 @@ public class MediaDetection {
|
||||
}
|
||||
|
||||
public static List<String> detectSeriesNames(Collection<File> files, Locale locale) throws Exception {
|
||||
return detectSeriesNames(files, locale, true, true);
|
||||
}
|
||||
|
||||
public static List<String> detectSeriesNames(Collection<File> files, Locale locale, boolean useSeriesIndex, boolean useAnimeIndex) throws Exception {
|
||||
List<IndexEntry<SearchResult>> index = new ArrayList<IndexEntry<SearchResult>>();
|
||||
if (useSeriesIndex)
|
||||
index.addAll(getSeriesIndex());
|
||||
if (useAnimeIndex)
|
||||
index.addAll(getAnimeIndex());
|
||||
|
||||
return detectSeriesNames(files, locale, index);
|
||||
}
|
||||
|
||||
public static List<String> detectSeriesNames(Collection<File> files, Locale locale, List<IndexEntry<SearchResult>> seriesIndex) throws Exception {
|
||||
List<String> names = new ArrayList<String>();
|
||||
|
||||
// try xattr metadata if enabled
|
||||
@ -400,17 +414,16 @@ public class MediaDetection {
|
||||
return matches;
|
||||
}
|
||||
|
||||
private static final List<IndexEntry<SearchResult>> seriesIndex = new ArrayList<IndexEntry<SearchResult>>(100000);
|
||||
private static final ArrayList<IndexEntry<SearchResult>> seriesIndex = new ArrayList<IndexEntry<SearchResult>>(0);
|
||||
|
||||
public static List<IndexEntry<SearchResult>> getSeriesIndex() throws IOException {
|
||||
synchronized (seriesIndex) {
|
||||
if (seriesIndex.isEmpty()) {
|
||||
seriesIndex.ensureCapacity(100000);
|
||||
try {
|
||||
for (SearchResult[] index : new SearchResult[][] { releaseInfo.getTheTVDBIndex(), releaseInfo.getAnidbIndex() }) {
|
||||
for (SearchResult it : index) {
|
||||
for (SearchResult it : releaseInfo.getTheTVDBIndex()) {
|
||||
seriesIndex.addAll(HighPerformanceMatcher.prepare(it));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// can't load movie index, just try again next time
|
||||
Logger.getLogger(MediaDetection.class.getClass().getName()).log(Level.SEVERE, "Failed to load series index: " + e.getMessage(), e);
|
||||
@ -423,6 +436,28 @@ public class MediaDetection {
|
||||
}
|
||||
}
|
||||
|
||||
private static final ArrayList<IndexEntry<SearchResult>> animeIndex = new ArrayList<IndexEntry<SearchResult>>(0);
|
||||
|
||||
public static List<IndexEntry<SearchResult>> getAnimeIndex() throws IOException {
|
||||
synchronized (animeIndex) {
|
||||
if (animeIndex.isEmpty()) {
|
||||
animeIndex.ensureCapacity(50000);
|
||||
try {
|
||||
for (SearchResult it : releaseInfo.getAnidbIndex()) {
|
||||
animeIndex.addAll(HighPerformanceMatcher.prepare(it));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// can't load movie index, just try again next time
|
||||
Logger.getLogger(MediaDetection.class.getClass().getName()).log(Level.SEVERE, "Failed to load anime index: " + e.getMessage(), e);
|
||||
|
||||
// rely on online search
|
||||
return emptyList();
|
||||
}
|
||||
}
|
||||
return animeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> matchSeriesByName(Collection<String> files, int maxStartIndex) throws Exception {
|
||||
HighPerformanceMatcher nameMatcher = new HighPerformanceMatcher(maxStartIndex);
|
||||
List<String> matches = new ArrayList<String>();
|
||||
@ -755,11 +790,12 @@ public class MediaDetection {
|
||||
return matches != null && matches.size() > 0 ? matches.get(0) : null;
|
||||
}
|
||||
|
||||
private static final List<IndexEntry<Movie>> movieIndex = new ArrayList<IndexEntry<Movie>>(100000);
|
||||
private static final ArrayList<IndexEntry<Movie>> movieIndex = new ArrayList<IndexEntry<Movie>>(0);
|
||||
|
||||
public static List<IndexEntry<Movie>> getMovieIndex() throws IOException {
|
||||
synchronized (movieIndex) {
|
||||
if (movieIndex.isEmpty()) {
|
||||
movieIndex.ensureCapacity(100000);
|
||||
try {
|
||||
for (Movie it : releaseInfo.getMovieList()) {
|
||||
movieIndex.addAll(HighPerformanceMatcher.prepare(it));
|
||||
|
@ -50,11 +50,16 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
||||
|
||||
private final EpisodeListProvider provider;
|
||||
|
||||
private boolean useAnimeIndex;
|
||||
private boolean useSeriesIndex;
|
||||
|
||||
// only allow one fetch session at a time so later requests can make use of cached results
|
||||
private final Object providerLock = new Object();
|
||||
|
||||
public EpisodeListMatcher(EpisodeListProvider provider) {
|
||||
public EpisodeListMatcher(EpisodeListProvider provider, boolean useSeriesIndex, boolean useAnimeIndex) {
|
||||
this.provider = provider;
|
||||
this.useSeriesIndex = useSeriesIndex;
|
||||
this.useAnimeIndex = useAnimeIndex;
|
||||
}
|
||||
|
||||
protected SearchResult selectSearchResult(final String query, final List<SearchResult> searchResults, Map<String, SearchResult> selectionMemory, final Component parent) throws Exception {
|
||||
@ -180,7 +185,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
||||
final Map<String, List<String>> inputMemory = new TreeMap<String, List<String>>(CommonSequenceMatcher.getLenientCollator(Locale.ROOT));
|
||||
|
||||
// detect series names and create episode list fetch tasks
|
||||
for (Entry<Set<File>, Set<String>> sameSeriesGroup : mapSeriesNamesByFiles(mediaFiles, locale).entrySet()) {
|
||||
for (Entry<Set<File>, Set<String>> sameSeriesGroup : mapSeriesNamesByFiles(mediaFiles, locale, useSeriesIndex, useAnimeIndex).entrySet()) {
|
||||
final List<List<File>> batchSets = new ArrayList<List<File>>();
|
||||
final Collection<String> queries = sameSeriesGroup.getValue();
|
||||
|
||||
@ -265,7 +270,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher {
|
||||
|
||||
// require user input if auto-detection has failed or has been disabled
|
||||
if (episodes.isEmpty()) {
|
||||
List<String> detectedSeriesNames = detectSeriesNames(files, locale);
|
||||
List<String> detectedSeriesNames = detectSeriesNames(files, locale, useSeriesIndex, useAnimeIndex);
|
||||
String parentPathHint = normalizePathSeparators(getRelativePathTail(files.get(0).getParentFile(), 2).getPath());
|
||||
String suggestion = detectedSeriesNames.size() > 0 ? join(detectedSeriesNames, ", ") : parentPathHint;
|
||||
|
||||
|
@ -288,8 +288,8 @@ public class RenamePanel extends JComponent {
|
||||
actionPopup.addDescription(new JLabel("Episode Mode:"));
|
||||
|
||||
// create actions for match popup episode list completion
|
||||
for (EpisodeListProvider provider : WebServices.getEpisodeListProviders()) {
|
||||
actionPopup.add(new AutoCompleteAction(provider.getName(), provider.getIcon(), new EpisodeListMatcher(provider)));
|
||||
for (EpisodeListProvider db : WebServices.getEpisodeListProviders()) {
|
||||
actionPopup.add(new AutoCompleteAction(db.getName(), db.getIcon(), new EpisodeListMatcher(db, db != WebServices.AniDB, db == WebServices.AniDB)));
|
||||
}
|
||||
|
||||
actionPopup.addSeparator();
|
||||
|
@ -935,7 +935,7 @@ class SubtitleAutoMatchDialog extends JDialog {
|
||||
Collection<String> querySet = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// auto-detect series names
|
||||
querySet.addAll(detectSeriesNames(files, Locale.ROOT));
|
||||
querySet.addAll(detectSeriesNames(files, Locale.ROOT, true, false));
|
||||
|
||||
// auto-detect movie names
|
||||
for (File f : files) {
|
||||
|
Loading…
Reference in New Issue
Block a user