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
.AbstractMap
;
8 import java
.util
.ArrayList
;
9 import java
.util
.HashMap
;
10 import java
.util
.List
;
12 import java
.util
.Map
.Entry
;
13 import java
.util
.Scanner
;
15 import be
.nikiroo
.fanfix
.Instance
;
16 import be
.nikiroo
.fanfix
.data
.MetaData
;
17 import be
.nikiroo
.utils
.Image
;
18 import be
.nikiroo
.utils
.Progress
;
19 import be
.nikiroo
.utils
.StringUtils
;
22 * Support class for <a href="http://www.fimfiction.net/">FimFiction.net</a>
23 * stories, a website dedicated to My Little Pony.
27 class Fimfiction
extends BasicSupport_Deprecated
{
29 protected boolean isHtml() {
34 public String
getSourceName() {
35 return "FimFiction.net";
39 protected MetaData
getMeta(URL source
, InputStream in
) throws IOException
{
40 MetaData meta
= new MetaData();
42 meta
.setTitle(getTitle(reset(in
)));
43 meta
.setAuthor(getAuthor(reset(in
)));
44 meta
.setDate(getDate(reset(in
)));
45 meta
.setTags(getTags(reset(in
)));
46 meta
.setSource(getSourceName());
47 meta
.setUrl(source
.toString());
48 meta
.setPublisher(getSourceName());
49 meta
.setUuid(source
.toString());
52 meta
.setSubject("MLP");
53 meta
.setType(getType().toString());
54 meta
.setImageDocument(false);
55 meta
.setCover(getCover(reset(in
)));
61 public Map
<String
, String
> getCookies() {
62 Map
<String
, String
> cookies
= new HashMap
<String
, String
>();
63 cookies
.put("view_mature", "true");
67 private List
<String
> getTags(InputStream in
) {
68 List
<String
> tags
= new ArrayList
<String
>();
71 @SuppressWarnings("resource")
72 Scanner scan
= new Scanner(in
, "UTF-8");
73 scan
.useDelimiter("\\n");
74 boolean started
= false;
75 while (scan
.hasNext()) {
76 String line
= scan
.next();
79 started
= line
.contains("\"story_container\"");
82 if (started
&& line
.contains("class=\"tag-")) {
83 if (line
.contains("index.php")) {
84 break; // end of *this story* tags
87 String keyword
= "title=\"";
88 Scanner tagScanner
= new Scanner(line
);
89 tagScanner
.useDelimiter(keyword
);
90 if (tagScanner
.hasNext()) {
91 tagScanner
.next();// Ignore first one
93 while (tagScanner
.hasNext()) {
94 String tag
= tagScanner
.next();
95 if (tag
.contains("\"")) {
96 tag
= tag
.split("\"")[0];
97 tag
= StringUtils
.unhtml(tag
).trim();
98 if (!tag
.isEmpty() && !tags
.contains(tag
)) {
110 private String
getTitle(InputStream in
) {
111 String line
= getLine(in
, " property=\"og:title\"", 0);
114 for (int i
= 0; i
< 3; i
++) {
115 pos
= line
.indexOf('"', pos
+ 1);
119 line
= line
.substring(pos
+ 1);
120 pos
= line
.indexOf('"');
122 return StringUtils
.unhtml(line
.substring(0, pos
)).trim();
130 private String
getAuthor(InputStream in
) {
131 String line
= getLine(in
, " href=\"/user/", 0);
133 int pos
= line
.indexOf('"');
135 line
= line
.substring(pos
+ 1);
136 pos
= line
.indexOf('"');
138 line
= line
.substring(0, pos
);
139 pos
= line
.lastIndexOf('/');
141 line
= line
.substring(pos
+ 1);
142 return line
.replace('+', ' ');
151 private String
getDate(InputStream in
) {
152 String line
= getLine(in
, "<span class=\"date\">", 0);
155 for (int i
= 0; i
< 3; i
++) {
156 pos
= line
.indexOf('>', pos
+ 1);
160 line
= line
.substring(pos
+ 1);
161 pos
= line
.indexOf('<');
163 return line
.substring(0, pos
).trim();
172 protected String
getDesc(URL source
, InputStream in
) {
173 // the og: meta version is the SHORT resume, this is the LONG resume
174 return getLine(in
, "class=\"description-text bbcode\"", 1);
177 private Image
getCover(InputStream in
) {
178 // Note: the 'og:image' is the SMALL cover, not the full version
179 String cover
= getLine(in
, "class=\"story_container__story_image\"", 1);
181 int pos
= cover
.indexOf('"');
183 cover
= cover
.substring(pos
+ 1);
184 pos
= cover
.indexOf('"');
186 cover
= cover
.substring(0, pos
);
191 return getImage(this, null, cover
);
195 protected List
<Entry
<String
, URL
>> getChapters(URL source
, InputStream in
,
197 List
<Entry
<String
, URL
>> urls
= new ArrayList
<Entry
<String
, URL
>>();
198 @SuppressWarnings("resource")
199 Scanner scan
= new Scanner(in
, "UTF-8");
200 scan
.useDelimiter("\\n");
201 boolean started
= false;
202 while (scan
.hasNext()) {
203 String line
= scan
.next().trim();
206 started
= line
.equals("<!--Chapters-->");
208 if (line
.equals("</form>")) {
212 if (line
.startsWith("<a href=")
213 || line
.contains("class=\"chapter-title\"")) {
216 int pos
= name
.indexOf('>');
218 name
= name
.substring(pos
+ 1);
219 pos
= name
.indexOf('<');
221 name
= name
.substring(0, pos
);
225 pos
= line
.indexOf('/');
227 line
= line
.substring(pos
); // we take the /, not +1
228 pos
= line
.indexOf('"');
230 line
= line
.substring(0, pos
);
235 urls
.add(new AbstractMap
.SimpleEntry
<String
, URL
>(name
,
236 new URL("http://www.fimfiction.net" + line
)));
237 } catch (MalformedURLException e
) {
238 Instance
.getTraceHandler().error(e
);
248 protected String
getChapterContent(URL source
, InputStream in
, int number
,
250 return getLine(in
, "<div class=\"bbcode\">", 1);
254 protected boolean supports(URL url
) {
255 return "fimfiction.net".equals(url
.getHost())
256 || "www.fimfiction.net".equals(url
.getHost());