5abc47b090ce563e1801bcd0ebed7c10cc09d47f
1 package be
.nikiroo
.fanfix
.supported
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.net
.MalformedURLException
;
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
;
13 import org
.jsoup
.helper
.DataUtil
;
14 import org
.jsoup
.nodes
.Element
;
15 import org
.jsoup
.select
.Elements
;
17 import be
.nikiroo
.fanfix
.Instance
;
18 import be
.nikiroo
.fanfix
.data
.MetaData
;
19 import be
.nikiroo
.utils
.Image
;
20 import be
.nikiroo
.utils
.Progress
;
21 import be
.nikiroo
.utils
.StringUtils
;
23 class MangaFox
extends BasicSupport
{
25 protected boolean isHtml() {
30 public String
getSourceName() {
35 protected MetaData
getMeta() throws IOException
{
36 MetaData meta
= new MetaData();
37 Element doc
= getSourceNode();
39 Element title
= doc
.getElementById("title");
40 Elements table
= null;
42 table
= title
.getElementsByTag("table");
46 Elements rows
= table
.first().getElementsByTag("tr");
47 if (rows
.size() > 1) {
48 table
= rows
.get(1).getElementsByTag("td");
49 // Columns: Realeased, Authors, Artists, Genres
50 if (table
.size() < 4) {
56 meta
.setTitle(getTitle());
58 meta
.setAuthor(getAuthors(table
.get(1).text() + ","
59 + table
.get(2).text()));
61 meta
.setDate(StringUtils
.unhtml(table
.get(0).text()).trim());
62 meta
.setTags(explode(table
.get(3).text()));
64 meta
.setSource(getSourceName());
65 meta
.setUrl(getSource().toString());
66 meta
.setPublisher(getSourceName());
67 meta
.setUuid(getSource().toString());
70 meta
.setSubject("manga");
71 meta
.setType(getType().toString());
72 meta
.setImageDocument(true);
73 meta
.setCover(getCover());
78 private String
getTitle() {
79 Element doc
= getSourceNode();
81 Element title
= doc
.getElementById("title");
82 Element h1
= title
.getElementsByTag("h1").first();
84 return StringUtils
.unhtml(h1
.text()).trim();
90 private String
getAuthors(String authorList
) {
92 for (String auth
: explode(authorList
)) {
93 if (!author
.isEmpty()) {
94 author
= author
+ ", ";
103 protected String
getDesc() {
104 Element doc
= getSourceNode();
105 Element title
= doc
.getElementsByClass("summary").first();
107 StringUtils
.unhtml(title
.text()).trim();
113 private Image
getCover() {
114 Element doc
= getSourceNode();
115 Element cover
= doc
.getElementsByClass("cover").first();
117 cover
= cover
.getElementsByTag("img").first();
121 String coverUrl
= cover
.absUrl("src");
125 coverIn
= openEx(coverUrl
);
127 return new Image(coverIn
);
131 } catch (IOException e
) {
132 Instance
.getTraceHandler().error(e
);
140 protected List
<Entry
<String
, URL
>> getChapters(Progress pg
) {
141 List
<Entry
<String
, URL
>> urls
= new ArrayList
<Entry
<String
, URL
>>();
143 Element doc
= getSourceNode();
144 for (Element li
: doc
.getElementsByTag("li")) {
145 Element el
= li
.getElementsByTag("h4").first();
147 el
= li
.getElementsByTag("h3").first();
150 Element a
= el
.getElementsByTag("a").first();
152 String title
= StringUtils
.unhtml(el
.text()).trim();
154 String url
= a
.absUrl("href");
155 if (url
.endsWith("1.html")) {
156 url
= url
.substring(0,
157 url
.length() - "1.html".length());
159 if (!url
.endsWith("/")) {
163 urls
.add(new AbstractMap
.SimpleEntry
<String
, URL
>(
164 title
, new URL(url
)));
165 } catch (Exception e
) {
166 Instance
.getTraceHandler().error(e
);
172 // the chapters are in reversed order
173 Collections
.reverse(urls
);
179 protected String
getChapterContent(URL chapUrl
, int number
, Progress pg
)
185 StringBuilder builder
= new StringBuilder();
187 String url
= chapUrl
.toString();
188 InputStream imageIn
= null;
189 Element imageDoc
= null;
191 // 1. find out how many images there are
194 // note: when used, the base URL can be an ad-page
195 imageIn
= openEx(url
+ "1.html");
196 imageDoc
= DataUtil
.load(imageIn
, "UTF-8", url
+ "1.html");
200 Element select
= imageDoc
.getElementsByClass("m").first();
201 Elements options
= select
.getElementsByTag("option");
202 size
= options
.size() - 1; // last is "Comments"
204 pg
.setMinMax(0, size
);
207 for (int i
= 1; i
<= size
; i
++) {
208 if (i
> 1) { // because fist one was opened for size
210 imageIn
= openEx(url
+ i
+ ".html");
211 imageDoc
= DataUtil
.load(imageIn
, "UTF-8", url
+ i
218 String linkImage
= imageDoc
.getElementById("image").absUrl("src");
219 if (linkImage
!= null) {
221 // to help with the retry and the originalUrl, part 1
222 builder
.append(withoutQuery(linkImage
));
223 builder
.append("]<br/>");
226 // to help with the retry and the originalUrl, part 2
230 return builder
.toString();
234 * Refresh the {@link URL} by calling {@link MangaFoxNew#openEx(String)}.
239 * @return TRUE if it was refreshed
241 private boolean refresh(String url
) {
245 } catch (Exception e
) {
251 * Open the URL through the cache, but: retry a second time after 100ms if
252 * it fails, remove the query part of the {@link URL} before saving it to
253 * the cache (so it can be recalled later).
258 * @return the resource
260 * @throws IOException
261 * in case of I/O error
263 private InputStream
openEx(String url
) throws IOException
{
265 return Instance
.getCache().open(new URL(url
), this, true,
267 } catch (Exception e
) {
271 } catch (InterruptedException ee
) {
274 return Instance
.getCache().open(new URL(url
), this, true,
280 * Return the same input {@link URL} but without the query part.
283 * the inpiut {@link URL} as a {@link String}
285 * @return the input {@link URL} without query
287 private URL
withoutQuery(String url
) {
290 // Remove the query from o (originalUrl), so it can be cached
293 o
= new URL(o
.getProtocol() + "://" + o
.getHost() + o
.getPath());
296 } catch (MalformedURLException e
) {
302 * Explode an HTML comma-separated list of values into a non-duplicate text
306 * the comma-separated values in HTML format
308 * @return the full list with no duplicate in text format
310 private List
<String
> explode(String values
) {
311 List
<String
> list
= new ArrayList
<String
>();
312 if (values
!= null && !values
.isEmpty()) {
313 for (String auth
: values
.split(",")) {
314 String a
= StringUtils
.unhtml(auth
).trim();
315 if (!a
.isEmpty() && !list
.contains(a
.trim())) {
325 protected boolean supports(URL url
) {
326 return "mangafox.me".equals(url
.getHost())
327 || "www.mangafox.me".equals(url
.getHost())
328 || "fanfox.net".equals(url
.getHost())
329 || "www.fanfox.net".equals(url
.getHost());