1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-12-25 09:18:51 -05:00

+ ReleaseDate metric matching step for differentiating multiple shows with the same name, usually nudging things towards the more recent episode/series.

This commit is contained in:
Reinhard Pointner 2012-10-09 13:30:32 +00:00
parent bf6cccfbbb
commit a248021ebf
4 changed files with 81 additions and 19 deletions

View File

@ -284,6 +284,26 @@ public enum EpisodeMetrics implements SimilarityMetric {
return null; return null;
} }
}),
// Match by file last modified and episode release dates
TimeStamp(new TimeStampMetric() {
@Override
public float getSimilarity(Object o1, Object o2) {
// adjust differentiation accuracy to about a year
return (float) (floor(super.getSimilarity(o1, o2) * 40) / 40);
}
@Override
public long getTimeStamp(Object object) {
if (object instanceof Episode) {
return ((Episode) object).airdate().getTimeStamp();
}
return super.getTimeStamp(object);
}
}); });
// inner metric // inner metric
@ -338,11 +358,12 @@ public enum EpisodeMetrics implements SimilarityMetric {
// 4 pass: divide by folder / file name and show name / episode title // 4 pass: divide by folder / file name and show name / episode title
// 5 pass: divide by name (rounded into n levels) // 5 pass: divide by name (rounded into n levels)
// 6 pass: divide by generic numeric similarity // 6 pass: divide by generic numeric similarity
// 7 pass: resolve remaining collisions via absolute string similarity // 7 pass: prefer episodes that were aired closer to the last modified date of the file
// 8 pass: resolve remaining collisions via absolute string similarity
if (includeFileMetrics) { if (includeFileMetrics) {
return new SimilarityMetric[] { FileSize, new MetricCascade(FileName, EpisodeFunnel), EpisodeBalancer, SubstringFields, new MetricCascade(SubstringSequence, Name), Numeric, new NameSimilarityMetric() }; return new SimilarityMetric[] { FileSize, new MetricCascade(FileName, EpisodeFunnel), EpisodeBalancer, SubstringFields, new MetricCascade(SubstringSequence, Name), Numeric, Name, TimeStamp, new NameSimilarityMetric() };
} else { } else {
return new SimilarityMetric[] { EpisodeFunnel, EpisodeBalancer, SubstringFields, new MetricCascade(SubstringSequence, Name), Numeric, new NameSimilarityMetric() }; return new SimilarityMetric[] { EpisodeFunnel, EpisodeBalancer, SubstringFields, new MetricCascade(SubstringSequence, Name), Numeric, Name, TimeStamp, new NameSimilarityMetric() };
} }
} }

View File

@ -0,0 +1,38 @@
package net.sourceforge.filebot.similarity;
import static java.lang.Math.*;
import java.io.File;
public class TimeStampMetric implements SimilarityMetric {
@Override
public float getSimilarity(Object o1, Object o2) {
long t1 = getTimeStamp(o1);
long t2 = getTimeStamp(o2);
if (t1 <= 0 || t2 <= 0)
return 0;
float min = min(t1, t2);
float max = max(t1, t2);
return min / max;
}
public long getTimeStamp(Object obj) {
if (obj instanceof File) {
return ((File) obj).lastModified();
}
if (obj instanceof Number) {
return ((Number) obj).longValue();
}
return -1;
}
}

View File

@ -3,9 +3,8 @@ package net.sourceforge.filebot.subtitle;
import static java.lang.Math.*; import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static net.sourceforge.filebot.MediaTypes.*; import static net.sourceforge.filebot.MediaTypes.*;
import static net.sourceforge.filebot.similarity.EpisodeMetrics.*;
import static net.sourceforge.filebot.similarity.Normalization.*; import static net.sourceforge.filebot.similarity.Normalization.*;
import static net.sourceforge.tuned.FileUtilities.*; import static net.sourceforge.tuned.FileUtilities.*;
@ -30,6 +29,7 @@ import net.sourceforge.filebot.similarity.EpisodeMetrics;
import net.sourceforge.filebot.similarity.Match; import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.similarity.Matcher; import net.sourceforge.filebot.similarity.Matcher;
import net.sourceforge.filebot.similarity.MetricAvg; import net.sourceforge.filebot.similarity.MetricAvg;
import net.sourceforge.filebot.similarity.MetricCascade;
import net.sourceforge.filebot.similarity.NameSimilarityMetric; import net.sourceforge.filebot.similarity.NameSimilarityMetric;
import net.sourceforge.filebot.similarity.SequenceMatchSimilarity; import net.sourceforge.filebot.similarity.SequenceMatchSimilarity;
import net.sourceforge.filebot.similarity.SimilarityMetric; import net.sourceforge.filebot.similarity.SimilarityMetric;
@ -46,10 +46,8 @@ public final class SubtitleUtilities {
public static Map<File, SubtitleDescriptor> matchSubtitles(Collection<File> files, Collection<SubtitleDescriptor> subtitles, boolean strict) throws InterruptedException { public static Map<File, SubtitleDescriptor> matchSubtitles(Collection<File> files, Collection<SubtitleDescriptor> subtitles, boolean strict) throws InterruptedException {
Map<File, SubtitleDescriptor> subtitleByVideo = new LinkedHashMap<File, SubtitleDescriptor>(); Map<File, SubtitleDescriptor> subtitleByVideo = new LinkedHashMap<File, SubtitleDescriptor>();
SimilarityMetric[] metrics = EpisodeMetrics.defaultSequence(false);
// optimize for generic media <-> subtitle matching // optimize for generic media <-> subtitle matching
replaceAll(asList(metrics), EpisodeMetrics.SubstringFields, EpisodeMetrics.SubstringSequence); SimilarityMetric[] metrics = new SimilarityMetric[] { EpisodeFunnel, EpisodeBalancer, SubstringSequence, new MetricCascade(SubstringSequence, Name), Numeric, new NameSimilarityMetric() };
// first match everything as best as possible, then filter possibly bad matches // first match everything as best as possible, then filter possibly bad matches
Matcher<File, SubtitleDescriptor> matcher = new Matcher<File, SubtitleDescriptor>(files, subtitles, false, metrics); Matcher<File, SubtitleDescriptor> matcher = new Matcher<File, SubtitleDescriptor>(files, subtitles, false, metrics);

View File

@ -49,6 +49,11 @@ public class Date implements Serializable {
} }
public long getTimeStamp() {
return new GregorianCalendar(year, month, day).getTimeInMillis();
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof Date) { if (obj instanceof Date) {