parent
a0d09d2c83
commit
cfee1cbb51
|
@ -4,8 +4,15 @@ package net.sourceforge.filebot.web;
|
|||
|
||||
import static net.sourceforge.filebot.web.EpisodeUtilities.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
|
||||
public abstract class AbstractEpisodeListProvider implements EpisodeListProvider {
|
||||
|
@ -54,4 +61,60 @@ public abstract class AbstractEpisodeListProvider implements EpisodeListProvider
|
|||
return eps;
|
||||
}
|
||||
|
||||
|
||||
protected static class ResultCache {
|
||||
|
||||
private final String id;
|
||||
private final Cache cache;
|
||||
|
||||
|
||||
public ResultCache(String id, Cache cache) {
|
||||
this.id = id;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
|
||||
public void putSearchResult(String key, Collection<? extends SearchResult> value) {
|
||||
cache.put(new Element(key(id, "SearchResult", key), value.toArray(new SearchResult[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<SearchResult> getSearchResult(String key) {
|
||||
try {
|
||||
Element element = cache.get(key(id, "SearchResult", key));
|
||||
if (element != null) {
|
||||
return Arrays.asList(((SearchResult[]) element.getValue()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void putEpisodeList(int key, Locale language, List<Episode> episodes) {
|
||||
cache.put(new Element(key(id, "EpisodeList", key, language.getLanguage()), episodes.toArray(new Episode[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<Episode> getEpisodeList(int key, Locale language) {
|
||||
try {
|
||||
Element element = cache.get(key(id, "EpisodeList", key, language.getLanguage()));
|
||||
if (element != null) {
|
||||
return Arrays.asList((Episode[]) element.getValue());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AbstractEpisodeListProvider.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private String key(Object... key) {
|
||||
return Arrays.toString(key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,13 +6,10 @@ import static net.sourceforge.filebot.web.EpisodeUtilities.*;
|
|||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.tuned.XPathUtilities.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -29,16 +26,14 @@ import javax.swing.Icon;
|
|||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
|
||||
|
||||
public class AnidbClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private static final String host = "anidb.net";
|
||||
private static final AnidbCache cache = new AnidbCache(CacheManager.getInstance().getCache("web-persistent-datasource"));
|
||||
private final String host = "anidb.net";
|
||||
private final ResultCache cache = new ResultCache(host, CacheManager.getInstance().getCache("web-persistent-datasource"));
|
||||
|
||||
private final String client;
|
||||
private final int clientver;
|
||||
|
@ -96,7 +91,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
URL url = new URL("http", "api." + host, 9001, "/httpapi?request=anime&client=" + client + "&clientver=" + clientver + "&protover=1&aid=" + anime.getAnimeId());
|
||||
|
||||
// try cache first
|
||||
List<Episode> episodes = cache.getEpisodeList(anime.getAnimeId(), language.getLanguage());
|
||||
List<Episode> episodes = cache.getEpisodeList(anime.getAnimeId(), language);
|
||||
if (episodes != null)
|
||||
return episodes;
|
||||
|
||||
|
@ -134,7 +129,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
// sanity check
|
||||
if (episodes.size() > 0) {
|
||||
// populate cache
|
||||
cache.putEpisodeList(episodes, anime.getAnimeId(), language.getLanguage());
|
||||
cache.putEpisodeList(anime.getAnimeId(), language, episodes);
|
||||
} else {
|
||||
// anime page xml doesn't work sometimes
|
||||
throw new RuntimeException(String.format("Failed to parse episode data from xml: %s (%d)", anime, anime.getAnimeId()));
|
||||
|
@ -171,8 +166,8 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
protected List<AnidbSearchResult> getAnimeTitles() throws Exception {
|
||||
URL url = new URL("http", host, "/api/animetitles.dat.gz");
|
||||
|
||||
// try cache first
|
||||
List<AnidbSearchResult> anime = cache.getAnimeList();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<AnidbSearchResult> anime = (List) cache.getSearchResult(null);
|
||||
if (anime != null)
|
||||
return anime;
|
||||
|
||||
|
@ -221,13 +216,13 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
// populate cache
|
||||
cache.putAnimeList(anime);
|
||||
cache.putSearchResult(null, anime);
|
||||
|
||||
return anime;
|
||||
}
|
||||
|
||||
|
||||
public static class AnidbSearchResult extends SearchResult implements Serializable {
|
||||
public static class AnidbSearchResult extends SearchResult {
|
||||
|
||||
protected int aid;
|
||||
protected String primaryTitle; // one per anime
|
||||
|
@ -267,46 +262,4 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class AnidbCache {
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
|
||||
public AnidbCache(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
|
||||
public void putAnimeList(Collection<AnidbSearchResult> anime) {
|
||||
cache.put(new Element(host + "AnimeList", anime.toArray(new AnidbSearchResult[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<AnidbSearchResult> getAnimeList() {
|
||||
Element element = cache.get(host + "AnimeList");
|
||||
|
||||
if (element != null)
|
||||
return Arrays.asList((AnidbSearchResult[]) element.getValue());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void putEpisodeList(Collection<Episode> episodes, int aid, String lang) {
|
||||
cache.put(new Element(host + "EpisodeList" + aid + lang, episodes.toArray(new Episode[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<Episode> getEpisodeList(int aid, String lang) {
|
||||
Element element = cache.get(host + "EpisodeList" + aid + lang);
|
||||
|
||||
if (element != null)
|
||||
return Arrays.asList((Episode[]) element.getValue());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import net.sourceforge.filebot.ResourceManager;
|
|||
|
||||
public class IMDbClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private static final String host = "www.imdb.com";
|
||||
private final String host = "www.imdb.com";
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
public abstract class SearchResult {
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public abstract class SearchResult implements Serializable {
|
||||
|
||||
protected final String name;
|
||||
|
||||
|
|
|
@ -7,12 +7,9 @@ import static net.sourceforge.filebot.web.WebRequest.*;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
@ -24,16 +21,14 @@ import org.json.simple.JSONArray;
|
|||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
|
||||
|
||||
public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private static final String host = "api.serienjunkies.de";
|
||||
private static final SerienjunkiesCache cache = new SerienjunkiesCache(CacheManager.getInstance().getCache("web-persistent-datasource"));
|
||||
private final String host = "api.serienjunkies.de";
|
||||
private final ResultCache cache = new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
|
||||
|
||||
private final String apikey;
|
||||
|
||||
|
@ -76,8 +71,8 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
|
||||
|
||||
protected List<SerienjunkiesSearchResult> getSeriesTitles() throws IOException {
|
||||
// try cache first
|
||||
List<SerienjunkiesSearchResult> seriesList = cache.getSeriesList();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SerienjunkiesSearchResult> seriesList = (List) cache.getSearchResult(null);
|
||||
if (seriesList != null)
|
||||
return seriesList;
|
||||
|
||||
|
@ -100,7 +95,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
// populate cache
|
||||
cache.putSeriesList(seriesList);
|
||||
cache.putSearchResult(null, seriesList);
|
||||
|
||||
return seriesList;
|
||||
}
|
||||
|
@ -111,7 +106,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
SerienjunkiesSearchResult series = (SerienjunkiesSearchResult) searchResult;
|
||||
|
||||
// try cache first
|
||||
List<Episode> episodes = cache.getEpisodeList(series.getSeriesId());
|
||||
List<Episode> episodes = cache.getEpisodeList(series.getSeriesId(), Locale.GERMAN);
|
||||
if (episodes != null)
|
||||
return episodes;
|
||||
|
||||
|
@ -134,7 +129,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
// populate cache
|
||||
cache.putEpisodeList(episodes, series.getSeriesId());
|
||||
cache.putEpisodeList(series.getSeriesId(), Locale.GERMAN, episodes);
|
||||
|
||||
// make sure episodes are in ordered correctly
|
||||
sortEpisodes(episodes);
|
||||
|
@ -177,7 +172,7 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
|
||||
public static class SerienjunkiesSearchResult extends SearchResult implements Serializable {
|
||||
public static class SerienjunkiesSearchResult extends SearchResult {
|
||||
|
||||
protected int sid;
|
||||
protected String link;
|
||||
|
@ -231,46 +226,4 @@ public class SerienjunkiesClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SerienjunkiesCache {
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
|
||||
public SerienjunkiesCache(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
|
||||
public void putSeriesList(Collection<SerienjunkiesSearchResult> anime) {
|
||||
cache.put(new Element(host + "SeriesList", anime.toArray(new SerienjunkiesSearchResult[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<SerienjunkiesSearchResult> getSeriesList() {
|
||||
Element element = cache.get(host + "SeriesList");
|
||||
|
||||
if (element != null)
|
||||
return Arrays.asList((SerienjunkiesSearchResult[]) element.getValue());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void putEpisodeList(Collection<Episode> episodes, int sid) {
|
||||
cache.put(new Element(host + "EpisodeList" + sid, episodes.toArray(new Episode[0])));
|
||||
}
|
||||
|
||||
|
||||
public List<Episode> getEpisodeList(int sid) {
|
||||
Element element = cache.get(host + "EpisodeList" + sid);
|
||||
|
||||
if (element != null)
|
||||
return Arrays.asList((Episode[]) element.getValue());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,12 +19,14 @@ import org.w3c.dom.Document;
|
|||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
|
||||
|
||||
public class TVRageClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private static final String host = "services.tvrage.com";
|
||||
private final String host = "services.tvrage.com";
|
||||
private final ResultCache cache = new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -41,13 +43,10 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
|
||||
@Override
|
||||
public List<SearchResult> search(String query, Locale locale) throws IOException, SAXException {
|
||||
|
||||
URL searchUrl = new URL("http", host, "/feeds/full_search.php?show=" + encode(query));
|
||||
|
||||
Document dom = getDocument(searchUrl);
|
||||
|
||||
List<Node> nodes = selectNodes("Results/show", dom);
|
||||
|
||||
List<SearchResult> searchResults = new ArrayList<SearchResult>(nodes.size());
|
||||
|
||||
for (Node node : nodes) {
|
||||
|
@ -64,15 +63,19 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
|
||||
@Override
|
||||
public List<Episode> getEpisodeList(SearchResult searchResult, Locale locale) throws IOException, SAXException {
|
||||
int showId = ((TVRageSearchResult) searchResult).getShowId();
|
||||
URL episodeListUrl = new URL("http", host, "/feeds/full_show_info.php?sid=" + showId);
|
||||
TVRageSearchResult series = (TVRageSearchResult) searchResult;
|
||||
|
||||
List<Episode> episodes = cache.getEpisodeList(series.getSeriesId(), Locale.ENGLISH);
|
||||
if (episodes != null)
|
||||
return episodes;
|
||||
|
||||
URL episodeListUrl = new URL("http", host, "/feeds/full_show_info.php?sid=" + series.getSeriesId());
|
||||
Document dom = getDocument(episodeListUrl);
|
||||
|
||||
String seriesName = selectString("Show/name", dom);
|
||||
Date seriesStartDate = Date.parse(selectString("Show/started", dom), "MMM/dd/yyyy");
|
||||
|
||||
List<Episode> episodes = new ArrayList<Episode>(25);
|
||||
episodes = new ArrayList<Episode>(25);
|
||||
List<Episode> specials = new ArrayList<Episode>(5);
|
||||
|
||||
// episodes and specials
|
||||
|
@ -98,6 +101,7 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
// add specials at the end
|
||||
episodes.addAll(specials);
|
||||
|
||||
cache.putEpisodeList(series.getSeriesId(), Locale.ENGLISH, episodes);
|
||||
return episodes;
|
||||
}
|
||||
|
||||
|
@ -134,7 +138,7 @@ public class TVRageClient extends AbstractEpisodeListProvider {
|
|||
}
|
||||
|
||||
|
||||
public int getShowId() {
|
||||
public int getSeriesId() {
|
||||
return showId;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.io.FileNotFoundException;
|
|||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -29,21 +28,18 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
|
||||
|
||||
public class TheTVDBClient extends AbstractEpisodeListProvider {
|
||||
|
||||
private static final String host = "www.thetvdb.com";
|
||||
|
||||
private final String apikey;
|
||||
private final String host = "www.thetvdb.com";
|
||||
|
||||
private final Map<MirrorType, String> mirrors = new EnumMap<MirrorType, String>(MirrorType.class);
|
||||
private final ResultCache cache = new ResultCache(host, CacheManager.getInstance().getCache("web-datasource"));
|
||||
|
||||
private final TheTVDBCache cache = new TheTVDBCache(CacheManager.getInstance().getCache("web-datasource"));
|
||||
private final String apikey;
|
||||
|
||||
|
||||
public TheTVDBClient(String apikey) {
|
||||
|
@ -315,37 +311,4 @@ public class TheTVDBClient extends AbstractEpisodeListProvider {
|
|||
|
||||
}
|
||||
|
||||
|
||||
private static class TheTVDBCache {
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
|
||||
public TheTVDBCache(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
|
||||
public void putEpisodeList(int seriesId, Locale language, List<Episode> episodes) {
|
||||
cache.put(new Element(key(host, "EpisodeList", seriesId, language.getLanguage()), episodes));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Episode> getEpisodeList(int seriesId, Locale language) {
|
||||
Element element = cache.get(key(host, "EpisodeList", seriesId, language.getLanguage()));
|
||||
|
||||
if (element != null)
|
||||
return (List<Episode>) element.getValue();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private String key(Object... key) {
|
||||
return Arrays.toString(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,14 @@ import static net.sourceforge.filebot.ui.rename.MatchSimilarityMetric.*;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.filebot.similarity.Match;
|
||||
import net.sourceforge.filebot.similarity.Matcher;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.web.Date;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
|
||||
|
@ -18,7 +23,7 @@ public class MatchSimilarityMetricTest {
|
|||
@Test
|
||||
public void substringMetrics() {
|
||||
Episode eY1T1 = new Episode("Doctor Who", new Date(2005, 0, 0), 1, 1, "Rose");
|
||||
Episode eY2T2 = new Episode("Doctor Who", new Date(1963, 0, 0), 1, 1, "An Unearthly Child");
|
||||
// Episode eY2T2 = new Episode("Doctor Who", new Date(1963, 0, 0), 1, 1, "An Unearthly Child");
|
||||
File fY1T1 = new File("Doctor Who (2005)/Doctor Who - 1x01 - Rose");
|
||||
File fY2T2 = new File("Doctor Who (1963)/Doctor Who - 1x01 - An Unearthly Child");
|
||||
|
||||
|
@ -44,4 +49,24 @@ public class MatchSimilarityMetricTest {
|
|||
assertEquals("abc", MatchSimilarityMetric.normalizeObject(new File("/folder/abc[EF62DF13].txt")));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void matcherLevel2() throws Exception {
|
||||
List<File> files = new ArrayList<File>();
|
||||
List<Episode> episodes = new ArrayList<Episode>();
|
||||
|
||||
files.add(new File("Greek/Greek - S01E19 - No Campus for Old Rules"));
|
||||
files.add(new File("Veronica Mars - Season 1/Veronica Mars [1x19] Hot Dogs"));
|
||||
episodes.add(new Episode("Veronica Mars", null, 1, 19, "Hot Dogs"));
|
||||
episodes.add(new Episode("Greek", null, 1, 19, "No Campus for Old Rules"));
|
||||
|
||||
SimilarityMetric[] metrics = new SimilarityMetric[] { EpisodeIdentifier, Title };
|
||||
List<Match<File, Episode>> m = new Matcher<File, Episode>(files, episodes, true, metrics).match();
|
||||
|
||||
assertEquals("Greek - S01E19 - No Campus for Old Rules", m.get(0).getValue().getName());
|
||||
assertEquals("Greek - 1x19 - No Campus for Old Rules", m.get(0).getCandidate().toString());
|
||||
assertEquals("Veronica Mars [1x19] Hot Dogs", m.get(1).getValue().getName());
|
||||
assertEquals("Veronica Mars - 1x19 - Hot Dogs", m.get(1).getCandidate().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public class TVRageClientTest {
|
|||
TVRageSearchResult result = (TVRageSearchResult) results.get(0);
|
||||
|
||||
assertEquals(buffySearchResult.getName(), result.getName());
|
||||
assertEquals(buffySearchResult.getShowId(), result.getShowId());
|
||||
assertEquals(buffySearchResult.getSeriesId(), result.getSeriesId());
|
||||
assertEquals(buffySearchResult.getLink(), result.getLink());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue