1 package be
.nikiroo
.fanfix
.supported
;
3 import java
.awt
.image
.BufferedImage
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
7 import java
.util
.ArrayList
;
10 import java
.util
.Map
.Entry
;
11 import java
.util
.Scanner
;
13 import be
.nikiroo
.fanfix
.Instance
;
14 import be
.nikiroo
.fanfix
.data
.MetaData
;
15 import be
.nikiroo
.utils
.StringUtils
;
18 * Support class for <a href="https://sofurry.com/">SoFurry.com</a>, a Furry
19 * website supporting images and stories (we only retrieve the stories).
23 class YiffStar
extends BasicSupport
{
26 public String
getSourceName() {
31 protected MetaData
getMeta(URL source
, InputStream in
) throws IOException
{
32 MetaData meta
= new MetaData();
34 meta
.setTitle(getTitle(reset(in
)));
35 meta
.setAuthor(getAuthor(source
, reset(in
)));
37 meta
.setTags(getTags(reset(in
)));
38 meta
.setSource(getSourceName());
39 meta
.setUrl(source
.toString());
40 meta
.setPublisher(getSourceName());
41 meta
.setUuid(source
.toString());
44 meta
.setSubject("Furry");
45 meta
.setType(getType().toString());
46 meta
.setImageDocument(false);
47 meta
.setCover(getCover(source
, reset(in
)));
53 protected boolean supports(URL url
) {
54 String host
= url
.getHost();
55 if (host
.startsWith("www.")) {
56 host
= host
.substring("www.".length());
59 return "sofurry.com".equals(host
);
63 protected boolean isHtml() {
68 public Map
<String
, String
> getCookies() {
70 // Cookies will actually be retained by the cache manager once logged in
71 // But we need to connect here and notify the cache manager
73 return super.getCookies();
77 public URL
getCanonicalUrl(URL source
) throws IOException
{
78 if (source
.getPath().startsWith("/view")) {
79 InputStream in
= Instance
.getCache().open(source
, this, false);
80 String line
= getLine(in
, "/browse/folder/", 0);
81 String
[] tab
= line
.split("\"");
83 String groupUrl
= source
.getProtocol() + "://"
84 + source
.getHost() + tab
[1];
85 return new URL(groupUrl
);
89 return super.getCanonicalUrl(source
);
92 private List
<String
> getTags(InputStream in
) {
93 List
<String
> tags
= new ArrayList
<String
>();
95 String line
= getLine(in
, "class=\"sf-story-big-tags", 0);
97 String
[] tab
= StringUtils
.unhtml(line
).split(",");
98 for (String possibleTag
: tab
) {
99 String tag
= possibleTag
.trim();
100 if (!tag
.isEmpty() && !tag
.equals("...") && !tags
.contains(tag
)) {
109 private BufferedImage
getCover(URL source
, InputStream in
)
112 List
<Entry
<String
, URL
>> chaps
= getChapters(source
, in
);
113 if (!chaps
.isEmpty()) {
114 in
= Instance
.getCache().open(chaps
.get(0).getValue(), this, true);
115 String line
= getLine(in
, " name=\"og:image\"", 0);
118 for (int i
= 0; i
< 3; i
++) {
119 pos
= line
.indexOf('"', pos
+ 1);
123 line
= line
.substring(pos
+ 1);
124 pos
= line
.indexOf('"');
126 line
= line
.substring(0, pos
);
127 if (line
.contains("/thumb?")) {
128 line
= line
.replace("/thumb?",
129 "/auxiliaryContent?type=25&");
130 return getImage(this, null, line
);
140 private String
getAuthor(URL source
, InputStream in
) throws IOException
{
141 String author
= getLine(in
, "class=\"onlinestatus", 0);
142 if (author
!= null) {
143 return StringUtils
.unhtml(author
).trim();
149 private String
getTitle(InputStream in
) throws IOException
{
150 String title
= getLine(in
, "class=\"sflabel pagetitle", 0);
152 if (title
.contains("(series)")) {
153 title
= title
.replace("(series)", "");
155 return StringUtils
.unhtml(title
).trim();
162 protected String
getDesc(URL source
, InputStream in
) throws IOException
{
163 return null; // TODO: no description at all? Cannot find one...
167 protected List
<Entry
<String
, URL
>> getChapters(URL source
, InputStream in
)
169 List
<Entry
<String
, URL
>> urls
= new ArrayList
<Entry
<String
, URL
>>();
171 @SuppressWarnings("resource")
172 Scanner scan
= new Scanner(in
, "UTF-8");
173 scan
.useDelimiter("\\n");
174 while (scan
.hasNext()) {
175 String line
= scan
.next();
176 if (line
.contains("\"/view/") && line
.contains("title=")) {
177 String
[] tab
= line
.split("\"");
178 if (tab
.length
> 5) {
179 String link
= tab
[5];
180 if (link
.startsWith("/")) {
181 link
= source
.getProtocol() + "://" + source
.getHost()
184 final URL value
= new URL(link
);
185 final String key
= StringUtils
.unhtml(line
).trim();
186 urls
.add(new Entry
<String
, URL
>() {
187 public URL
setValue(URL value
) {
191 public URL
getValue() {
195 public String
getKey() {
207 protected String
getChapterContent(URL source
, InputStream in
, int number
)
209 StringBuilder builder
= new StringBuilder();
211 String startAt
= "id=\"sfContentBody";
212 String endAt
= "id=\"recommendationArea";
215 @SuppressWarnings("resource")
216 Scanner scan
= new Scanner(in
, "UTF-8");
217 scan
.useDelimiter("\\n");
218 while (scan
.hasNext()) {
219 String line
= scan
.next();
220 if (!ok
&& line
.contains(startAt
)) {
222 } else if (ok
&& line
.contains(endAt
)) {
228 builder
.append(line
);
229 builder
.append('\n');
233 return builder
.toString();