* set foundation for possible future fine-tuning of SxE pattern matching combined with release info knowledge

This commit is contained in:
Reinhard Pointner 2013-11-27 18:49:15 +00:00
parent eff07ec40f
commit 9e41373f43
3 changed files with 52 additions and 13 deletions

View File

@ -111,16 +111,20 @@ public class MediaDetection {
return releaseInfo.getLanguageSuffix(getName(file));
}
public static SeasonEpisodeMatcher getSeasonEpisodeMatcher(boolean strict) {
return new SeasonEpisodeMatcherWithFilter(strict);
}
public static boolean isEpisode(String name, boolean strict) {
return parseEpisodeNumber(name, strict) != null || parseDate(name) != null;
}
public static List<SxE> parseEpisodeNumber(String string, boolean strict) {
return new SeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, strict).match(string);
return getSeasonEpisodeMatcher(strict).match(string);
}
public static List<SxE> parseEpisodeNumber(File file, boolean strict) {
return new SeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, strict).match(file);
return getSeasonEpisodeMatcher(strict).match(file);
}
public static Date parseDate(Object object) {
@ -248,7 +252,7 @@ public class MediaDetection {
public static Object getEpisodeIdentifier(CharSequence name, boolean strict) {
// check SxE first
Object match = new SeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, true).match(name);
Object match = getSeasonEpisodeMatcher(true).match(name);
// then Date pattern
if (match == null) {
@ -257,7 +261,7 @@ public class MediaDetection {
// check SxE non-strict
if (match == null && !strict) {
match = new SeasonEpisodeMatcher(SeasonEpisodeMatcher.DEFAULT_SANITY, false).match(name);
match = getSeasonEpisodeMatcher(false).match(name);
}
return match;
@ -1040,6 +1044,33 @@ public class MediaDetection {
}
}
private static class SeasonEpisodeMatcherWithFilter extends SeasonEpisodeMatcher {
private final Pattern ignorePattern = MediaDetection.releaseInfo.getVideoFormatPattern(false);
public SeasonEpisodeMatcherWithFilter(boolean strict) {
super(DEFAULT_SANITY, strict);
}
protected String clean(CharSequence name) {
return ignorePattern.matcher(name).replaceAll("");
}
@Override
public List<SxE> match(CharSequence name) {
return super.match(clean(name));
}
@Override
protected List<String> tokenizeTail(File file) {
List<String> tail = super.tokenizeTail(file);
for (int i = 0; i < tail.size(); i++) {
tail.set(i, clean(tail.get(i)));
}
return tail;
}
}
public static void storeMetaInfo(File file, Object model) {
// only for Episode / Movie objects
if ((model instanceof Episode || model instanceof Movie) && file.exists()) {

View File

@ -119,7 +119,7 @@ public class ReleaseInfo {
Pattern languageSuffix = getLanguageSuffixPattern(languages, strict);
Pattern languageTag = getLanguageTagPattern(languages);
Pattern videoSource = getVideoSourcePattern();
Pattern videoFormat = getVideoFormatPattern();
Pattern videoFormat = getVideoFormatPattern(strict);
Pattern resolution = getResolutionPattern();
Pattern queryBlacklist = getBlacklistPattern();
@ -226,10 +226,10 @@ public class ReleaseInfo {
return compile("(?<!\\p{Alnum})(\\d{4}|[6-9]\\d{2})x(\\d{4}|[4-9]\\d{2})(?!\\p{Alnum})");
}
public Pattern getVideoFormatPattern() {
public Pattern getVideoFormatPattern(boolean strict) {
// pattern matching any video source name
String pattern = getBundle(getClass().getName()).getString("pattern.video.format");
return compile("(?<!\\p{Alnum})(" + pattern + ")(?!\\p{Alnum})", CASE_INSENSITIVE);
return strict ? compile("(?<!\\p{Alnum})(" + pattern + ")(?!\\p{Alnum})", CASE_INSENSITIVE) : compile(pattern, CASE_INSENSITIVE);
}
public Pattern getVideoSourcePattern() {

View File

@ -107,7 +107,7 @@ public class SeasonEpisodeMatcher {
}
};
// match patterns like 101, 102 (and greedily just grab the first)
// (last-resort) match patterns like 101, 102 (and greedily just grab the first)
Num101_SUBSTRING = new SeasonEpisodePattern(STRICT_SANITY, "(\\d{1})(\\d{2}).+") {
@Override
@ -148,17 +148,17 @@ public class SeasonEpisodeMatcher {
public List<SxE> match(File file) {
// take folder name into consideration as much as file name but put priority on file name
List<File> pathTail = listPathTail(file, 2, true);
List<String> tail = tokenizeTail(file);
for (SeasonEpisodeParser pattern : patterns) {
for (File tail : pathTail) {
List<SxE> match = pattern.match(tail.getName());
for (int t = 0; t < tail.size(); t++) {
List<SxE> match = pattern.match(tail.get(t));
if (!match.isEmpty()) {
// current pattern did match
for (int i = 0; i < match.size(); i++) {
if (match.get(i).season < 0) {
Matcher sm = seasonPattern.matcher(file.getPath());
if (match.get(i).season < 0 && t < tail.size() - 1) {
Matcher sm = seasonPattern.matcher(tail.get(t + 1));
if (sm.find()) {
match.set(i, new SxE(Integer.parseInt(sm.group(1)), match.get(i).episode));
}
@ -171,6 +171,14 @@ public class SeasonEpisodeMatcher {
return null;
}
protected List<String> tokenizeTail(File file) {
List<String> tail = new ArrayList<String>(2);
for (File f : listPathTail(file, 2, true)) {
tail.add(getName(f));
}
return tail;
}
public int find(CharSequence name, int fromIndex) {
for (SeasonEpisodeParser pattern : patterns) {
int index = pattern.find(name, fromIndex);