GUI: automatically select URLs from clipboard
[nikiroo-utils.git] / src / be / nikiroo / fanfix / supported / YiffStar.java
CommitLineData
a4143cd7
NR
1package be.nikiroo.fanfix.supported;
2
3import java.awt.image.BufferedImage;
4import java.io.IOException;
5import java.io.InputStream;
6import java.net.URL;
7import java.util.ArrayList;
6e06d2cc 8import java.util.HashMap;
a4143cd7
NR
9import java.util.List;
10import java.util.Map;
11import java.util.Map.Entry;
12import java.util.Scanner;
13
14import be.nikiroo.fanfix.Instance;
6e06d2cc 15import be.nikiroo.fanfix.bundles.Config;
a4143cd7
NR
16import be.nikiroo.fanfix.data.MetaData;
17import be.nikiroo.utils.StringUtils;
18
19/**
20 * Support class for <a href="https://sofurry.com/">SoFurry.com</a>, a Furry
21 * website supporting images and stories (we only retrieve the stories).
22 *
23 * @author niki
24 */
25class YiffStar extends BasicSupport {
26
27 @Override
28 public String getSourceName() {
29 return "YiffStar";
30 }
31
32 @Override
33 protected MetaData getMeta(URL source, InputStream in) throws IOException {
34 MetaData meta = new MetaData();
35
36 meta.setTitle(getTitle(reset(in)));
37 meta.setAuthor(getAuthor(source, reset(in)));
38 meta.setDate("");
39 meta.setTags(getTags(reset(in)));
40 meta.setSource(getSourceName());
41 meta.setUrl(source.toString());
42 meta.setPublisher(getSourceName());
43 meta.setUuid(source.toString());
44 meta.setLuid("");
45 meta.setLang("EN");
46 meta.setSubject("Furry");
47 meta.setType(getType().toString());
48 meta.setImageDocument(false);
49 meta.setCover(getCover(source, reset(in)));
50
51 return meta;
52 }
53
54 @Override
55 protected boolean supports(URL url) {
56 String host = url.getHost();
57 if (host.startsWith("www.")) {
58 host = host.substring("www.".length());
59 }
60
61 return "sofurry.com".equals(host);
62 }
63
64 @Override
65 protected boolean isHtml() {
66 return true;
67 }
68
69 @Override
6e06d2cc
NR
70 public void login() throws IOException {
71 Map<String, String> post = new HashMap<String, String>();
72 post.put("LoginForm[sfLoginUsername]",
73 Instance.getConfig().getString(Config.LOGIN_YIFFSTAR_USER));
74 post.put("LoginForm[sfLoginPassword]",
75 Instance.getConfig().getString(Config.LOGIN_YIFFSTAR_PASS));
76 post.put("YII_CSRF_TOKEN", "");
a4143cd7 77
6e06d2cc
NR
78 // Cookies will actually be retained by the cache manager once logged in
79 // TODO: not working yet, once fixed can be removed (adding "/guest" to
80 // URLs fix the access problem!):
81 /*
82 * Instance.getCache() .openNoCache(new
83 * URL("https://www.sofurry.com/user/login"), this, post).close();
84 */
a4143cd7
NR
85 }
86
87 @Override
88 public URL getCanonicalUrl(URL source) throws IOException {
89 if (source.getPath().startsWith("/view")) {
90 InputStream in = Instance.getCache().open(source, this, false);
91 String line = getLine(in, "/browse/folder/", 0);
6e06d2cc
NR
92 if (line != null) {
93 String[] tab = line.split("\"");
94 if (tab.length > 1) {
95 String groupUrl = source.getProtocol() + "://"
96 + source.getHost() + tab[1];
97 return new URL(groupUrl);
98 }
a4143cd7
NR
99 }
100 }
101
102 return super.getCanonicalUrl(source);
103 }
104
105 private List<String> getTags(InputStream in) {
106 List<String> tags = new ArrayList<String>();
107
108 String line = getLine(in, "class=\"sf-story-big-tags", 0);
109 if (line != null) {
110 String[] tab = StringUtils.unhtml(line).split(",");
111 for (String possibleTag : tab) {
112 String tag = possibleTag.trim();
113 if (!tag.isEmpty() && !tag.equals("...") && !tags.contains(tag)) {
114 tags.add(tag);
115 }
116 }
117 }
118
119 return tags;
120 }
121
122 private BufferedImage getCover(URL source, InputStream in)
123 throws IOException {
124
125 List<Entry<String, URL>> chaps = getChapters(source, in);
126 if (!chaps.isEmpty()) {
127 in = Instance.getCache().open(chaps.get(0).getValue(), this, true);
128 String line = getLine(in, " name=\"og:image\"", 0);
129 if (line != null) {
130 int pos = -1;
131 for (int i = 0; i < 3; i++) {
132 pos = line.indexOf('"', pos + 1);
133 }
134
135 if (pos >= 0) {
136 line = line.substring(pos + 1);
137 pos = line.indexOf('"');
138 if (pos >= 0) {
139 line = line.substring(0, pos);
140 if (line.contains("/thumb?")) {
141 line = line.replace("/thumb?",
142 "/auxiliaryContent?type=25&");
143 return getImage(this, null, line);
144 }
145 }
146 }
147 }
148 }
149
150 return null;
151 }
152
153 private String getAuthor(URL source, InputStream in) throws IOException {
154 String author = getLine(in, "class=\"onlinestatus", 0);
155 if (author != null) {
156 return StringUtils.unhtml(author).trim();
157 }
158
159 return null;
160 }
161
162 private String getTitle(InputStream in) throws IOException {
163 String title = getLine(in, "class=\"sflabel pagetitle", 0);
164 if (title != null) {
165 if (title.contains("(series)")) {
166 title = title.replace("(series)", "");
167 }
168 return StringUtils.unhtml(title).trim();
169 }
170
171 return null;
172 }
173
174 @Override
175 protected String getDesc(URL source, InputStream in) throws IOException {
176 return null; // TODO: no description at all? Cannot find one...
177 }
178
179 @Override
180 protected List<Entry<String, URL>> getChapters(URL source, InputStream in)
181 throws IOException {
182 List<Entry<String, URL>> urls = new ArrayList<Entry<String, URL>>();
183
184 @SuppressWarnings("resource")
185 Scanner scan = new Scanner(in, "UTF-8");
186 scan.useDelimiter("\\n");
187 while (scan.hasNext()) {
188 String line = scan.next();
189 if (line.contains("\"/view/") && line.contains("title=")) {
190 String[] tab = line.split("\"");
191 if (tab.length > 5) {
192 String link = tab[5];
193 if (link.startsWith("/")) {
194 link = source.getProtocol() + "://" + source.getHost()
195 + link;
196 }
197 final URL value = new URL(link);
198 final String key = StringUtils.unhtml(line).trim();
199 urls.add(new Entry<String, URL>() {
200 public URL setValue(URL value) {
201 return null;
202 }
203
204 public URL getValue() {
205 return value;
206 }
207
208 public String getKey() {
209 return key;
210 }
211 });
212 }
213 }
214 }
215
216 return urls;
217 }
218
219 @Override
220 protected String getChapterContent(URL source, InputStream in, int number)
221 throws IOException {
222 StringBuilder builder = new StringBuilder();
223
224 String startAt = "id=\"sfContentBody";
225 String endAt = "id=\"recommendationArea";
226 boolean ok = false;
227
228 @SuppressWarnings("resource")
229 Scanner scan = new Scanner(in, "UTF-8");
230 scan.useDelimiter("\\n");
231 while (scan.hasNext()) {
232 String line = scan.next();
233 if (!ok && line.contains(startAt)) {
234 ok = true;
235 } else if (ok && line.contains(endAt)) {
236 ok = false;
237 break;
238 }
239
240 if (ok) {
241 builder.append(line);
242 builder.append('\n');
243 }
244 }
245
246 return builder.toString();
247 }
248}