merge from master
[nikiroo-utils.git] / supported / Fimfiction.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix.supported;
2
68686a37 3import java.io.IOException;
08fe2e33
NR
4import java.io.InputStream;
5import java.net.MalformedURLException;
6import java.net.URL;
ce297a79 7import java.util.AbstractMap;
08fe2e33
NR
8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.List;
11import java.util.Map;
12import java.util.Map.Entry;
13import java.util.Scanner;
14
15import be.nikiroo.fanfix.Instance;
68686a37 16import be.nikiroo.fanfix.data.MetaData;
16a81ef7 17import be.nikiroo.utils.Image;
ed08c171 18import be.nikiroo.utils.Progress;
68686a37 19import be.nikiroo.utils.StringUtils;
08fe2e33
NR
20
21/**
22 * Support class for <a href="http://www.fimfiction.net/">FimFiction.net</a>
23 * stories, a website dedicated to My Little Pony.
24 *
25 * @author niki
26 */
0ffa4754 27class Fimfiction extends BasicSupport_Deprecated {
08fe2e33
NR
28 @Override
29 protected boolean isHtml() {
30 return true;
31 }
32
08fe2e33 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(reset(in)));
39 meta.setDate(getDate(reset(in)));
40 meta.setTags(getTags(reset(in)));
727108fe 41 meta.setSource(getType().getSourceName());
2206ef66 42 meta.setUrl(source.toString());
727108fe 43 meta.setPublisher(getType().getSourceName());
68686a37
NR
44 meta.setUuid(source.toString());
45 meta.setLuid("");
276f95c6 46 meta.setLang("en");
68686a37
NR
47 meta.setSubject("MLP");
48 meta.setType(getType().toString());
49 meta.setImageDocument(false);
50 meta.setCover(getCover(reset(in)));
51
52 return meta;
08fe2e33
NR
53 }
54
55 @Override
56 public Map<String, String> getCookies() {
57 Map<String, String> cookies = new HashMap<String, String>();
58 cookies.put("view_mature", "true");
59 return cookies;
60 }
61
68686a37 62 private List<String> getTags(InputStream in) {
08fe2e33
NR
63 List<String> tags = new ArrayList<String>();
64 tags.add("MLP");
65
66 @SuppressWarnings("resource")
67 Scanner scan = new Scanner(in, "UTF-8");
68 scan.useDelimiter("\\n");
c3c79003 69 boolean started = false;
08fe2e33
NR
70 while (scan.hasNext()) {
71 String line = scan.next();
c3c79003
NR
72
73 if (!started) {
74 started = line.contains("\"story_container\"");
75 }
76
77 if (started && line.contains("class=\"tag-")) {
78 if (line.contains("index.php")) {
79 break; // end of *this story* tags
08fe2e33
NR
80 }
81
e1168b3c
NR
82 String keyword = "title=\"";
83 Scanner tagScanner = new Scanner(line);
84 tagScanner.useDelimiter(keyword);
85 if (tagScanner.hasNext()) {
86 tagScanner.next();// Ignore first one
87 }
88 while (tagScanner.hasNext()) {
89 String tag = tagScanner.next();
90 if (tag.contains("\"")) {
91 tag = tag.split("\"")[0];
92 tag = StringUtils.unhtml(tag).trim();
93 if (!tag.isEmpty() && !tags.contains(tag)) {
94 tags.add(tag);
95 }
c3c79003 96 }
08fe2e33 97 }
e1168b3c 98 tagScanner.close();
08fe2e33
NR
99 }
100 }
101
102 return tags;
103 }
104
68686a37 105 private String getTitle(InputStream in) {
08fe2e33
NR
106 String line = getLine(in, " property=\"og:title\"", 0);
107 if (line != null) {
108 int pos = -1;
109 for (int i = 0; i < 3; i++) {
110 pos = line.indexOf('"', pos + 1);
111 }
112
113 if (pos >= 0) {
114 line = line.substring(pos + 1);
115 pos = line.indexOf('"');
116 if (pos >= 0) {
68686a37 117 return StringUtils.unhtml(line.substring(0, pos)).trim();
08fe2e33
NR
118 }
119 }
120 }
121
122 return null;
123 }
124
68686a37 125 private String getAuthor(InputStream in) {
08fe2e33
NR
126 String line = getLine(in, " href=\"/user/", 0);
127 if (line != null) {
128 int pos = line.indexOf('"');
129 if (pos >= 0) {
130 line = line.substring(pos + 1);
131 pos = line.indexOf('"');
132 if (pos >= 0) {
133 line = line.substring(0, pos);
134 pos = line.lastIndexOf('/');
135 if (pos >= 0) {
136 line = line.substring(pos + 1);
137 return line.replace('+', ' ');
138 }
139 }
140 }
141 }
142
143 return null;
144 }
145
68686a37 146 private String getDate(InputStream in) {
08fe2e33
NR
147 String line = getLine(in, "<span class=\"date\">", 0);
148 if (line != null) {
149 int pos = -1;
150 for (int i = 0; i < 3; i++) {
151 pos = line.indexOf('>', pos + 1);
152 }
153
154 if (pos >= 0) {
155 line = line.substring(pos + 1);
156 pos = line.indexOf('<');
157 if (pos >= 0) {
158 return line.substring(0, pos).trim();
159 }
160 }
161 }
162
163 return null;
164 }
165
166 @Override
167 protected String getDesc(URL source, InputStream in) {
168 // the og: meta version is the SHORT resume, this is the LONG resume
83f66cbb 169 return getLine(in, "class=\"description-text bbcode\"", 1);
08fe2e33
NR
170 }
171
16a81ef7 172 private Image getCover(InputStream in) {
08fe2e33 173 // Note: the 'og:image' is the SMALL cover, not the full version
83f66cbb 174 String cover = getLine(in, "class=\"story_container__story_image\"", 1);
08fe2e33
NR
175 if (cover != null) {
176 int pos = cover.indexOf('"');
177 if (pos >= 0) {
178 cover = cover.substring(pos + 1);
179 pos = cover.indexOf('"');
180 if (pos >= 0) {
181 cover = cover.substring(0, pos);
182 }
183 }
184 }
185
333f0e7b 186 return getImage(this, null, cover);
08fe2e33
NR
187 }
188
189 @Override
ed08c171
NR
190 protected List<Entry<String, URL>> getChapters(URL source, InputStream in,
191 Progress pg) {
08fe2e33
NR
192 List<Entry<String, URL>> urls = new ArrayList<Entry<String, URL>>();
193 @SuppressWarnings("resource")
194 Scanner scan = new Scanner(in, "UTF-8");
195 scan.useDelimiter("\\n");
83f66cbb 196 boolean started = false;
08fe2e33 197 while (scan.hasNext()) {
83f66cbb
NR
198 String line = scan.next().trim();
199
200 if (!started) {
201 started = line.equals("<!--Chapters-->");
202 } else {
203 if (line.equals("</form>")) {
204 break;
205 }
206
e1168b3c
NR
207 if (line.startsWith("<a href=")
208 || line.contains("class=\"chapter-title\"")) {
83f66cbb
NR
209 // Chapter name
210 String name = line;
211 int pos = name.indexOf('>');
08fe2e33 212 if (pos >= 0) {
83f66cbb
NR
213 name = name.substring(pos + 1);
214 pos = name.indexOf('<');
215 if (pos >= 0) {
216 name = name.substring(0, pos);
217 }
08fe2e33 218 }
83f66cbb
NR
219 // Chapter content
220 pos = line.indexOf('/');
08fe2e33 221 if (pos >= 0) {
83f66cbb
NR
222 line = line.substring(pos); // we take the /, not +1
223 pos = line.indexOf('"');
224 if (pos >= 0) {
225 line = line.substring(0, pos);
226 }
08fe2e33 227 }
08fe2e33 228
83f66cbb 229 try {
ce297a79
NR
230 urls.add(new AbstractMap.SimpleEntry<String, URL>(name,
231 new URL("http://www.fimfiction.net" + line)));
83f66cbb 232 } catch (MalformedURLException e) {
d66deb8d 233 Instance.getInstance().getTraceHandler().error(e);
83f66cbb 234 }
08fe2e33
NR
235 }
236 }
237 }
238
239 return urls;
240 }
241
242 @Override
ed08c171
NR
243 protected String getChapterContent(URL source, InputStream in, int number,
244 Progress pg) {
83f66cbb 245 return getLine(in, "<div class=\"bbcode\">", 1);
08fe2e33
NR
246 }
247
248 @Override
249 protected boolean supports(URL url) {
250 return "fimfiction.net".equals(url.getHost())
251 || "www.fimfiction.net".equals(url.getHost());
252 }
253}