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