Library fixes + "make install" fix
[fanfix.git] / src / be / nikiroo / fanfix / supported / Epub.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix.supported;
2
3import java.awt.image.BufferedImage;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.IOException;
7import java.io.InputStream;
8import java.net.URL;
9import java.util.List;
10import java.util.Map.Entry;
11import java.util.zip.ZipEntry;
12import java.util.zip.ZipInputStream;
13
14import javax.imageio.ImageIO;
15
16import be.nikiroo.fanfix.Instance;
17import be.nikiroo.fanfix.bundles.Config;
18import be.nikiroo.utils.IOUtils;
19import be.nikiroo.utils.MarkableFileInputStream;
20
21/**
22 * Support class for EPUB files created with this program (as we need some
23 * metadata available in those we create).
24 *
25 * @author niki
26 */
27class Epub extends BasicSupport {
28 private InfoText base;
29 private URL fakeSource;
30
31 private File tmpCover;
32 private File tmpInfo;
33 private File tmp;
34
35 /** Only used by {@link Epub#getInput()} so it is always reset. */
36 private InputStream in;
37
38 @Override
39 public String getSourceName() {
40 return "epub";
41 }
42
43 @Override
44 protected boolean supports(URL url) {
45 if (url.getPath().toLowerCase().endsWith(".epub")) {
46 return true;
47 }
48
49 return false;
50 }
51
52 @Override
53 protected boolean isHtml() {
54 if (tmpInfo.exists()) {
55 return base.isHtml();
56 }
57
58 return false;
59 }
60
61 @Override
62 protected String getTitle(URL source, InputStream in) throws IOException {
63 if (tmpInfo.exists()) {
64 return base.getTitle(fakeSource, getFakeInput());
65 }
66
67 return source.toString();
68 }
69
70 @Override
71 protected String getAuthor(URL source, InputStream in) throws IOException {
72 if (tmpInfo.exists()) {
73 return base.getAuthor(fakeSource, getFakeInput());
74 }
75
76 return null;
77 }
78
79 @Override
80 protected String getDate(URL source, InputStream in) throws IOException {
81 if (tmpInfo.exists()) {
82 return base.getDate(fakeSource, getFakeInput());
83 }
84
85 return null;
86 }
87
88 @Override
89 protected String getSubject(URL source, InputStream in) throws IOException {
90 if (tmpInfo.exists()) {
91 return base.getSubject(fakeSource, getFakeInput());
92 }
93
94 return null;
95 }
96
97 @Override
98 protected String getDesc(URL source, InputStream in) throws IOException {
99 if (tmpInfo.exists()) {
100 return base.getDesc(fakeSource, getFakeInput());
101 }
102
103 return null;
104 }
105
106 @Override
107 protected URL getCover(URL source, InputStream in) throws IOException {
108 if (tmpCover.exists()) {
109 return tmpCover.toURI().toURL();
110 }
111
112 return null;
113 }
114
115 @Override
116 protected List<Entry<String, URL>> getChapters(URL source, InputStream in)
117 throws IOException {
118 if (tmpInfo.exists()) {
119 return base.getChapters(fakeSource, getFakeInput());
120 }
121
122 return null;
123 }
124
125 @Override
126 protected String getChapterContent(URL source, InputStream in, int number)
127 throws IOException {
128 if (tmpInfo.exists()) {
129 return base.getChapterContent(fakeSource, getFakeInput(), number);
130 }
131
132 return null;
133 }
134
135 @Override
136 protected String getLang(URL source, InputStream in) throws IOException {
137 if (tmpInfo.exists()) {
138 return base.getLang(fakeSource, getFakeInput());
139 }
140
141 return super.getLang(source, in);
142 }
143
144 @Override
145 protected String getPublisher(URL source, InputStream in)
146 throws IOException {
147 if (tmpInfo.exists()) {
148 return base.getPublisher(fakeSource, getFakeInput());
149 }
150
151 return super.getPublisher(source, in);
152 }
153
154 @Override
155 protected List<String> getTags(URL source, InputStream in)
156 throws IOException {
157 if (tmpInfo.exists()) {
158 return base.getTags(fakeSource, getFakeInput());
159 }
160
161 return super.getTags(source, in);
162 }
163
164 @Override
165 protected String getUuid(URL source, InputStream in) throws IOException {
166 if (tmpInfo.exists()) {
167 return base.getUuid(fakeSource, getFakeInput());
168 }
169
170 return super.getUuid(source, in);
171 }
172
173 @Override
174 protected String getLuid(URL source, InputStream in) throws IOException {
175 if (tmpInfo.exists()) {
176 return base.getLuid(fakeSource, getFakeInput());
177 }
178
179 return super.getLuid(source, in);
180 }
181
182 @Override
183 protected void preprocess(InputStream in) throws IOException {
184 // Note: do NOT close this stream, as it would also close "in"
185 ZipInputStream zipIn = new ZipInputStream(in);
186 tmp = File.createTempFile("fanfic-reader-parser_", ".tmp");
187 tmpInfo = new File(tmp + ".info");
188 tmpCover = File.createTempFile("fanfic-reader-parser_", ".tmp");
189
190 base = new InfoText();
191 fakeSource = tmp.toURI().toURL();
192
193 for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
194 .getNextEntry()) {
195 if (!entry.isDirectory()
196 && entry.getName().startsWith(getDataPrefix())) {
197 String entryLName = entry.getName().toLowerCase();
fe999aa4 198
08fe2e33
NR
199 boolean imageEntry = false;
200 for (String ext : getImageExt(false)) {
201 if (entryLName.endsWith(ext)) {
202 imageEntry = true;
203 }
204 }
205
206 if (entry.getName().equals(getDataPrefix() + "version")) {
207 // Nothing to do for now ("first"
208 // version is 3.0)
209 } else if (entryLName.endsWith(".info")) {
210 // Info file
211 IOUtils.write(zipIn, tmpInfo);
212 } else if (imageEntry) {
213 // Cover
214 if (getCover()) {
215 try {
216 BufferedImage image = ImageIO.read(zipIn);
217 ImageIO.write(image, Instance.getConfig()
218 .getString(Config.IMAGE_FORMAT_COVER)
219 .toLowerCase(), tmpCover);
220 } catch (Exception e) {
221 Instance.syserr(e);
222 }
223 }
224 } else if (entry.getName().equals(getDataPrefix() + "URL")) {
225 // Do nothing
226 } else if (entry.getName().equals(getDataPrefix() + "SUMMARY")) {
227 // Do nothing
228 } else {
229 // Hopefully the data file
230 IOUtils.write(zipIn, tmp);
231 }
232 }
233 }
234
235 if (requireInfo() && (!tmp.exists() || !tmpInfo.exists())) {
236 throw new IOException(
237 "file not supported (maybe not created with this program or corrupt)");
238 }
239
240 if (tmp.exists()) {
241 this.in = new MarkableFileInputStream(new FileInputStream(tmp));
242 }
243 }
244
245 @Override
246 protected void close() throws IOException {
247 for (File file : new File[] { tmp, tmpInfo, tmpCover }) {
248 if (file != null && file.exists()) {
249 if (!file.delete()) {
250 file.deleteOnExit();
251 }
252 }
253 }
254
255 tmp = null;
256 tmpInfo = null;
257 tmpCover = null;
258 fakeSource = null;
259
260 try {
261 if (in != null) {
262 in.close();
263 }
264 } finally {
265 in = null;
266 base.close();
267 }
268 }
269
270 protected String getDataPrefix() {
271 return "DATA/";
272 }
273
274 protected boolean requireInfo() {
275 return true;
276 }
277
278 protected boolean getCover() {
279 return true;
280 }
281
282 /**
283 * Reset then return {@link Epub#in}.
284 *
285 * @return {@link Epub#in}
286 *
287 * @throws IOException
288 * in case of I/O error
289 */
290 private InputStream getFakeInput() throws IOException {
291 in.reset();
292 return in;
293 }
294}