fix cache, MangaLEL +search
authorNiki Roo <niki@nikiroo.be>
Sun, 14 Apr 2019 11:43:36 +0000 (13:43 +0200)
committerNiki Roo <niki@nikiroo.be>
Sun, 14 Apr 2019 11:43:36 +0000 (13:43 +0200)
changelog-fr.md
changelog.md
src/be/nikiroo/fanfix/DataLoader.java
src/be/nikiroo/fanfix/Instance.java
src/be/nikiroo/fanfix/VersionCheck.java
src/be/nikiroo/fanfix/searchable/Fanfiction.java
src/be/nikiroo/fanfix/searchable/MangaLel.java
src/be/nikiroo/fanfix/supported/MangaFox.java
src/be/nikiroo/fanfix/supported/MangaLel.java
src/be/nikiroo/fanfix/test/BasicSupportTest.java

index 5a635f72bb31b64066b901240e7c217db8e0a125..6fe48c60abd3b5b12dbc92ebd86d8016cdca1f6e 100644 (file)
@@ -8,6 +8,7 @@
 - fix: correction de DEBUG=0
 - gui: correction pour le focus 
 - MangaLEL: site web changĂ©
+- search: supporte MangaLEL
 
 # Version 2.0.2
 
index dc932337e81b9360453a3f6b8aac029ab71bbaa9..24fbceee4e52750989fc17d007d6b40a8f3b416f 100644 (file)
@@ -8,6 +8,7 @@
 - fix: fix DEBUG=0
 - gui: focus fix
 - MangaLEL: website has changed
+- search: MangaLEL support
 
 # Version 2.0.2
 
index e2af0709bb316e06ac78634d6b3aa877082ccc33..51855c418d6ea8b7f5973a3dd1c16b6684515e8f 100644 (file)
@@ -11,7 +11,6 @@ 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.IOUtils;
 import be.nikiroo.utils.Image;
 import be.nikiroo.utils.ImageUtils;
 import be.nikiroo.utils.TraceHandler;
@@ -27,7 +26,7 @@ import be.nikiroo.utils.TraceHandler;
  */
 public class DataLoader {
        private Downloader downloader;
-       private Cache downloadCache;
+       private Downloader downloaderNoCache;
        private Cache cache;
 
        /**
@@ -51,9 +50,11 @@ public class DataLoader {
         */
        public DataLoader(File dir, String UA, int hoursChanging, int hoursStable)
                        throws IOException {
-               downloader = new Downloader(UA);
-               downloadCache = new Cache(dir, hoursChanging, hoursStable);
-               cache = downloadCache;
+               downloader = new Downloader(UA, new Cache(dir, hoursChanging,
+                               hoursStable));
+               downloaderNoCache = new Downloader(UA);
+
+               cache = downloader.getCache();
        }
 
        /**
@@ -65,7 +66,7 @@ public class DataLoader {
         */
        public DataLoader(String UA) {
                downloader = new Downloader(UA);
-               downloadCache = null;
+               downloaderNoCache = downloader;
                cache = new CacheMemory();
        }
 
@@ -77,9 +78,10 @@ public class DataLoader {
         */
        public void setTraceHandler(TraceHandler tracer) {
                downloader.setTraceHandler(tracer);
+               downloaderNoCache.setTraceHandler(tracer);
                cache.setTraceHandler(tracer);
-               if (downloadCache != null) {
-                       downloadCache.setTraceHandler(tracer);
+               if (downloader.getCache() != null) {
+                       downloader.getCache().setTraceHandler(tracer);
                }
 
        }
@@ -87,6 +89,8 @@ public class DataLoader {
        /**
         * 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
@@ -102,8 +106,7 @@ public class DataLoader {
         */
        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);
        }
 
        /**
@@ -114,72 +117,71 @@ public class DataLoader {
         * 
         * @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 = null;
-
-                       if (downloadCache != null) {
-                               in = downloadCache.load(originalUrl, false, stable);
-                               Instance.getTraceHandler().trace(
-                                               "Cache " + (in != null ? "hit" : "miss") + ": " + url);
-                       }
-
-                       if (in == null) {
-                               try {
-                                       in = openNoCache(url, support, null, null, null);
-                                       if (downloadCache != null) {
-                                               downloadCache.save(in, originalUrl);
-                                               // ..But we want a resetable stream
-                                               in.close();
-                                               in = downloadCache.load(originalUrl, true, stable);
-                                       } else {
-                                               InputStream resetIn = IOUtils.forceResetableStream(in);
-                                               if (resetIn != in) {
-                                                       in.close();
-                                                       in = resetIn;
-                                               }
-                                       }
-                               } 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
+        * @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);
        }
 
        /**
@@ -217,8 +219,8 @@ public class DataLoader {
                        }
                }
 
-               return downloader.open(url, currentReferer, cookiesValues, postParams,
-                               getParams, oauth);
+               return downloaderNoCache.open(url, currentReferer, cookiesValues,
+                               postParams, getParams, oauth);
        }
 
        /**
@@ -236,8 +238,8 @@ public class DataLoader {
         */
        public void refresh(URL url, BasicSupport support, boolean stable)
                        throws IOException {
-               if (downloadCache != null && !downloadCache.check(url, false, stable)) {
-                       open(url, support, stable).close();
+               if (check(url, stable)) {
+                       open(url, url, support, stable, null, null, null).close();
                }
        }
 
@@ -254,7 +256,8 @@ public class DataLoader {
         * 
         */
        public boolean check(URL url, boolean stable) {
-               return downloadCache != null && downloadCache.check(url, false, stable);
+               return downloader.getCache() != null
+                               && downloader.getCache().check(url, false, stable);
        }
 
        /**
index c547a2b121bdf07ae3e48ad146ad28ea07ed9c04..24d67afb88cf0c98c551b8f1c6cdd82f3252f6ab 100644 (file)
@@ -17,6 +17,7 @@ import be.nikiroo.fanfix.library.LocalLibrary;
 import be.nikiroo.fanfix.library.RemoteLibrary;
 import be.nikiroo.utils.Cache;
 import be.nikiroo.utils.IOUtils;
+import be.nikiroo.utils.Image;
 import be.nikiroo.utils.Proxy;
 import be.nikiroo.utils.TempFiles;
 import be.nikiroo.utils.TraceHandler;
@@ -71,7 +72,8 @@ public class Instance {
                remoteDir = new File(configDir, "remote");
                lib = createDefaultLibrary(remoteDir);
 
-               // create cache
+               // create cache and TMP
+               Image.setTemporaryFilesRoot(new File(configDir, "tmp.images"));
                File tmp = getFile(Config.CACHE_DIR);
                if (tmp == null) {
                        // Could have used: System.getProperty("java.io.tmpdir")
index 76758af85ca3daaa5ef4f5b8e5fcc799bbee6f2e..2c9a0328aca615aa982f58f68262b636e9758086 100644 (file)
@@ -120,7 +120,8 @@ public class VersionCheck {
                                InputStream in = null;
                                for (String url : new String[] { urlFrBE, urlFr, urlDefault }) {
                                        try {
-                                               in = Instance.getCache().openNoCache(new URL(url));
+                                               in = Instance.getCache()
+                                                               .open(new URL(url), null, false);
                                                break;
                                        } catch (IOException e) {
                                        }
index d0b6f99bd903c071c5e6566140e731c15ca8a687..d25153eb28f6921ea7c4bc64410f384b6e812dd7 100644 (file)
@@ -280,10 +280,11 @@ class Fanfiction extends BasicSearchable {
                                                        in.close();
                                                }
                                        } catch (Exception e) {
-                                               Instance.getTraceHandler()
-                                                               .error(new Exception(
-                                                                               "Cannot download cover for Fanfiction story in search mode",
-                                                                               e));
+                                               // Should not happen on Fanfiction.net
+                                               Instance.getTraceHandler().error(
+                                                               new Exception(
+                                                                               "Cannot download cover for Fanfiction story in search mode: "
+                                                                                               + meta.getTitle(), e));
                                        }
                                }
                        }
index c8a522c896d17849ab1cc223d86c468aa15934fa..879b163888db05fb9ab309a1bd87a0b8ea4c4602 100644 (file)
@@ -86,27 +86,18 @@ class MangaLel extends BasicSearchable {
                for (Element result : doc.getElementsByClass("rechercheAffichage")) {
                        Element a = result.getElementsByTag("a").first();
                        if (a != null) {
+                               int projectId = -1;
+
                                MetaData meta = new MetaData();
-                               meta.setUrl(a.absUrl("href"));
-                               Element img = result.getElementsByTag("img").first();
-                               if (img != null) {
-                                       String coverUrl = img.absUrl("src");
 
-                                       try {
-                                               InputStream in = Instance.getCache().open(
-                                                               new URL(coverUrl), getSupport(), true);
-                                               try {
-                                                       meta.setCover(new Image(in));
-                                               } finally {
-                                                       in.close();
-                                               }
-                                       } catch (Exception e) {
-                                               Instance.getTraceHandler()
-                                                               .error(new Exception(
-                                                                               "Cannot download cover for MangaLEL story in search mode",
-                                                                               e));
-                                       }
-                               }
+                               // Target:
+                               // http://mangas-lecture-en-ligne.fr/index_lel.php?page=presentationProjet&idProjet=218
+
+                               // a.absUrl("href"):
+                               // http://mangas-lecture-en-ligne.fr/index_lel?onCommence=oui&idChapitre=2805
+
+                               // ...but we need the PROJECT id, not the CHAPTER id -> use
+                               // <IMG>
 
                                Elements infos = result.getElementsByClass("texte");
                                if (infos != null) {
@@ -125,7 +116,43 @@ class MangaLel extends BasicSearchable {
                                                                        getVal(tab, 5)));
                                }
 
-                               metas.add(meta);
+                               Element img = result.getElementsByTag("img").first();
+                               if (img != null) {
+                                       try {
+                                               String[] tab = img.attr("src").split("/");
+                                               String str = tab[tab.length - 1];
+                                               tab = str.split("\\.");
+                                               str = tab[0];
+                                               projectId = Integer.parseInt(str);
+
+                                               String coverUrl = img.absUrl("src");
+                                               try {
+                                                       InputStream in = Instance.getCache().open(
+                                                                       new URL(coverUrl), getSupport(), true);
+                                                       try {
+                                                               meta.setCover(new Image(in));
+                                                       } finally {
+                                                               in.close();
+                                                       }
+                                               } catch (Exception e) {
+                                                       // Happen often on MangaLEL...
+                                                       Instance.getTraceHandler().trace(
+                                                                       "Cannot download cover for MangaLEL story in search mode: "
+                                                                                       + meta.getTitle());
+                                               }
+                                       } catch (Exception e) {
+                                               // no project id... cannot use the story :(
+                                               Instance.getTraceHandler().error(
+                                                               "Cannot find ProjectId for MangaLEL story in search mode: "
+                                                                               + meta.getTitle());
+                                       }
+                               }
+
+                               if (projectId >= 0) {
+                                       meta.setUrl("http://mangas-lecture-en-ligne.fr/index_lel.php?page=presentationProjet&idProjet="
+                                                       + projectId);
+                                       metas.add(meta);
+                               }
                        }
                }
 
index 5dee0d6a9f95cd2bf4e420dbf9cec38bca3322fa..dae2d314f900d79a70c5d6237667d007a9a616dd 100644 (file)
@@ -336,8 +336,8 @@ class MangaFox extends BasicSupport {
         */
        private InputStream openEx(String url) throws IOException {
                try {
-                       return Instance.getCache().open(new URL(url), this, true,
-                                       withoutQuery(url));
+                       return Instance.getCache().open(new URL(url), withoutQuery(url),
+                                       this, true);
                } catch (Exception e) {
                        // second chance
                        try {
@@ -345,8 +345,8 @@ class MangaFox extends BasicSupport {
                        } catch (InterruptedException ee) {
                        }
 
-                       return Instance.getCache().open(new URL(url), this, true,
-                                       withoutQuery(url));
+                       return Instance.getCache().open(new URL(url), withoutQuery(url),
+                                       this, true);
                }
        }
 
index 020ee86f1d64c36f9002ff8156cb31194e097bfa..1ba51bc0f5d8a5c32a0341526a5aac142ae3fff6 100644 (file)
@@ -60,30 +60,29 @@ class MangaLel extends BasicSupport {
 
        private String getAuthor() {
                Element doc = getSourceNode();
-               Elements tabEls = doc.getElementsByClass("projet-titre");
-
-               String value = "";
-               if (tabEls.size() >= 2) {
-                       value = StringUtils.unhtml(tabEls.get(1).text()).trim();
+               Element tabEls = doc.getElementsByClass("presentation-projet").first();
+               if (tabEls != null) {
+                       String[] tab = tabEls.outerHtml().split("<br>");
+                       return getVal(tab, 1);
                }
 
-               return value;
+               return "";
        }
 
        private List<String> getTags() {
-               List<String> tags = new ArrayList<String>();
-
                Element doc = getSourceNode();
-               Elements tabEls = doc.getElementsByClass("projet-titre");
-
-               if (tabEls.size() >= 4) {
-                       String values = StringUtils.unhtml(tabEls.get(3).text()).trim();
-                       for (String value : values.split(",")) {
-                               tags.add(value);
+               Element tabEls = doc.getElementsByClass("presentation-projet").first();
+               if (tabEls != null) {
+                       String[] tab = tabEls.outerHtml().split("<br>");
+                       List<String> tags = new ArrayList<String>();
+                       for (String tag : getVal(tab, 3).split(" ")) {
+                               tags.add(tag);
                        }
+                       return tags;
                }
 
-               return tags;
+               return new ArrayList<String>();
+
        }
 
        private String getDate() {
@@ -118,14 +117,13 @@ class MangaLel extends BasicSupport {
        @Override
        protected String getDesc() {
                Element doc = getSourceNode();
-               Elements tabEls = doc.getElementsByClass("projet-titre");
-
-               String value = "";
-               if (tabEls.size() >= 5) {
-                       value = StringUtils.unhtml(tabEls.get(4).text()).trim();
+               Element tabEls = doc.getElementsByClass("presentation-projet").first();
+               if (tabEls != null) {
+                       String[] tab = tabEls.outerHtml().split("<br>");
+                       return getVal(tab, 4);
                }
 
-               return value;
+               return "";
        }
 
        private Image getCover() {
@@ -167,6 +165,20 @@ class MangaLel extends BasicSupport {
                return null;
        }
 
+       private String getVal(String[] tab, int i) {
+               String val = "";
+
+               if (i < tab.length) {
+                       val = StringUtils.unhtml(tab[i]);
+                       int pos = val.indexOf(":");
+                       if (pos >= 0) {
+                               val = val.substring(pos + 1).trim();
+                       }
+               }
+
+               return val;
+       }
+
        @Override
        protected List<Entry<String, URL>> getChapters(Progress pg)
                        throws IOException {
@@ -203,12 +215,12 @@ class MangaLel extends BasicSupport {
                        Element content = pageDoc.getElementById("content");
                        Elements linkEls = content.getElementsByTag("img");
                        for (Element linkEl : linkEls) {
-                               if (linkEl.attr("src").trim().isEmpty()) {
+                               if (linkEl.absUrl("src").isEmpty()) {
                                        continue;
                                }
 
                                builder.append("[");
-                               builder.append(linkEl.absUrl("src").trim());
+                               builder.append(linkEl.absUrl("src"));
                                builder.append("]<br/>");
                        }
 
index a3f5221df5c62db03b1e1e970074e036dbdec59a..b731c441860bb6b8d3baf10da8ca8fdaa783fc11 100644 (file)
@@ -394,11 +394,6 @@ class BasicSupportTest extends TestLauncher {
        }
 
        private class BasicSupportEmpty extends BasicSupport_Deprecated {
-               @Override
-               protected String getSourceName() {
-                       return null;
-               }
-
                @Override
                protected boolean supports(URL url) {
                        return false;