From af1f506fb4bb7265645e34cd03c6c7178d6a4da7 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Fri, 10 Aug 2018 23:21:49 +0200 Subject: [PATCH] New: MangaLel support (manga, FR) --- changelog-fr.md | 1 + changelog.md | 1 + .../fanfix/bundles/resources.properties | 5 +- .../fanfix/bundles/resources_fr.properties | 5 +- .../fanfix/supported/BasicSupport.java | 3 + src/be/nikiroo/fanfix/supported/MangaFox.java | 2 +- src/be/nikiroo/fanfix/supported/MangaLel.java | 240 ++++++++++++++++++ .../nikiroo/fanfix/supported/SupportType.java | 2 + 8 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 src/be/nikiroo/fanfix/supported/MangaLel.java diff --git a/changelog-fr.md b/changelog-fr.md index f7c6b45..dc110b5 100644 --- a/changelog-fr.md +++ b/changelog-fr.md @@ -5,6 +5,7 @@ - FimfictionAPI: les noms des chapitres sont maintenant triés correctement - e621: supporte aussi les recherches (/post/) - remote: la cover est maintenant envoyée au client pour les imports +- MangaLel: support pour MangaLel # Version 1.7.1 diff --git a/changelog.md b/changelog.md index 94290dd..ed9f4ec 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ - FimfictionAPI: chapter names are now correctly ordered - e621: now supports searches (/post/) - remote: cover is now sent over the network for imported stories +- MangaLel: new support for MangaLel # Version 1.7.1 diff --git a/src/be/nikiroo/fanfix/bundles/resources.properties b/src/be/nikiroo/fanfix/bundles/resources.properties index 94148c6..d2e2c63 100644 --- a/src/be/nikiroo/fanfix/bundles/resources.properties +++ b/src/be/nikiroo/fanfix/bundles/resources.properties @@ -116,7 +116,10 @@ INPUT_DESC_MANGAFOX = A well filled repository of mangas, or, as their website s INPUT_DESC_E621 = Furry website supporting comics, including MLP # Description of this input type # (FORMAT: STRING) -INPUT_DESC_E_HENTAI = Website offering many comics/manga, mostly but not always NSFW +INPUT_DESC_E_HENTAI = Website offering many comics/mangas, mostly but not always NSFW +# Description of this input type +# (FORMAT: STRING) +INPUT_DESC_MANGA_LEL = Website offering many mangas, in French # Description of this input type # (FORMAT: STRING) INPUT_DESC_YIFFSTAR = A Furry website, story-oriented diff --git a/src/be/nikiroo/fanfix/bundles/resources_fr.properties b/src/be/nikiroo/fanfix/bundles/resources_fr.properties index 3e84578..fabb029 100644 --- a/src/be/nikiroo/fanfix/bundles/resources_fr.properties +++ b/src/be/nikiroo/fanfix/bundles/resources_fr.properties @@ -103,7 +103,10 @@ INPUT_DESC_MANGAFOX = Un site répertoriant une quantité non négligeable de ma INPUT_DESC_E621 = Un site Furry proposant des comics, y compris de MLP # Description of this input type # (FORMAT: STRING) -INPUT_DESC_E_HENTAI = Un site web proposant beaucoup de comics/manga, souvent mais pas toujours NSFW +INPUT_DESC_E_HENTAI = Un site web proposant beaucoup de comics/mangas, souvent mais pas toujours NSFW +# Description of this input type +# (FORMAT: STRING) +INPUT_DESC_MANGA_LEL = Un site web proposant beaucoup de mangas, en Français # Description of this input type # (FORMAT: STRING) INPUT_DESC_YIFFSTAR = Un site web Furry, orienté sur les histoires plutôt que les images diff --git a/src/be/nikiroo/fanfix/supported/BasicSupport.java b/src/be/nikiroo/fanfix/supported/BasicSupport.java index 8154a15..527f4de 100644 --- a/src/be/nikiroo/fanfix/supported/BasicSupport.java +++ b/src/be/nikiroo/fanfix/supported/BasicSupport.java @@ -514,6 +514,9 @@ public abstract class BasicSupport { case E_HENTAI: support = new EHentai(); break; + case MANGA_LEL: + support = new MangaLel(); + break; case CBZ: support = new Cbz(); break; diff --git a/src/be/nikiroo/fanfix/supported/MangaFox.java b/src/be/nikiroo/fanfix/supported/MangaFox.java index c418d38..bd5816a 100644 --- a/src/be/nikiroo/fanfix/supported/MangaFox.java +++ b/src/be/nikiroo/fanfix/supported/MangaFox.java @@ -106,7 +106,7 @@ class MangaFox extends BasicSupport { Element doc = getSourceNode(); Element title = doc.getElementsByClass("summary").first(); if (title != null) { - StringUtils.unhtml(title.text()).trim(); + return StringUtils.unhtml(title.text()).trim(); } return null; diff --git a/src/be/nikiroo/fanfix/supported/MangaLel.java b/src/be/nikiroo/fanfix/supported/MangaLel.java new file mode 100644 index 0000000..43d0b2c --- /dev/null +++ b/src/be/nikiroo/fanfix/supported/MangaLel.java @@ -0,0 +1,240 @@ +package be.nikiroo.fanfix.supported; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map.Entry; + +import org.jsoup.helper.DataUtil; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.utils.Image; +import be.nikiroo.utils.Progress; +import be.nikiroo.utils.StringUtils; + +class MangaLel extends BasicSupport { + @Override + protected boolean isHtml() { + return true; + } + + @Override + public String getSourceName() { + return "MangaLel.com"; + } + + @Override + protected MetaData getMeta() throws IOException { + MetaData meta = new MetaData(); + + String[] authorDateTag = getAuthorDateTag(); + + meta.setTitle(getTitle()); + meta.setAuthor(authorDateTag[0]); + meta.setDate(authorDateTag[1]); + meta.setTags(explode(authorDateTag[2])); + meta.setSource(getSourceName()); + meta.setUrl(getSource().toString()); + meta.setPublisher(getSourceName()); + meta.setUuid(getSource().toString()); + meta.setLuid(""); + meta.setLang("fr"); + meta.setSubject("manga"); + meta.setType(getType().toString()); + meta.setImageDocument(true); + meta.setCover(getCover()); + + return meta; + } + + private String getTitle() { + Element doc = getSourceNode(); + Element h2 = doc.getElementsByClass("widget-title").first(); + if (h2 != null) { + return StringUtils.unhtml(h2.text()).trim(); + } + + return null; + } + + // 0 = author + // 1 = date + // 2 = tags + private String[] getAuthorDateTag() { + String[] tab = new String[3]; + + Element doc = getSourceNode(); + Element tabEls = doc.getElementsByClass("dl-horizontal").first(); + int prevOk = 0; + for (Element tabEl : tabEls.children()) { + String txt = tabEl.text().trim(); + if (prevOk > 0) { + if (tab[prevOk - 1] == null) { + tab[prevOk - 1] = ""; + } else { + tab[prevOk - 1] += ", "; + } + + tab[prevOk - 1] += txt; + prevOk = 0; + } else { + if (txt.equals("Auteur(s)") || txt.equals("Artist(s)")) { + prevOk = 1; + } else if (txt.equals("Date de sortie")) { + prevOk = 2; + } else if (txt.equals("Type") || txt.equals("Catégories")) { + prevOk = 3; + } else { + prevOk = 0; + } + } + } + + for (int i = 0; i < 3; i++) { + String list = ""; + for (String item : explode(tab[i])) { + if (!list.isEmpty()) { + list = list + ", "; + } + list += item; + } + tab[i] = list; + } + + return tab; + } + + @Override + protected String getDesc() { + String desc = null; + + Element doc = getSourceNode(); + Element title = doc.getElementsByClass("well").first(); + if (title != null) { + desc = StringUtils.unhtml(title.text()).trim(); + if (desc.startsWith("Résumé")) { + desc = desc.substring("Résumé".length()).trim(); + } + } + + return desc; + } + + private Image getCover() { + Element doc = getSourceNode(); + Element cover = doc.getElementsByClass("img-responsive").first(); + + if (cover != null) { + String coverUrl = cover.absUrl("src"); + + InputStream coverIn; + try { + coverIn = Instance.getCache().open(new URL(coverUrl), this, + true); + try { + return new Image(coverIn); + } finally { + coverIn.close(); + } + } catch (IOException e) { + Instance.getTraceHandler().error(e); + } + } + + return null; + } + + @Override + protected List> getChapters(Progress pg) { + List> urls = new ArrayList>(); + + int i = 1; + Element doc = getSourceNode(); + Element chapEls = doc.getElementsByClass("chapters").first(); + for (Element chapEl : chapEls.getElementsByTag("li")) { + Element titleEl = chapEl.getElementsByTag("h5").first(); + String title = StringUtils.unhtml(titleEl.text()).trim(); + title = Integer.toString(i++); // because Atril does not support + // strange file names + + Element linkEl = chapEl.getElementsByTag("h5").first() + .getElementsByTag("a").first(); + String link = linkEl.absUrl("href"); + + try { + urls.add(new AbstractMap.SimpleEntry(title, + new URL(link))); + } catch (MalformedURLException e) { + Instance.getTraceHandler().error(e); + } + } + + Collections.reverse(urls); + return urls; + } + + @Override + protected String getChapterContent(URL chapUrl, int number, Progress pg) + throws IOException { + if (pg == null) { + pg = new Progress(); + } + + StringBuilder builder = new StringBuilder(); + + InputStream in = Instance.getCache().open(chapUrl, this, false); + try { + Element pageDoc = DataUtil.load(in, "UTF-8", chapUrl.toString()); + Elements linkEls = pageDoc.getElementsByClass("img-responsive"); + for (Element linkEl : linkEls) { + if (linkEl.hasAttr("data-src")) { + builder.append("["); + builder.append(linkEl.absUrl("data-src").trim()); + builder.append("]
"); + } + } + + } finally { + in.close(); + } + + return builder.toString(); + } + + /** + * Explode an HTML comma-separated list of values into a non-duplicate text + * {@link List} . + * + * @param values + * the comma-separated values in HTML format + * + * @return the full list with no duplicate in text format + */ + private List explode(String values) { + List list = new ArrayList(); + if (values != null && !values.isEmpty()) { + for (String auth : values.split(",")) { + String a = StringUtils.unhtml(auth).trim(); + if (!a.isEmpty() && !list.contains(a.trim())) { + list.add(a); + } + } + } + + return list; + } + + @Override + protected boolean supports(URL url) { + return "manga-lel.com".equals(url.getHost()) + || "www.manga-lel.com".equals(url.getHost()); + } +} diff --git a/src/be/nikiroo/fanfix/supported/SupportType.java b/src/be/nikiroo/fanfix/supported/SupportType.java index 2c92562..7ded392 100644 --- a/src/be/nikiroo/fanfix/supported/SupportType.java +++ b/src/be/nikiroo/fanfix/supported/SupportType.java @@ -27,6 +27,8 @@ public enum SupportType { YIFFSTAR, /** Comics and images groups, mostly but not only NSFW */ E_HENTAI, + /** Website with lots of Mangas, in French */ + MANGA_LEL, /** CBZ files */ CBZ, /** HTML files */ -- 2.27.0