This commit is contained in:
Reinhard Pointner 2016-03-08 13:06:07 +00:00
parent e95078668e
commit 1f53b540dc
4 changed files with 2 additions and 291 deletions

View File

@ -86,7 +86,7 @@ public class CacheManager {
}
if (cacheRevision != applicationRevision && applicationRevision > 0 && !isNewCache) {
debug.config(format("App version (r%d) does not match cache version (r%d): reset cache", applicationRevision, cacheRevision));
debug.config(format("Current application version (r%d) does not match cache version (r%d): reset cache", applicationRevision, cacheRevision));
// tag cache with new revision number
isNewCache = true;

View File

@ -17,8 +17,6 @@ import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.Collator;
import java.text.Normalizer;
import java.text.Normalizer.Form;
@ -43,10 +41,8 @@ import java.util.regex.Pattern;
import net.filebot.Cache;
import net.filebot.CacheType;
import net.filebot.Resource;
import net.filebot.util.ByteBufferInputStream;
import net.filebot.util.FileUtilities.RegexFileFilter;
import net.filebot.web.AnidbSearchResult;
import net.filebot.web.CachedResource;
import net.filebot.web.Movie;
import net.filebot.web.SubtitleSearchResult;
import net.filebot.web.TheTVDBSearchResult;
@ -483,112 +479,7 @@ public class ReleaseInfo {
return System.getProperty(name, getBundle(ReleaseInfo.class.getName()).getString(name));
}
protected static class PatternResource extends CachedResource<String[]> {
public PatternResource(String resource) {
super(resource, String[].class, ONE_WEEK); // check for updates every week
}
@Override
public String[] process(ByteBuffer data) {
return compile("\\n").split(Charset.forName("UTF-8").decode(data));
}
}
protected static class MovieResource extends CachedResource<Movie[]> {
public MovieResource(String resource) {
super(resource, Movie[].class, ONE_MONTH); // check for updates every month
}
@Override
public Movie[] process(ByteBuffer data) throws IOException {
List<String[]> rows = readCSV(new XZInputStream(new ByteBufferInputStream(data)), "UTF-8", "\t");
List<Movie> movies = new ArrayList<Movie>(rows.size());
for (String[] row : rows) {
int imdbid = parseInt(row[0]);
int tmdbid = parseInt(row[1]);
int year = parseInt(row[2]);
String name = row[3];
String[] aliasNames = copyOfRange(row, 4, row.length);
movies.add(new Movie(name, aliasNames, year, imdbid > 0 ? imdbid : -1, tmdbid > 0 ? tmdbid : -1, null));
}
return movies.toArray(new Movie[0]);
}
}
protected static class TheTVDBIndexResource extends CachedResource<TheTVDBSearchResult[]> {
public TheTVDBIndexResource(String resource) {
super(resource, TheTVDBSearchResult[].class, ONE_WEEK); // check for updates every week
}
@Override
public TheTVDBSearchResult[] process(ByteBuffer data) throws IOException {
List<String[]> rows = readCSV(new XZInputStream(new ByteBufferInputStream(data)), "UTF-8", "\t");
List<TheTVDBSearchResult> tvshows = new ArrayList<TheTVDBSearchResult>(rows.size());
for (String[] row : rows) {
int id = parseInt(row[0]);
String name = row[1];
String[] aliasNames = copyOfRange(row, 2, row.length);
tvshows.add(new TheTVDBSearchResult(name, aliasNames, id));
}
return tvshows.toArray(new TheTVDBSearchResult[0]);
}
}
protected static class AnidbIndexResource extends CachedResource<AnidbSearchResult[]> {
public AnidbIndexResource(String resource) {
super(resource, AnidbSearchResult[].class, ONE_WEEK); // check for updates every week
}
@Override
public AnidbSearchResult[] process(ByteBuffer data) throws IOException {
List<String[]> rows = readCSV(new XZInputStream(new ByteBufferInputStream(data)), "UTF-8", "\t");
List<AnidbSearchResult> anime = new ArrayList<AnidbSearchResult>(rows.size());
for (String[] row : rows) {
int aid = parseInt(row[0]);
String primaryTitle = row[1];
String[] aliasNames = copyOfRange(row, 2, row.length);
anime.add(new AnidbSearchResult(aid, primaryTitle, aliasNames));
}
return anime.toArray(new AnidbSearchResult[0]);
}
}
protected static class OpenSubtitlesIndexResource extends CachedResource<SubtitleSearchResult[]> {
public OpenSubtitlesIndexResource(String resource) {
super(resource, SubtitleSearchResult[].class, ONE_MONTH); // check for updates every month
}
@Override
public SubtitleSearchResult[] process(ByteBuffer data) throws IOException {
List<String[]> rows = readCSV(new XZInputStream(new ByteBufferInputStream(data)), "UTF-8", "\t");
List<SubtitleSearchResult> result = new ArrayList<SubtitleSearchResult>(rows.size());
for (String[] row : rows) {
String kind = row[0];
int score = parseInt(row[1]);
int imdbId = parseInt(row[2]);
int year = parseInt(row[3]);
String name = row[4];
String[] aliasNames = copyOfRange(row, 5, row.length);
result.add(new SubtitleSearchResult(name, aliasNames, year, imdbId, -1, Locale.ENGLISH, SubtitleSearchResult.Kind.forName(kind), score));
}
return result.toArray(new SubtitleSearchResult[0]);
}
}
protected static class FolderEntryFilter implements FileFilter {
public static class FolderEntryFilter implements FileFilter {
private final Pattern entryPattern;

View File

@ -1,149 +0,0 @@
package net.filebot.web;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
public abstract class AbstractCachedResource<R, T extends Serializable> {
public static final long ONE_MINUTE = 60 * 1000;
public static final long ONE_HOUR = 60 * ONE_MINUTE;
public static final long ONE_DAY = 24 * ONE_HOUR;
public static final long ONE_WEEK = 7 * ONE_DAY;
public static final long ONE_MONTH = 30 * ONE_DAY;
protected final String resource;
protected final Class<T> type;
protected final long expirationTime;
protected final int retryCountLimit;
protected final long retryWaitTime;
public AbstractCachedResource(String resource, Class<T> type, long expirationTime, int retryCountLimit, long retryWaitTime) {
this.resource = resource;
this.type = type;
this.expirationTime = expirationTime;
this.retryCountLimit = retryCountLimit;
this.retryWaitTime = retryWaitTime;
}
/**
* Convert resource data into usable data
*/
protected abstract R fetchData(URL url, long lastModified) throws IOException;
protected abstract T process(R data) throws Exception;
protected abstract Cache getCache();
public synchronized T get() throws IOException {
String cacheKey = type.getName() + ":" + resource.toString();
Element element = null;
long lastUpdateTime = 0;
try {
element = getCache().get(cacheKey);
// sanity check ehcache diskcache problems
if (element != null && !cacheKey.equals(element.getKey().toString())) {
element = null;
}
if (element != null) {
lastUpdateTime = element.getLatestOfCreationAndUpdateTime();
}
// fetch from cache
if (element != null && System.currentTimeMillis() - lastUpdateTime < expirationTime) {
return type.cast(element.getValue());
}
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.FINEST, e.getMessage());
}
// fetch and process resource
R data = null;
T product = null;
IOException networkException = null;
try {
long lastModified = element != null ? lastUpdateTime : 0;
URL url = getResourceLocation(resource);
// DEBUG
// System.out.println(String.format("CachedResource.resourceLocation => %s (If-Modified-Since: %s)", url, java.time.Instant.ofEpochMilli(lastModified)));
data = fetch(url, lastModified, element != null ? 0 : retryCountLimit);
} catch (IOException e) {
networkException = e;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (data != null) {
try {
product = process(data);
element = new Element(cacheKey, product);
} catch (Exception e) {
throw new IOException(e);
}
} else {
try {
if (element != null) {
product = type.cast(element.getValue());
}
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.FINEST, e.getMessage());
}
}
try {
if (element != null) {
getCache().put(element);
}
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.FINEST, e.getMessage());
}
// throw network error only if we can't use previously cached data
if (networkException != null) {
if (product == null) {
throw networkException;
}
// just log error and continue with cached data
Logger.getLogger(getClass().getName()).log(Level.WARNING, networkException.toString());
}
return product;
}
protected URL getResourceLocation(String resource) throws IOException {
return new URL(resource);
}
protected R fetch(URL url, long lastModified, int retries) throws IOException, InterruptedException {
for (int i = 0; retries < 0 || i <= retries; i++) {
try {
if (i > 0) {
Thread.sleep(retryWaitTime);
}
return fetchData(url, lastModified);
} catch (FileNotFoundException e) {
// if the resource doesn't exist no need for retries
throw e;
} catch (IOException e) {
if (i >= 0 && i >= retries) {
throw e;
}
}
}
return null; // can't happen
}
}

View File

@ -1,31 +0,0 @@
package net.filebot.web;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.nio.ByteBuffer;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
public abstract class CachedResource<T extends Serializable> extends AbstractCachedResource<ByteBuffer, T> {
public CachedResource(String resource, Class<T> type, long expirationTime) {
this(resource, type, expirationTime, 2, 1000); // 3 retries in 1s intervals by default
}
public CachedResource(String resource, Class<T> type, long expirationTime, int retryCountLimit, long retryWaitTime) {
super(resource, type, expirationTime, retryCountLimit, retryWaitTime);
}
@Override
protected Cache getCache() {
return CacheManager.getInstance().getCache("web-persistent-datasource");
}
@Override
protected ByteBuffer fetchData(URL url, long lastModified) throws IOException {
return WebRequest.fetchIfModified(url, lastModified);
}
}