Commit | Line | Data |
---|---|---|
fd69647f NR |
1 | package be.nikiroo.fanfix.searchable; |
2 | ||
3 | import java.io.IOException; | |
4 | import java.net.URL; | |
5 | import java.util.List; | |
6 | ||
7 | import org.jsoup.helper.DataUtil; | |
8 | import org.jsoup.nodes.Document; | |
9 | ||
10 | import be.nikiroo.fanfix.Instance; | |
11 | import be.nikiroo.fanfix.data.MetaData; | |
12 | import be.nikiroo.fanfix.supported.BasicSupport; | |
13 | import be.nikiroo.fanfix.supported.SupportType; | |
14 | ||
15 | /** | |
16 | * This class supports browsing through stories on the supported websites. It | |
17 | * will fetch some {@link MetaData} that satisfy a search query or some tags if | |
18 | * supported. | |
19 | * | |
20 | * @author niki | |
21 | */ | |
22 | public abstract class BasicSearchable { | |
23 | private SupportType type; | |
24 | private BasicSupport support; | |
25 | ||
26 | /** | |
27 | * Create a new {@link BasicSearchable} of the given type. | |
28 | * | |
29 | * @param type | |
30 | * the type, must not be NULL | |
31 | */ | |
32 | public BasicSearchable(SupportType type) { | |
33 | setType(type); | |
34 | support = BasicSupport.getSupport(getType(), null); | |
35 | } | |
36 | ||
aaeabf3a NR |
37 | /** |
38 | * Find the given tag by its hierarchical IDs. | |
39 | * <p> | |
40 | * I.E., it will take the tag A, subtag B, subsubtag C... | |
41 | * | |
42 | * @param ids | |
43 | * the IDs to look for | |
44 | * | |
45 | * @return the appropriate tag fully filled, or NULL if not found | |
46 | * | |
47 | * @throws IOException | |
48 | * in case of I/O error | |
49 | */ | |
50 | public SearchableTag getTag(Integer... ids) throws IOException { | |
51 | SearchableTag tag = null; | |
52 | List<SearchableTag> tags = getTags(); | |
53 | ||
54 | for (Integer tagIndex : ids) { | |
55 | // ! 1-based index ! | |
56 | if (tagIndex == null || tags == null || tagIndex <= 0 | |
57 | || tagIndex > tags.size()) { | |
58 | return null; | |
59 | } | |
60 | ||
61 | tag = tags.get(tagIndex - 1); | |
62 | fillTag(tag); | |
63 | tags = tag.getChildren(); | |
64 | } | |
65 | ||
66 | return tag; | |
67 | } | |
68 | ||
fd69647f NR |
69 | /** |
70 | * The support type. | |
71 | * | |
72 | * @return the type | |
73 | */ | |
74 | public SupportType getType() { | |
75 | return type; | |
76 | } | |
77 | ||
78 | /** | |
79 | * The support type. | |
80 | * | |
81 | * @param type | |
82 | * the new type | |
83 | */ | |
84 | protected void setType(SupportType type) { | |
85 | this.type = type; | |
86 | } | |
87 | ||
88 | /** | |
89 | * The associated {@link BasicSupport}. | |
90 | * <p> | |
91 | * Mostly used to download content. | |
92 | * | |
93 | * @return the support | |
94 | */ | |
95 | protected BasicSupport getSupport() { | |
96 | return support; | |
97 | } | |
98 | ||
99 | /** | |
100 | * Get a list of tags that can be browsed here. | |
101 | * | |
102 | * @return the list of tags | |
103 | * | |
104 | * @throws IOException | |
105 | * in case of I/O error | |
106 | */ | |
107 | abstract public List<SearchableTag> getTags() throws IOException; | |
108 | ||
109 | /** | |
110 | * Fill the tag (set it 'complete') with more information from the support. | |
111 | * | |
112 | * @param tag | |
113 | * the tag to fill | |
114 | * | |
115 | * @throws IOException | |
116 | * in case of I/O error | |
117 | */ | |
91b82a5c | 118 | abstract public void fillTag(SearchableTag tag) throws IOException; |
fd69647f | 119 | |
124442f1 NR |
120 | /** |
121 | * Search for the given term and return the number of pages of results of | |
122 | * stories satisfying this search term. | |
123 | * | |
124 | * @param search | |
125 | * the term to search for | |
126 | * | |
127 | * @return a number of pages | |
128 | * | |
129 | * @throws IOException | |
130 | * in case of I/O error | |
131 | */ | |
132 | abstract public int searchPages(String search) throws IOException; | |
133 | ||
81acd363 NR |
134 | /** |
135 | * Search for the given tag and return the number of pages of results of | |
136 | * stories satisfying this tag. | |
137 | * | |
138 | * @param tag | |
139 | * the tag to search for | |
140 | * | |
141 | * @return a number of pages | |
142 | * | |
143 | * @throws IOException | |
144 | * in case of I/O error | |
145 | */ | |
146 | abstract public int searchPages(SearchableTag tag) throws IOException; | |
147 | ||
fd69647f NR |
148 | /** |
149 | * Search for the given term and return a list of stories satisfying this | |
150 | * search term. | |
151 | * <p> | |
152 | * Not that the returned stories will <b>NOT</b> be complete, but will only | |
153 | * contain enough information to present them to the user and retrieve them. | |
154 | * <p> | |
155 | * URL is guaranteed to be usable, LUID will always be NULL. | |
156 | * | |
157 | * @param search | |
158 | * the term to search for | |
8ffc8b73 NR |
159 | * @param page |
160 | * the page to use for result pagination, index is 1-based | |
fd69647f NR |
161 | * |
162 | * @return a list of stories that satisfy that search term | |
163 | * | |
164 | * @throws IOException | |
165 | * in case of I/O error | |
166 | */ | |
8ffc8b73 NR |
167 | abstract public List<MetaData> search(String search, int page) |
168 | throws IOException; | |
fd69647f NR |
169 | |
170 | /** | |
171 | * Search for the given tag and return a list of stories satisfying this | |
172 | * tag. | |
173 | * <p> | |
174 | * Not that the returned stories will <b>NOT</b> be complete, but will only | |
175 | * contain enough information to present them to the user and retrieve them. | |
176 | * <p> | |
177 | * URL is guaranteed to be usable, LUID will always be NULL. | |
178 | * | |
8ffc8b73 | 179 | * @param tag |
fd69647f | 180 | * the tag to search for |
e66c9078 NR |
181 | * @param page |
182 | * the page to use for result pagination (see | |
183 | * {@link SearchableTag#getPages()}, remember to check for -1), | |
184 | * index is 1-based | |
fd69647f NR |
185 | * |
186 | * @return a list of stories that satisfy that search term | |
187 | * | |
188 | * @throws IOException | |
189 | * in case of I/O error | |
190 | */ | |
e66c9078 NR |
191 | abstract public List<MetaData> search(SearchableTag tag, int page) |
192 | throws IOException; | |
fd69647f NR |
193 | |
194 | /** | |
195 | * Load a document from its url. | |
196 | * | |
197 | * @param url | |
198 | * the URL to load | |
76ec935e NR |
199 | * @param stable |
200 | * TRUE for more stable resources, FALSE when they often change | |
201 | * | |
fd69647f NR |
202 | * @return the document |
203 | * | |
204 | * @throws IOException | |
205 | * in case of I/O error | |
206 | */ | |
76ec935e NR |
207 | protected Document load(String url, boolean stable) throws IOException { |
208 | return load(new URL(url), stable); | |
fd69647f NR |
209 | } |
210 | ||
211 | /** | |
212 | * Load a document from its url. | |
213 | * | |
214 | * @param url | |
215 | * the URL to load | |
76ec935e NR |
216 | * @param stable |
217 | * TRUE for more stable resources, FALSE when they often change | |
218 | * | |
fd69647f NR |
219 | * @return the document |
220 | * | |
221 | * @throws IOException | |
222 | * in case of I/O error | |
223 | */ | |
76ec935e NR |
224 | protected Document load(URL url, boolean stable) throws IOException { |
225 | return DataUtil.load(Instance.getCache().open(url, support, stable), | |
fd69647f NR |
226 | "UTF-8", url.toString()); |
227 | } | |
228 | ||
229 | /** | |
230 | * Return a {@link BasicSearchable} implementation supporting the given | |
231 | * type, or NULL if it does not exist. | |
232 | * | |
233 | * @param type | |
b31a0db0 NR |
234 | * the type, can be NULL (will just return NULL, since we do not |
235 | * support it) | |
fd69647f NR |
236 | * |
237 | * @return an implementation that supports it, or NULL | |
238 | */ | |
aaeabf3a | 239 | static public BasicSearchable getSearchable(SupportType type) { |
fd69647f NR |
240 | BasicSearchable support = null; |
241 | ||
b31a0db0 NR |
242 | if (type != null) { |
243 | switch (type) { | |
244 | case FIMFICTION: | |
245 | // TODO | |
246 | break; | |
247 | case FANFICTION: | |
248 | support = new Fanfiction(type); | |
249 | break; | |
250 | case MANGAFOX: | |
251 | // TODO | |
252 | break; | |
253 | case E621: | |
254 | // TODO | |
255 | break; | |
256 | case YIFFSTAR: | |
257 | // TODO | |
258 | break; | |
259 | case E_HENTAI: | |
260 | // TODO | |
261 | break; | |
262 | case MANGA_LEL: | |
263 | support = new MangaLel(); | |
264 | break; | |
265 | case CBZ: | |
266 | case HTML: | |
267 | case INFO_TEXT: | |
268 | case TEXT: | |
269 | case EPUB: | |
270 | break; | |
271 | } | |
fd69647f NR |
272 | } |
273 | ||
274 | return support; | |
275 | } | |
276 | } |