import java.net.URL;
import java.util.Map;
-import javax.imageio.ImageIO;
-
import be.nikiroo.fanfix.bundles.Config;
import be.nikiroo.fanfix.supported.BasicSupport;
import be.nikiroo.utils.Cache;
+import be.nikiroo.utils.CacheMemory;
import be.nikiroo.utils.Downloader;
+import be.nikiroo.utils.Image;
import be.nikiroo.utils.ImageUtils;
+import be.nikiroo.utils.TraceHandler;
/**
* This cache will manage Internet (and local) downloads, as well as put the
* @author niki
*/
public class DataLoader {
- private Cache cache;
private Downloader downloader;
+ private Downloader downloaderNoCache;
+ private Cache cache;
+ private boolean offline;
/**
* Create a new {@link DataLoader} object.
*/
public DataLoader(File dir, String UA, int hoursChanging, int hoursStable)
throws IOException {
- cache = new Cache(dir, hoursChanging, hoursStable);
+ downloader = new Downloader(UA, new Cache(dir, hoursChanging,
+ hoursStable));
+ downloaderNoCache = new Downloader(UA);
+
+ cache = downloader.getCache();
+ }
+
+ /**
+ * Create a new {@link DataLoader} object without disk cache (will keep a
+ * memory cache for manual cache operations).
+ *
+ * @param UA
+ * the User-Agent to use to download the resources
+ */
+ public DataLoader(String UA) {
downloader = new Downloader(UA);
+ downloaderNoCache = downloader;
+ cache = new CacheMemory();
+ }
+
+ /**
+ * This {@link Downloader} is forbidden to try and connect to the network.
+ * <p>
+ * If TRUE, it will only check the cache (even in no-cache mode!).
+ * <p>
+ * Default is FALSE.
+ *
+ * @return TRUE if offline
+ */
+ public boolean isOffline() {
+ return offline;
+ }
+
+ /**
+ * This {@link Downloader} is forbidden to try and connect to the network.
+ * <p>
+ * If TRUE, it will only check the cache (even in no-cache mode!).
+ * <p>
+ * Default is FALSE.
+ *
+ * @param offline TRUE for offline, FALSE for online
+ */
+ public void setOffline(boolean offline) {
+ this.offline = offline;
+ downloader.setOffline(offline);
+ downloaderNoCache.setOffline(offline);
+
+ // If we don't, we cannot support no-cache using code in OFFLINE mode
+ if (offline) {
+ downloaderNoCache.setCache(cache);
+ } else {
+ downloaderNoCache.setCache(null);
+ }
+ }
+
+ /**
+ * The traces handler for this {@link Cache}.
+ *
+ * @param tracer
+ * the new traces handler
+ */
+ public void setTraceHandler(TraceHandler tracer) {
+ downloader.setTraceHandler(tracer);
+ downloaderNoCache.setTraceHandler(tracer);
+ cache.setTraceHandler(tracer);
+ if (downloader.getCache() != null) {
+ downloader.getCache().setTraceHandler(tracer);
+ }
+
}
/**
* Open a resource (will load it from the cache if possible, or save it into
* the cache after downloading if not).
+ * <p>
+ * The cached resource will be assimilated to the given original {@link URL}
*
* @param url
* the resource to open
* @param support
- * the support to use to download the resource
+ * the support to use to download the resource (can be NULL)
* @param stable
* TRUE for more stable resources, FALSE when they often change
*
*/
public InputStream open(URL url, BasicSupport support, boolean stable)
throws IOException {
- // MUST NOT return null
- return open(url, support, stable, url);
+ return open(url, url, support, stable, null, null, null);
}
/**
*
* @param url
* the resource to open
+ * @param originalUrl
+ * the original {@link URL} before any redirection occurs, which
+ * is also used for the cache ID if needed (so we can retrieve
+ * the content with this URL if needed)
* @param support
* the support to use to download the resource
* @param stable
* TRUE for more stable resources, FALSE when they often change
- * @param originalUrl
- * the original {@link URL} used to locate the cached resource
*
* @return the opened resource, NOT NULL
*
* @throws IOException
* in case of I/O error
*/
- public InputStream open(URL url, BasicSupport support, boolean stable,
- URL originalUrl) throws IOException {
- // MUST NOT return null
- try {
- InputStream in = cache.load(originalUrl, false, stable);
- Instance.trace("Cache " + (in != null ? "hit" : "miss") + ": "
- + url);
-
- if (in == null) {
- try {
- in = openNoCache(url, support, null, null, null);
- cache.save(in, originalUrl);
- // ..But we want a resetable stream
- in.close();
- in = cache.load(originalUrl, false, stable);
- } catch (IOException e) {
- throw new IOException("Cannot save the url: "
- + (url == null ? "null" : url.toString()), e);
- }
- }
-
- return in;
- } catch (IOException e) {
- throw new IOException("Cannot open the url: "
- + (url == null ? "null" : url.toString()), e);
- }
+ public InputStream open(URL url, URL originalUrl, BasicSupport support,
+ boolean stable) throws IOException {
+ return open(url, originalUrl, support, stable, null, null, null);
}
/**
- * Open the given {@link URL} without using the cache, but still update the
- * cookies.
+ * Open a resource (will load it from the cache if possible, or save it into
+ * the cache after downloading if not).
+ * <p>
+ * The cached resource will be assimilated to the given original {@link URL}
*
* @param url
- * the {@link URL} to open
+ * the resource to open
+ * @param originalUrl
+ * the original {@link URL} before any redirection occurs, which
+ * is also used for the cache ID if needed (so we can retrieve
+ * the content with this URL if needed)
+ * @param support
+ * the support to use to download the resource (can be NULL)
+ * @param stable
+ * TRUE for more stable resources, FALSE when they often change
+ * @param postParams
+ * the POST parameters
+ * @param getParams
+ * the GET parameters (priority over POST)
+ * @param oauth
+ * OAuth authorization (aka, "bearer XXXXXXX")
*
- * @return the {@link InputStream} of the opened page
+ * @return the opened resource, NOT NULL
*
* @throws IOException
* in case of I/O error
*/
- public InputStream openNoCache(URL url) throws IOException {
- return downloader.open(url);
+ public InputStream open(URL url, URL originalUrl, BasicSupport support,
+ boolean stable, Map<String, String> postParams,
+ Map<String, String> getParams, String oauth) throws IOException {
+
+ Map<String, String> cookiesValues = null;
+ URL currentReferer = url;
+
+ if (support != null) {
+ cookiesValues = support.getCookies();
+ currentReferer = support.getCurrentReferer();
+ // priority: arguments
+ if (oauth == null) {
+ oauth = support.getOAuth();
+ }
+ }
+
+ return downloader.open(url, originalUrl, currentReferer, cookiesValues,
+ postParams, getParams, oauth, stable);
}
/**
}
}
- return downloader.open(url, currentReferer, cookiesValues, postParams,
- getParams, oauth);
+ return downloaderNoCache.open(url, currentReferer, cookiesValues,
+ postParams, getParams, oauth);
}
/**
* @param url
* the resource to open
* @param support
- * the support to use to download the resource
+ * the support to use to download the resource (can be NULL)
* @param stable
* TRUE for more stable resources, FALSE when they often change
*
*/
public void refresh(URL url, BasicSupport support, boolean stable)
throws IOException {
- if (!cache.check(url, false, stable)) {
- open(url, support, stable).close();
+ if (!check(url, stable)) {
+ open(url, url, support, stable, null, null, null).close();
}
}
*
*/
public boolean check(URL url, boolean stable) {
- return cache.check(url, false, stable);
+ return downloader.getCache() != null
+ && downloader.getCache().check(url, false, stable);
}
/**
* Save the given resource as an image on disk using the default image
- * format for content.
+ * format for content or cover -- will automatically add the extension, too.
*
- * @param url
+ * @param img
* the resource
* @param target
- * the target file
+ * the target file without extension
+ * @param cover
+ * use the cover image format instead of the content image format
*
* @throws IOException
* in case of I/O error
*/
- public void saveAsImage(URL url, File target) throws IOException {
- InputStream in = open(url, null, true);
- try {
- ImageIO.write(ImageUtils.fromStream(in), Instance.getConfig()
- .getString(Config.IMAGE_FORMAT_CONTENT).toLowerCase(),
- target);
- } catch (IOException e) {
- throw new IOException("Cannot write image " + url, e);
- } finally {
- in.close();
+ public void saveAsImage(Image img, File target, boolean cover)
+ throws IOException {
+ String format;
+ if (cover) {
+ format = Instance.getConfig().getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER)
+ .toLowerCase();
+ } else {
+ format = Instance.getConfig()
+ .getString(Config.FILE_FORMAT_IMAGE_FORMAT_CONTENT).toLowerCase();
}
+ saveAsImage(img, new File(target.toString() + "." + format), format);
+ }
+
+ /**
+ * Save the given resource as an image on disk using the given image format
+ * for content, or with "png" format if it fails.
+ *
+ * @param img
+ * the resource
+ * @param target
+ * the target file
+ * @param format
+ * the file format ("png", "jpeg", "bmp"...)
+ *
+ * @throws IOException
+ * in case of I/O error
+ */
+ public void saveAsImage(Image img, File target, String format)
+ throws IOException {
+ ImageUtils.getInstance().saveAsImage(img, target, format);
}
/**
* @param uniqueID
* a unique ID for this resource
*
- * @return the resulting {@link File}
*
* @throws IOException
* in case of I/O error
*/
- public File addToCache(InputStream in, String uniqueID) throws IOException {
- return cache.save(in, uniqueID);
+ public void addToCache(InputStream in, String uniqueID) throws IOException {
+ cache.save(in, uniqueID);
}
/**