Commit | Line | Data |
---|---|---|
af1f506f NR |
1 | package be.nikiroo.fanfix.supported; |
2 | ||
3 | import java.io.IOException; | |
4 | import java.io.InputStream; | |
af1f506f | 5 | import java.net.URL; |
6fc76bae NR |
6 | import java.text.ParseException; |
7 | import java.text.SimpleDateFormat; | |
af1f506f NR |
8 | import java.util.AbstractMap; |
9 | import java.util.ArrayList; | |
af1f506f NR |
10 | import java.util.List; |
11 | import java.util.Map.Entry; | |
12 | ||
13 | import org.jsoup.helper.DataUtil; | |
14 | import org.jsoup.nodes.Element; | |
15 | import org.jsoup.select.Elements; | |
16 | ||
17 | import be.nikiroo.fanfix.Instance; | |
18 | import be.nikiroo.fanfix.data.MetaData; | |
19 | import be.nikiroo.utils.Image; | |
20 | import be.nikiroo.utils.Progress; | |
21 | import be.nikiroo.utils.StringUtils; | |
22 | ||
23 | class MangaLel extends BasicSupport { | |
24 | @Override | |
25 | protected boolean isHtml() { | |
26 | return true; | |
27 | } | |
28 | ||
af1f506f NR |
29 | @Override |
30 | protected MetaData getMeta() throws IOException { | |
31 | MetaData meta = new MetaData(); | |
32 | ||
af1f506f | 33 | meta.setTitle(getTitle()); |
6fc76bae NR |
34 | meta.setAuthor(getAuthor()); |
35 | meta.setDate(getDate()); | |
36 | meta.setTags(getTags()); | |
727108fe | 37 | meta.setSource(getType().getSourceName()); |
af1f506f | 38 | meta.setUrl(getSource().toString()); |
727108fe | 39 | meta.setPublisher(getType().getSourceName()); |
af1f506f NR |
40 | meta.setUuid(getSource().toString()); |
41 | meta.setLuid(""); | |
42 | meta.setLang("fr"); | |
43 | meta.setSubject("manga"); | |
44 | meta.setType(getType().toString()); | |
45 | meta.setImageDocument(true); | |
46 | meta.setCover(getCover()); | |
47 | ||
48 | return meta; | |
49 | } | |
50 | ||
51 | private String getTitle() { | |
52 | Element doc = getSourceNode(); | |
6fc76bae NR |
53 | Element h4 = doc.getElementsByTag("h4").first(); |
54 | if (h4 != null) { | |
55 | return StringUtils.unhtml(h4.text()).trim(); | |
af1f506f NR |
56 | } |
57 | ||
58 | return null; | |
59 | } | |
60 | ||
6fc76bae NR |
61 | private String getAuthor() { |
62 | Element doc = getSourceNode(); | |
12443642 NR |
63 | Element tabEls = doc.getElementsByClass("presentation-projet").first(); |
64 | if (tabEls != null) { | |
65 | String[] tab = tabEls.outerHtml().split("<br>"); | |
66 | return getVal(tab, 1); | |
6fc76bae NR |
67 | } |
68 | ||
12443642 | 69 | return ""; |
6fc76bae NR |
70 | } |
71 | ||
72 | private List<String> getTags() { | |
af1f506f | 73 | Element doc = getSourceNode(); |
12443642 NR |
74 | Element tabEls = doc.getElementsByClass("presentation-projet").first(); |
75 | if (tabEls != null) { | |
76 | String[] tab = tabEls.outerHtml().split("<br>"); | |
77 | List<String> tags = new ArrayList<String>(); | |
78 | for (String tag : getVal(tab, 3).split(" ")) { | |
79 | tags.add(tag); | |
af1f506f | 80 | } |
12443642 | 81 | return tags; |
af1f506f NR |
82 | } |
83 | ||
12443642 NR |
84 | return new ArrayList<String>(); |
85 | ||
6fc76bae NR |
86 | } |
87 | ||
88 | private String getDate() { | |
89 | Element doc = getSourceNode(); | |
90 | Element table = doc.getElementsByClass("table").first(); | |
91 | ||
92 | // We take the first date we find | |
93 | String value = ""; | |
94 | if (table != null) { | |
95 | Elements els; | |
96 | els = table.getElementsByTag("tr"); | |
97 | if (els.size() >= 2) { | |
98 | els = els.get(1).getElementsByTag("td"); | |
99 | if (els.size() >= 3) { | |
100 | value = StringUtils.unhtml(els.get(2).text()).trim(); | |
af1f506f | 101 | } |
af1f506f | 102 | } |
af1f506f NR |
103 | } |
104 | ||
6fc76bae NR |
105 | if (!value.isEmpty()) { |
106 | try { | |
107 | long time = StringUtils.toTime(value); | |
108 | value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") | |
109 | .format(time); | |
110 | } catch (ParseException e) { | |
111 | } | |
112 | } | |
113 | ||
114 | return value; | |
af1f506f NR |
115 | } |
116 | ||
117 | @Override | |
118 | protected String getDesc() { | |
af1f506f | 119 | Element doc = getSourceNode(); |
12443642 NR |
120 | Element tabEls = doc.getElementsByClass("presentation-projet").first(); |
121 | if (tabEls != null) { | |
122 | String[] tab = tabEls.outerHtml().split("<br>"); | |
123 | return getVal(tab, 4); | |
af1f506f NR |
124 | } |
125 | ||
12443642 | 126 | return ""; |
af1f506f NR |
127 | } |
128 | ||
129 | private Image getCover() { | |
130 | Element doc = getSourceNode(); | |
6fc76bae NR |
131 | Element container = doc.getElementsByClass("container").first(); |
132 | ||
133 | if (container != null) { | |
134 | ||
135 | Elements imgs = container.getElementsByTag("img"); | |
136 | Element img = null; | |
137 | if (imgs.size() >= 1) { | |
138 | img = imgs.get(0); | |
139 | if (img.hasClass("banniere-team-projet")) { | |
140 | img = null; | |
141 | if (imgs.size() >= 2) { | |
142 | img = imgs.get(1); | |
143 | } | |
144 | } | |
145 | } | |
af1f506f | 146 | |
6fc76bae NR |
147 | if (img != null) { |
148 | String coverUrl = img.absUrl("src"); | |
af1f506f | 149 | |
6fc76bae | 150 | InputStream coverIn; |
af1f506f | 151 | try { |
d66deb8d | 152 | coverIn = Instance.getInstance().getCache().open(new URL(coverUrl), this, true); |
6fc76bae NR |
153 | try { |
154 | return new Image(coverIn); | |
155 | } finally { | |
156 | coverIn.close(); | |
157 | } | |
158 | } catch (IOException e) { | |
d66deb8d | 159 | Instance.getInstance().getTraceHandler().error(e); |
af1f506f | 160 | } |
af1f506f NR |
161 | } |
162 | } | |
163 | ||
164 | return null; | |
165 | } | |
166 | ||
12443642 NR |
167 | private String getVal(String[] tab, int i) { |
168 | String val = ""; | |
169 | ||
170 | if (i < tab.length) { | |
171 | val = StringUtils.unhtml(tab[i]); | |
172 | int pos = val.indexOf(":"); | |
173 | if (pos >= 0) { | |
174 | val = val.substring(pos + 1).trim(); | |
175 | } | |
176 | } | |
177 | ||
178 | return val; | |
179 | } | |
180 | ||
af1f506f | 181 | @Override |
6fc76bae NR |
182 | protected List<Entry<String, URL>> getChapters(Progress pg) |
183 | throws IOException { | |
af1f506f NR |
184 | List<Entry<String, URL>> urls = new ArrayList<Entry<String, URL>>(); |
185 | ||
af1f506f | 186 | Element doc = getSourceNode(); |
6fc76bae NR |
187 | Element table = doc.getElementsByClass("table").first(); |
188 | if (table != null) { | |
189 | for (Element tr : table.getElementsByTag("tr")) { | |
190 | Element a = tr.getElementsByTag("a").first(); | |
191 | if (a != null) { | |
192 | String name = StringUtils.unhtml(a.text()).trim(); | |
193 | URL url = new URL(a.absUrl("href")); | |
194 | urls.add(new AbstractMap.SimpleEntry<String, URL>(name, url)); | |
195 | } | |
af1f506f NR |
196 | } |
197 | } | |
198 | ||
af1f506f NR |
199 | return urls; |
200 | } | |
201 | ||
202 | @Override | |
203 | protected String getChapterContent(URL chapUrl, int number, Progress pg) | |
204 | throws IOException { | |
205 | if (pg == null) { | |
206 | pg = new Progress(); | |
207 | } | |
208 | ||
209 | StringBuilder builder = new StringBuilder(); | |
210 | ||
d66deb8d | 211 | InputStream in = Instance.getInstance().getCache().open(chapUrl, this, false); |
af1f506f NR |
212 | try { |
213 | Element pageDoc = DataUtil.load(in, "UTF-8", chapUrl.toString()); | |
6fc76bae NR |
214 | Element content = pageDoc.getElementById("content"); |
215 | Elements linkEls = content.getElementsByTag("img"); | |
af1f506f | 216 | for (Element linkEl : linkEls) { |
12443642 | 217 | if (linkEl.absUrl("src").isEmpty()) { |
6fc76bae | 218 | continue; |
af1f506f | 219 | } |
6fc76bae NR |
220 | |
221 | builder.append("["); | |
12443642 | 222 | builder.append(linkEl.absUrl("src")); |
6fc76bae | 223 | builder.append("]<br/>"); |
af1f506f NR |
224 | } |
225 | ||
226 | } finally { | |
227 | in.close(); | |
228 | } | |
229 | ||
230 | return builder.toString(); | |
231 | } | |
232 | ||
af1f506f NR |
233 | @Override |
234 | protected boolean supports(URL url) { | |
6fc76bae NR |
235 | // URL structure (the projectId is the manga key): |
236 | // http://mangas-lecture-en-ligne.fr/index_lel.php?page=presentationProjet&idProjet=999 | |
237 | ||
238 | return "mangas-lecture-en-ligne.fr".equals(url.getHost()); | |
af1f506f NR |
239 | } |
240 | } |