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