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
.ArrayList
;
8 import java
.util
.Collections
;
10 import java
.util
.Map
.Entry
;
11 import java
.util
.Scanner
;
13 import be
.nikiroo
.fanfix
.Instance
;
14 import be
.nikiroo
.utils
.StringUtils
;
16 class MangaFox
extends BasicSupport
{
18 protected boolean isHtml() {
23 public String
getSourceName() {
24 return "MangaFox.met";
28 protected String
getSubject(URL source
, InputStream in
) {
33 public boolean isImageDocument(URL source
, InputStream in
)
39 protected List
<String
> getTags(URL source
, InputStream in
) {
40 List
<String
> tags
= new ArrayList
<String
>();
42 String line
= getLine(in
, "/genres/", 0);
44 line
= StringUtils
.unhtml(line
);
45 String
[] tab
= line
.split(",");
47 for (String tag
: tab
) {
57 protected String
getTitle(URL source
, InputStream in
) {
58 String line
= getLine(in
, " property=\"og:title\"", 0);
61 for (int i
= 0; i
< 3; i
++) {
62 pos
= line
.indexOf('"', pos
+ 1);
66 line
= line
.substring(pos
+ 1);
67 pos
= line
.indexOf('"');
69 return line
.substring(0, pos
);
78 protected String
getAuthor(URL source
, InputStream in
) {
79 List
<String
> authors
= new ArrayList
<String
>();
81 String line
= getLine(in
, "/author/", 0, false);
83 for (String ln
: StringUtils
.unhtml(line
).split(",")) {
84 if (ln
!= null && !ln
.trim().isEmpty()
85 && !authors
.contains(ln
.trim())) {
86 authors
.add(ln
.trim());
93 } catch (IOException e
) {
97 line
= getLine(in
, "/artist/", 0, false);
99 for (String ln
: StringUtils
.unhtml(line
).split(",")) {
100 if (ln
!= null && !ln
.trim().isEmpty()
101 && !authors
.contains(ln
.trim())) {
102 authors
.add(ln
.trim());
107 if (authors
.isEmpty()) {
110 StringBuilder builder
= new StringBuilder();
111 for (String author
: authors
) {
112 if (builder
.length() > 0) {
113 builder
.append(", ");
116 builder
.append(author
);
119 return builder
.toString();
124 protected String
getDate(URL source
, InputStream in
) {
125 String line
= getLine(in
, "/released/", 0);
127 line
= StringUtils
.unhtml(line
);
135 protected String
getDesc(URL source
, InputStream in
) {
136 String line
= getLine(in
, " property=\"og:description\"", 0);
139 for (int i
= 0; i
< 3; i
++) {
140 pos
= line
.indexOf('"', pos
+ 1);
144 line
= line
.substring(pos
+ 1);
145 pos
= line
.indexOf('"');
147 return line
.substring(0, pos
);
156 protected URL
getCover(URL url
, InputStream in
) {
157 String line
= getLine(in
, " property=\"og:image\"", 0);
161 for (int i
= 0; i
< 3; i
++) {
162 pos
= line
.indexOf('"', pos
+ 1);
166 line
= line
.substring(pos
+ 1);
167 pos
= line
.indexOf('"');
169 cover
= line
.substring(0, pos
);
176 return new URL(cover
);
177 } catch (MalformedURLException e
) {
186 protected List
<Entry
<String
, URL
>> getChapters(URL source
, InputStream in
) {
187 List
<Entry
<String
, URL
>> urls
= new ArrayList
<Entry
<String
, URL
>>();
189 String volumeAt
= "<h3 class=\"volume\">";
190 String linkAt
= "href=\"http://mangafox.me/";
191 String endAt
= "<script type=\"text/javascript\">";
193 boolean started
= false;
195 @SuppressWarnings("resource")
196 Scanner scan
= new Scanner(in
, "UTF-8");
197 scan
.useDelimiter("\\n");
198 while (scan
.hasNext()) {
199 String line
= scan
.next();
201 if (started
&& line
.contains(endAt
)) {
203 } else if (!started
&& line
.contains(volumeAt
)) {
207 if (started
&& line
.contains(linkAt
)) {
208 // Chapter content url
210 int pos
= line
.indexOf("href=\"");
212 line
= line
.substring(pos
+ "href=\"".length());
213 pos
= line
.indexOf('\"');
215 url
= line
.substring(0, pos
);
221 if (scan
.hasNext()) {
222 name
= StringUtils
.unhtml(scan
.next()).trim();
223 // Remove the "new" tag if present
224 if (name
.endsWith("new")) {
225 name
= name
.substring(0, name
.length() - 3).trim();
229 // to help with the retry and the originalUrl
233 final String key
= name
;
234 final URL value
= new URL(url
);
235 urls
.add(new Entry
<String
, URL
>() {
236 public URL
setValue(URL value
) {
240 public String
getKey() {
244 public URL
getValue() {
248 } catch (MalformedURLException e
) {
254 // the chapters are in reversed order
255 Collections
.reverse(urls
);
261 protected String
getChapterContent(URL source
, InputStream in
, int number
) {
262 StringBuilder builder
= new StringBuilder();
263 String base
= getCurrentReferer().toString();
264 int pos
= base
.lastIndexOf('/');
265 base
= base
.substring(0, pos
+ 1); // including the '/' at the end
267 boolean close
= false;
269 String linkNextLine
= getLine(in
, "return enlarge()", 0);
272 } catch (IOException e
) {
276 String linkImageLine
= getLine(in
, "return enlarge()", 1);
277 String linkNext
= null;
278 String linkImage
= null;
279 pos
= linkNextLine
.indexOf("href=\"");
281 linkNextLine
= linkNextLine
.substring(pos
+ "href=\"".length());
282 pos
= linkNextLine
.indexOf('\"');
284 linkNext
= linkNextLine
.substring(0, pos
);
287 pos
= linkImageLine
.indexOf("src=\"");
289 linkImageLine
= linkImageLine
290 .substring(pos
+ "src=\"".length());
291 pos
= linkImageLine
.indexOf('\"');
293 linkImage
= linkImageLine
.substring(0, pos
);
297 if (linkImage
!= null) {
299 // to help with the retry and the originalUrl, part 1
300 builder
.append(withoutQuery(linkImage
));
301 builder
.append("]\n");
304 // to help with the retry and the originalUrl, part 2
310 } catch (IOException e
) {
316 if (linkNext
!= null && !"javascript:void(0);".equals(linkNext
)) {
319 url
= new URL(base
+ linkNext
);
320 in
= openEx(base
+ linkNext
);
321 setCurrentReferer(url
);
322 } catch (IOException e
) {
323 Instance
.syserr(new IOException(
324 "Cannot get the next manga page which is: "
332 setCurrentReferer(source
);
333 return builder
.toString();
337 protected boolean supports(URL url
) {
338 return "mangafox.me".equals(url
.getHost())
339 || "www.mangafox.me".equals(url
.getHost());
343 * Refresh the {@link URL} by calling {@link MangaFox#openEx(String)}.
348 * @return TRUE if it was refreshed
350 private boolean refresh(String url
) {
354 } catch (Exception e
) {
360 * Open the URL through the cache, but: retry a second time after 100ms if
361 * it fails, remove the query part of the {@link URL} before saving it to
362 * the cache (so it can be recalled later).
367 * @return the resource
369 * @throws IOException
370 * in case of I/O error
372 private InputStream
openEx(String url
) throws IOException
{
374 return Instance
.getCache().open(new URL(url
), this, true,
376 } catch (Exception e
) {
380 } catch (InterruptedException ee
) {
383 return Instance
.getCache().open(new URL(url
), this, true,
389 * Return the same input {@link URL} but without the query part.
392 * the inpiut {@link URL} as a {@link String}
394 * @return the input {@link URL} without query
396 private URL
withoutQuery(String url
) {
399 // Remove the query from o (originalUrl), so it can be cached
402 o
= new URL(o
.getProtocol() + "://" + o
.getHost() + o
.getPath());
405 } catch (MalformedURLException e
) {