1 package be
.nikiroo
.fanfix
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
9 import be
.nikiroo
.fanfix
.bundles
.Config
;
10 import be
.nikiroo
.fanfix
.supported
.BasicSupport
;
11 import be
.nikiroo
.utils
.Cache
;
12 import be
.nikiroo
.utils
.CacheMemory
;
13 import be
.nikiroo
.utils
.Downloader
;
14 import be
.nikiroo
.utils
.IOUtils
;
15 import be
.nikiroo
.utils
.Image
;
16 import be
.nikiroo
.utils
.ImageUtils
;
17 import be
.nikiroo
.utils
.TraceHandler
;
20 * This cache will manage Internet (and local) downloads, as well as put the
21 * downloaded files into a cache.
23 * As long the cached resource is not too old, it will use it instead of
24 * retrieving the file again.
28 public class DataLoader
{
29 private Downloader downloader
;
30 private Cache downloadCache
;
34 * Create a new {@link DataLoader} object.
37 * the directory to use as cache
39 * the User-Agent to use to download the resources
40 * @param hoursChanging
41 * the number of hours after which a cached file that is thought
42 * to change ~often is considered too old (or -1 for
45 * the number of hours after which a LARGE cached file that is
46 * thought to change rarely is considered too old (or -1 for
50 * in case of I/O error
52 public DataLoader(File dir
, String UA
, int hoursChanging
, int hoursStable
)
54 downloader
= new Downloader(UA
);
55 downloadCache
= new Cache(dir
, hoursChanging
, hoursStable
);
56 cache
= downloadCache
;
60 * Create a new {@link DataLoader} object without disk cache (will keep a
61 * memory cache for manual cache operations).
64 * the User-Agent to use to download the resources
66 public DataLoader(String UA
) {
67 downloader
= new Downloader(UA
);
69 cache
= new CacheMemory();
73 * The traces handler for this {@link Cache}.
76 * the new traces handler
78 public void setTraceHandler(TraceHandler tracer
) {
79 downloader
.setTraceHandler(tracer
);
80 cache
.setTraceHandler(tracer
);
81 if (downloadCache
!= null) {
82 downloadCache
.setTraceHandler(tracer
);
88 * Open a resource (will load it from the cache if possible, or save it into
89 * the cache after downloading if not).
92 * the resource to open
94 * the support to use to download the resource
96 * TRUE for more stable resources, FALSE when they often change
98 * @return the opened resource, NOT NULL
100 * @throws IOException
101 * in case of I/O error
103 public InputStream
open(URL url
, BasicSupport support
, boolean stable
)
105 // MUST NOT return null
106 return open(url
, support
, stable
, url
);
110 * Open a resource (will load it from the cache if possible, or save it into
111 * the cache after downloading if not).
113 * The cached resource will be assimilated to the given original {@link URL}
116 * the resource to open
118 * the support to use to download the resource
120 * TRUE for more stable resources, FALSE when they often change
122 * the original {@link URL} used to locate the cached resource
124 * @return the opened resource, NOT NULL
126 * @throws IOException
127 * in case of I/O error
129 public InputStream
open(URL url
, BasicSupport support
, boolean stable
,
130 URL originalUrl
) throws IOException
{
131 // MUST NOT return null
133 InputStream in
= null;
135 if (downloadCache
!= null) {
136 in
= downloadCache
.load(originalUrl
, false, stable
);
137 Instance
.getTraceHandler().trace(
138 "Cache " + (in
!= null ?
"hit" : "miss") + ": " + url
);
143 in
= openNoCache(url
, support
, null, null, null);
144 if (downloadCache
!= null) {
145 downloadCache
.save(in
, originalUrl
);
146 // ..But we want a resetable stream
148 in
= downloadCache
.load(originalUrl
, true, stable
);
150 InputStream resetIn
= IOUtils
.forceResetableStream(in
);
156 } catch (IOException e
) {
157 throw new IOException("Cannot save the url: "
158 + (url
== null ?
"null" : url
.toString()), e
);
163 } catch (IOException e
) {
164 throw new IOException("Cannot open the url: "
165 + (url
== null ?
"null" : url
.toString()), e
);
170 * Open the given {@link URL} without using the cache, but still update the
174 * the {@link URL} to open
176 * @return the {@link InputStream} of the opened page
178 * @throws IOException
179 * in case of I/O error
181 public InputStream
openNoCache(URL url
) throws IOException
{
182 return downloader
.open(url
);
186 * Open the given {@link URL} without using the cache, but still using and
187 * updating the cookies.
190 * the {@link URL} to open
192 * the {@link BasicSupport} used for the cookies
194 * the POST parameters
196 * the GET parameters (priority over POST)
198 * OAuth authorization (aka, "bearer XXXXXXX")
200 * @return the {@link InputStream} of the opened page
202 * @throws IOException
203 * in case of I/O error
205 public InputStream
openNoCache(URL url
, BasicSupport support
,
206 Map
<String
, String
> postParams
, Map
<String
, String
> getParams
,
207 String oauth
) throws IOException
{
209 Map
<String
, String
> cookiesValues
= null;
210 URL currentReferer
= url
;
211 if (support
!= null) {
212 cookiesValues
= support
.getCookies();
213 currentReferer
= support
.getCurrentReferer();
214 // priority: arguments
216 oauth
= support
.getOAuth();
220 return downloader
.open(url
, currentReferer
, cookiesValues
, postParams
,
225 * Refresh the resource into cache if needed.
228 * the resource to open
230 * the support to use to download the resource
232 * TRUE for more stable resources, FALSE when they often change
234 * @throws IOException
235 * in case of I/O error
237 public void refresh(URL url
, BasicSupport support
, boolean stable
)
239 if (downloadCache
!= null && !downloadCache
.check(url
, false, stable
)) {
240 open(url
, support
, stable
).close();
245 * Check the resource to see if it is in the cache.
248 * the resource to check
250 * a stable file (that dones't change too often) -- parameter
251 * used to check if the file is too old to keep or not
253 * @return TRUE if it is
256 public boolean check(URL url
, boolean stable
) {
257 return downloadCache
!= null && downloadCache
.check(url
, false, stable
);
261 * Save the given resource as an image on disk using the default image
262 * format for content or cover -- will automatically add the extension, too.
267 * the target file without extension
269 * use the cover image format instead of the content image format
271 * @throws IOException
272 * in case of I/O error
274 public void saveAsImage(Image img
, File target
, boolean cover
)
278 format
= Instance
.getConfig().getString(Config
.IMAGE_FORMAT_COVER
)
281 format
= Instance
.getConfig()
282 .getString(Config
.IMAGE_FORMAT_CONTENT
).toLowerCase();
284 saveAsImage(img
, new File(target
.toString() + "." + format
), format
);
288 * Save the given resource as an image on disk using the given image format
289 * for content, or with "png" format if it fails.
296 * the file format ("png", "jpeg", "bmp"...)
298 * @throws IOException
299 * in case of I/O error
301 public void saveAsImage(Image img
, File target
, String format
)
303 ImageUtils
.getInstance().saveAsImage(img
, target
, format
);
307 * Manually add this item to the cache.
312 * a unique ID for this resource
315 * @throws IOException
316 * in case of I/O error
318 public void addToCache(InputStream in
, String uniqueID
) throws IOException
{
319 cache
.save(in
, uniqueID
);
323 * Return the {@link InputStream} corresponding to the given unique ID, or
324 * NULL if none found.
329 * @return the content or NULL
331 public InputStream
getFromCache(String uniqueID
) {
332 return cache
.load(uniqueID
, true, true);
336 * Remove the given resource from the cache.
339 * a unique ID used to locate the cached resource
341 * @return TRUE if it was removed
343 public boolean removeFromCache(String uniqueID
) {
344 return cache
.remove(uniqueID
);
348 * Clean the cache (delete the cached items).
351 * only clean the files that are considered too old
353 * @return the number of cleaned items
355 public int cleanCache(boolean onlyOld
) {
356 return cache
.clean(onlyOld
);