Library scanning much quicker
[fanfix.git] / src / be / nikiroo / fanfix / supported / E621.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix.supported;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.net.URL;
6import java.util.ArrayList;
7import java.util.List;
8import java.util.Map.Entry;
9import java.util.Scanner;
10
11import be.nikiroo.fanfix.Instance;
12import be.nikiroo.fanfix.data.Chapter;
68686a37 13import be.nikiroo.fanfix.data.MetaData;
08fe2e33
NR
14import be.nikiroo.fanfix.data.Story;
15import be.nikiroo.utils.StringUtils;
16
17/**
18 * Support class for <a href="http://e621.net/">e621.net</a> and <a
19 * href="http://e926.net/">e926.net</a>, a Furry website supporting comics,
20 * including some of MLP.
21 * <p>
22 * <a href="http://e926.net/">e926.net</a> only shows the "clean" images and
23 * comics, but it can be difficult to browse.
24 *
25 * @author niki
26 */
27class E621 extends BasicSupport {
28 @Override
29 public String getSourceName() {
30 return "e621.net";
31 }
32
33 @Override
68686a37
NR
34 protected MetaData getMeta(URL source, InputStream in) throws IOException {
35 MetaData meta = new MetaData();
36
37 meta.setTitle(getTitle(reset(in)));
38 meta.setAuthor(getAuthor(source, reset(in)));
39 meta.setDate("");
40 meta.setTags(new ArrayList<String>()); // TODDO ???
41 meta.setSource(getSourceName());
42 meta.setPublisher(getSourceName());
43 meta.setUuid(source.toString());
44 meta.setLuid("");
45 meta.setLang("EN");
46 meta.setSubject("");
47 meta.setType(getType().toString());
48 meta.setImageDocument(true);
49 meta.setCover(null);
50
51 return meta;
08fe2e33
NR
52 }
53
54 @Override
55 public Story process(URL url) throws IOException {
56 // There is no chapters on e621, just pagination...
57 Story story = super.process(url);
58
59 Chapter only = new Chapter(1, null);
60 for (Chapter chap : story) {
61 only.getParagraphs().addAll(chap.getParagraphs());
62 }
63
64 story.getChapters().clear();
65 story.getChapters().add(only);
66
67 return story;
68 }
69
70 @Override
71 protected boolean supports(URL url) {
72 String host = url.getHost();
73 if (host.startsWith("www.")) {
74 host = host.substring("www.".length());
75 }
76
77 return ("e621.net".equals(host) || "e926.net".equals(host))
78 && url.getPath().startsWith("/pool/");
79 }
80
81 @Override
82 protected boolean isHtml() {
83 return true;
84 }
85
68686a37 86 private String getAuthor(URL source, InputStream in) throws IOException {
08fe2e33
NR
87 String author = getLine(in, "href=\"/post/show/", 0);
88 if (author != null) {
89 String key = "href=\"";
90 int pos = author.indexOf(key);
91 if (pos >= 0) {
92 author = author.substring(pos + key.length());
93 pos = author.indexOf("\"");
94 if (pos >= 0) {
95 author = author.substring(0, pos - 1);
96 String page = source.getProtocol() + "://"
97 + source.getHost() + author;
98 InputStream pageIn = Instance.getCache().open(
99 new URL(page), this, false);
100 try {
101 key = "class=\"tag-type-artist\"";
102 author = getLine(pageIn, key, 0);
103 if (author != null) {
104 pos = author.indexOf("<a href=\"");
105 if (pos >= 0) {
106 author = author.substring(pos);
107 pos = author.indexOf("</a>");
108 if (pos >= 0) {
109 author = author.substring(0, pos);
110 return StringUtils.unhtml(author);
111 }
112 }
113 }
114 } finally {
115 pageIn.close();
116 }
117 }
118 }
119 }
120
121 return null;
122 }
123
68686a37 124 private String getTitle(InputStream in) throws IOException {
08fe2e33
NR
125 String title = getLine(in, "<title>", 0);
126 if (title != null) {
127 int pos = title.indexOf('>');
128 if (pos >= 0) {
129 title = title.substring(pos + 1);
130 pos = title.indexOf('<');
131 if (pos >= 0) {
132 title = title.substring(0, pos);
133 }
134 }
135
136 if (title.startsWith("Pool:")) {
137 title = title.substring("Pool:".length());
138 }
139
68686a37 140 title = StringUtils.unhtml(title).trim();
08fe2e33
NR
141 }
142
143 return title;
144 }
145
146 @Override
147 protected String getDesc(URL source, InputStream in) throws IOException {
148 String desc = getLine(in, "margin-bottom: 2em;", 0);
149
150 if (desc != null) {
151 StringBuilder builder = new StringBuilder();
152
153 boolean inTags = false;
154 for (char car : desc.toCharArray()) {
155 if ((inTags && car == '>') || (!inTags && car == '<')) {
156 inTags = !inTags;
157 }
158
159 if (inTags) {
160 builder.append(car);
161 }
162 }
163
164 return builder.toString().trim();
165 }
166
167 return null;
168 }
169
170 @Override
171 protected List<Entry<String, URL>> getChapters(URL source, InputStream in)
172 throws IOException {
173 List<Entry<String, URL>> urls = new ArrayList<Entry<String, URL>>();
174 int last = 1; // no pool/show when only one page
175
176 @SuppressWarnings("resource")
177 Scanner scan = new Scanner(in, "UTF-8");
178 scan.useDelimiter("\\n");
179 while (scan.hasNext()) {
180 String line = scan.next();
181 for (int pos = line.indexOf(source.getPath()); pos >= 0; pos = line
182 .indexOf(source.getPath(), pos + source.getPath().length())) {
183 int equalPos = line.indexOf("=", pos);
184 int quotePos = line.indexOf("\"", pos);
185 if (equalPos >= 0 && quotePos > equalPos) {
186 String snum = line.substring(equalPos + 1, quotePos);
187 try {
188 int num = Integer.parseInt(snum);
189 if (num > last) {
190 last = num;
191 }
192 } catch (NumberFormatException e) {
193 }
194 }
195 }
196 }
197
198 for (int i = 1; i <= last; i++) {
199 final String key = Integer.toString(i);
200 final URL value = new URL(source.toString() + "?page=" + i);
201 urls.add(new Entry<String, URL>() {
202 public URL setValue(URL value) {
203 return null;
204 }
205
206 public URL getValue() {
207 return value;
208 }
209
210 public String getKey() {
211 return key;
212 }
213 });
214 }
215
216 return urls;
217 }
218
219 @Override
220 protected String getChapterContent(URL source, InputStream in, int number)
221 throws IOException {
222 StringBuilder builder = new StringBuilder();
223 String staticSite = "https://static1.e621.net";
224 if (source.getHost().contains("e926")) {
225 staticSite = staticSite.replace("e621", "e926");
226 }
227
228 String key = staticSite + "/data/preview/";
229
230 @SuppressWarnings("resource")
231 Scanner scan = new Scanner(in, "UTF-8");
232 scan.useDelimiter("\\n");
233 while (scan.hasNext()) {
234 String line = scan.next();
235 if (line.contains("class=\"preview\"")) {
236 for (int pos = line.indexOf(key); pos >= 0; pos = line.indexOf(
237 key, pos + key.length())) {
238 int endPos = line.indexOf("\"", pos);
239 if (endPos >= 0) {
240 String id = line.substring(pos + key.length(), endPos);
241 id = staticSite + "/data/" + id;
242
243 int dotPos = id.lastIndexOf(".");
244 if (dotPos >= 0) {
245 id = id.substring(0, dotPos);
246 builder.append("[");
247 builder.append(id);
248 builder.append("]\n");
249 }
250 }
251 }
252 }
253 }
254
255 return builder.toString();
256 }
257}