add mangahub, remove mangfox
[nikiroo-utils.git] / src / be / nikiroo / fanfix / supported / MangaHub.java
1 package be.nikiroo.fanfix.supported;
2
3 import java.io.IOException;
4 import java.net.HttpURLConnection;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.AbstractMap;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.List;
11 import java.util.Map.Entry;
12
13 import org.jsoup.nodes.Element;
14
15 import be.nikiroo.fanfix.Instance;
16 import be.nikiroo.fanfix.data.MetaData;
17 import be.nikiroo.utils.Image;
18 import be.nikiroo.utils.Progress;
19 import be.nikiroo.utils.StringUtils;
20
21 /**
22 * Support class for <a href="https://mangahub.io/">MangaHub</a>, a website
23 * dedicated to Manga.
24 *
25 * @author niki
26 */
27 class MangaHub extends BasicSupport {
28 @Override
29 protected boolean isHtml() {
30 return true;
31 }
32
33 @Override
34 protected MetaData getMeta() throws IOException {
35 MetaData meta = new MetaData();
36
37 meta.setTitle(getTitle());
38 meta.setDate("");
39 meta.setAuthor(getAuthor());
40 meta.setTags(getTags());
41 meta.setSource(getType().getSourceName());
42 meta.setUrl(getSource().toString());
43 meta.setPublisher(getType().getSourceName());
44 meta.setUuid(getSource().toString());
45 meta.setLuid("");
46 meta.setLang("en");
47 meta.setSubject("manga");
48 meta.setType(getType().toString());
49 meta.setImageDocument(true);
50 meta.setCover(getCover());
51
52 return meta;
53 }
54
55 private String getTitle() {
56 Element doc = getSourceNode();
57
58 Element el = doc.getElementsByTag("h1").first();
59 if (el != null) {
60 return StringUtils.unhtml(el.text()).trim();
61 }
62
63 return null;
64 }
65
66 private String getAuthor() {
67 String author = "";
68
69 Element el = getSourceNode().select("h1+div span:not([class])").first();
70 if (el != null)
71 author = StringUtils.unhtml(el.text()).trim();
72 return author;
73 }
74
75 private List<String> getTags() {
76 return getListA("genre-label");
77 }
78
79 private List<String> getListA(String uniqueClass) {
80 List<String> list = new ArrayList<String>();
81
82 Element doc = getSourceNode();
83 Element el = doc.getElementsByClass(uniqueClass).first();
84 if (el != null) {
85 for (Element valueA : el.getElementsByTag("a")) {
86 list.add(StringUtils.unhtml(valueA.text()).trim());
87 }
88 }
89
90 return list;
91 }
92
93 @Override
94 protected String getDesc() {
95 Element doc = getSourceNode();
96 Element title = doc.getElementsByClass("fullcontent").first();
97 if (title != null) {
98 return StringUtils.unhtml(title.text()).trim();
99 }
100
101 return null;
102 }
103
104 private Image getCover() {
105 Element doc = getSourceNode();
106 Element cover = doc.getElementsByClass("manga-thumb").first();
107 if (cover != null) {
108 try {
109 return bsImages.getImage(this, new URL(cover.absUrl("src")));
110 } catch (MalformedURLException e) {
111 Instance.getTraceHandler().error(e);
112 }
113 }
114
115 return null;
116 }
117
118 @Override
119 protected List<Entry<String, URL>> getChapters(Progress pg) {
120 List<Entry<String, URL>> urls = new ArrayList<Entry<String, URL>>();
121
122 Element doc = getSourceNode();
123 for (Element el : doc.getElementsByClass("list-group-item")) {
124 Element urlEl = el.getElementsByTag("a").first();
125 if (urlEl == null)
126 continue;
127
128 String url = urlEl.absUrl("href");
129
130 String title = "";
131 el = el.getElementsByClass("text-secondary").first();
132 if (el != null) {
133 title = StringUtils.unhtml(el.text()).trim();
134 }
135
136 try {
137 urls.add(new AbstractMap.SimpleEntry<String, URL>(title, new URL(url)));
138 } catch (Exception e) {
139 Instance.getTraceHandler().error(e);
140 }
141 }
142
143 // by default, the chapters are in reversed order
144 Collections.reverse(urls);
145
146 return urls;
147 }
148
149 @Override
150 protected String getChapterContent(URL chapUrl, int number, Progress pg) throws IOException {
151 if (pg == null) {
152 pg = new Progress();
153 }
154
155 // 1. Get the title and chapter url part
156 String path = chapUrl.getPath();
157 if (path.endsWith("/")) {
158 path = path.substring(0, path.length() - "/".length());
159 }
160 String tab[] = path.split("/");
161 String chap = tab[tab.length - 1];
162 String title = tab[tab.length - 2];
163
164 if (chap.startsWith("chapter-")) {
165 chap = chap.substring("chapter-".length());
166 }
167
168 // 2. generate an image base
169 String base = "https://img.mghubcdn.com/file/imghub/" + title + "/" + chap + "/";
170
171 // 3. add each chapter
172 StringBuilder builder = new StringBuilder();
173
174 int i = 1;
175 String url = base + i + ".jpg";
176 while (getHttpStatus(new URL(url)) != 404) {
177 builder.append("[");
178 builder.append(url);
179 builder.append("]<br/>");
180
181 i++;
182 url = base + i + ".jpg";
183 }
184
185 return builder.toString();
186 }
187
188 // HTTP response code, or -1 if other error
189 private int getHttpStatus(URL url) {
190 try {
191 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
192 try {
193 connection.setRequestMethod("HEAD");
194 return connection.getResponseCode();
195 } finally {
196 connection.disconnect();
197 }
198 } catch (Exception e) {
199 return -1;
200 }
201 }
202
203 @Override
204 protected boolean supports(URL url) {
205 return "mangahub.io".equals(url.getHost()) || "www.mangahub.io".equals(url.getHost());
206 }
207 }