From cfee1cbb510ae3ca486148eb595eef1abf1e81d3 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sun, 13 Nov 2011 18:22:50 +0000 Subject: [PATCH] * refactor caching * added caching to tvrage --- .../web/AbstractEpisodeListProvider.java | 63 +++++++++++++++++++ .../sourceforge/filebot/web/AnidbClient.java | 63 +++---------------- .../sourceforge/filebot/web/IMDbClient.java | 2 +- .../sourceforge/filebot/web/SearchResult.java | 5 +- .../filebot/web/SerienjunkiesClient.java | 63 +++---------------- .../sourceforge/filebot/web/TVRageClient.java | 20 +++--- .../filebot/web/TheTVDBClient.java | 43 +------------ .../ui/rename/MatchSimilarityMetricTest.java | 27 +++++++- .../filebot/web/TVRageClientTest.java | 2 +- 9 files changed, 126 insertions(+), 162 deletions(-) diff --git a/source/net/sourceforge/filebot/web/AbstractEpisodeListProvider.java b/source/net/sourceforge/filebot/web/AbstractEpisodeListProvider.java index fadf8fcc..47cafa2e 100644 --- a/source/net/sourceforge/filebot/web/AbstractEpisodeListProvider.java +++ b/source/net/sourceforge/filebot/web/AbstractEpisodeListProvider.java @@ -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 value) { + cache.put(new Element(key(id, "SearchResult", key), value.toArray(new SearchResult[0]))); + } + + + public List 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 episodes) { + cache.put(new Element(key(id, "EpisodeList", key, language.getLanguage()), episodes.toArray(new Episode[0]))); + } + + + public List 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); + } + } + } diff --git a/source/net/sourceforge/filebot/web/AnidbClient.java b/source/net/sourceforge/filebot/web/AnidbClient.java index cb04dc72..7c76351e 100644 --- a/source/net/sourceforge/filebot/web/AnidbClient.java +++ b/source/net/sourceforge/filebot/web/AnidbClient.java @@ -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 episodes = cache.getEpisodeList(anime.getAnimeId(), language.getLanguage()); + List 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 getAnimeTitles() throws Exception { URL url = new URL("http", host, "/api/animetitles.dat.gz"); - // try cache first - List anime = cache.getAnimeList(); + @SuppressWarnings("unchecked") + List 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 anime) { - cache.put(new Element(host + "AnimeList", anime.toArray(new AnidbSearchResult[0]))); - } - - - public List getAnimeList() { - Element element = cache.get(host + "AnimeList"); - - if (element != null) - return Arrays.asList((AnidbSearchResult[]) element.getValue()); - - return null; - } - - - public void putEpisodeList(Collection episodes, int aid, String lang) { - cache.put(new Element(host + "EpisodeList" + aid + lang, episodes.toArray(new Episode[0]))); - } - - - public List getEpisodeList(int aid, String lang) { - Element element = cache.get(host + "EpisodeList" + aid + lang); - - if (element != null) - return Arrays.asList((Episode[]) element.getValue()); - - return null; - } - - } - } diff --git a/source/net/sourceforge/filebot/web/IMDbClient.java b/source/net/sourceforge/filebot/web/IMDbClient.java index afbac5ee..6bb8f03e 100644 --- a/source/net/sourceforge/filebot/web/IMDbClient.java +++ b/source/net/sourceforge/filebot/web/IMDbClient.java @@ -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 diff --git a/source/net/sourceforge/filebot/web/SearchResult.java b/source/net/sourceforge/filebot/web/SearchResult.java index b4afd641..e6f44adb 100644 --- a/source/net/sourceforge/filebot/web/SearchResult.java +++ b/source/net/sourceforge/filebot/web/SearchResult.java @@ -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; diff --git a/source/net/sourceforge/filebot/web/SerienjunkiesClient.java b/source/net/sourceforge/filebot/web/SerienjunkiesClient.java index 24279762..129387e6 100644 --- a/source/net/sourceforge/filebot/web/SerienjunkiesClient.java +++ b/source/net/sourceforge/filebot/web/SerienjunkiesClient.java @@ -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 getSeriesTitles() throws IOException { - // try cache first - List seriesList = cache.getSeriesList(); + @SuppressWarnings("unchecked") + List 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 episodes = cache.getEpisodeList(series.getSeriesId()); + List 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 anime) { - cache.put(new Element(host + "SeriesList", anime.toArray(new SerienjunkiesSearchResult[0]))); - } - - - public List getSeriesList() { - Element element = cache.get(host + "SeriesList"); - - if (element != null) - return Arrays.asList((SerienjunkiesSearchResult[]) element.getValue()); - - return null; - } - - - public void putEpisodeList(Collection episodes, int sid) { - cache.put(new Element(host + "EpisodeList" + sid, episodes.toArray(new Episode[0]))); - } - - - public List getEpisodeList(int sid) { - Element element = cache.get(host + "EpisodeList" + sid); - - if (element != null) - return Arrays.asList((Episode[]) element.getValue()); - - return null; - } - - } - } diff --git a/source/net/sourceforge/filebot/web/TVRageClient.java b/source/net/sourceforge/filebot/web/TVRageClient.java index 5621db74..59fa3636 100644 --- a/source/net/sourceforge/filebot/web/TVRageClient.java +++ b/source/net/sourceforge/filebot/web/TVRageClient.java @@ -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 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 nodes = selectNodes("Results/show", dom); - List searchResults = new ArrayList(nodes.size()); for (Node node : nodes) { @@ -64,15 +63,19 @@ public class TVRageClient extends AbstractEpisodeListProvider { @Override public List 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 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 episodes = new ArrayList(25); + episodes = new ArrayList(25); List specials = new ArrayList(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; } diff --git a/source/net/sourceforge/filebot/web/TheTVDBClient.java b/source/net/sourceforge/filebot/web/TheTVDBClient.java index 60efe171..bab435b8 100644 --- a/source/net/sourceforge/filebot/web/TheTVDBClient.java +++ b/source/net/sourceforge/filebot/web/TheTVDBClient.java @@ -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 mirrors = new EnumMap(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 episodes) { - cache.put(new Element(key(host, "EpisodeList", seriesId, language.getLanguage()), episodes)); - } - - - @SuppressWarnings("unchecked") - public List getEpisodeList(int seriesId, Locale language) { - Element element = cache.get(key(host, "EpisodeList", seriesId, language.getLanguage())); - - if (element != null) - return (List) element.getValue(); - - return null; - } - - - private String key(Object... key) { - return Arrays.toString(key); - } - - } - } diff --git a/test/net/sourceforge/filebot/ui/rename/MatchSimilarityMetricTest.java b/test/net/sourceforge/filebot/ui/rename/MatchSimilarityMetricTest.java index 4dea4b5a..b3adbf94 100644 --- a/test/net/sourceforge/filebot/ui/rename/MatchSimilarityMetricTest.java +++ b/test/net/sourceforge/filebot/ui/rename/MatchSimilarityMetricTest.java @@ -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 files = new ArrayList(); + List episodes = new ArrayList(); + + 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> m = new Matcher(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()); + } + } diff --git a/test/net/sourceforge/filebot/web/TVRageClientTest.java b/test/net/sourceforge/filebot/web/TVRageClientTest.java index 8d95f00c..d7c25b99 100644 --- a/test/net/sourceforge/filebot/web/TVRageClientTest.java +++ b/test/net/sourceforge/filebot/web/TVRageClientTest.java @@ -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()); }