Improve importing progress reporting
[fanfix.git] / src / be / nikiroo / fanfix / supported / Epub.java
1 package be.nikiroo.fanfix.supported;
2
3 import java.awt.image.BufferedImage;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.net.URL;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.Map.Entry;
12 import java.util.zip.ZipEntry;
13 import java.util.zip.ZipInputStream;
14
15 import be.nikiroo.fanfix.Instance;
16 import be.nikiroo.fanfix.data.MetaData;
17 import be.nikiroo.utils.IOUtils;
18 import be.nikiroo.utils.MarkableFileInputStream;
19 import be.nikiroo.utils.Progress;
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 */
27 class Epub extends InfoText {
28 private File tmp;
29 protected MetaData meta;
30
31 private URL fakeSource;
32 private InputStream fakeIn;
33
34 @Override
35 public String getSourceName() {
36 return "epub";
37 }
38
39 @Override
40 protected boolean supports(URL url) {
41 if (url.getPath().toLowerCase().endsWith(".epub")) {
42 return true;
43 }
44
45 return false;
46 }
47
48 @Override
49 protected MetaData getMeta(URL source, InputStream in) throws IOException {
50 return meta;
51 }
52
53 @Override
54 protected String getDesc(URL source, InputStream in) throws IOException {
55 if (fakeIn != null) {
56 fakeIn.reset();
57 return super.getDesc(fakeSource, fakeIn);
58 }
59
60 return null;
61 }
62
63 @Override
64 protected List<Entry<String, URL>> getChapters(URL source, InputStream in,
65 Progress pg) throws IOException {
66 if (fakeIn != null) {
67 fakeIn.reset();
68 return super.getChapters(fakeSource, fakeIn, pg);
69 }
70
71 return null;
72 }
73
74 @Override
75 protected String getChapterContent(URL source, InputStream in, int number,
76 Progress pg) throws IOException {
77 if (fakeIn != null) {
78 fakeIn.reset();
79 return super.getChapterContent(fakeSource, fakeIn, number, pg);
80 }
81
82 return null;
83 }
84
85 @Override
86 protected void preprocess(URL source, InputStream in) throws IOException {
87 // Note: do NOT close this stream, as it would also close "in"
88 ZipInputStream zipIn = new ZipInputStream(in);
89 tmp = File.createTempFile("fanfic-reader-parser_", ".tmp");
90 File tmpInfo = new File(tmp + ".info");
91 fakeSource = tmp.toURI().toURL();
92 BufferedImage cover = null;
93
94 for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
95 .getNextEntry()) {
96 if (!entry.isDirectory()
97 && entry.getName().startsWith(getDataPrefix())) {
98 String entryLName = entry.getName().toLowerCase();
99
100 boolean imageEntry = false;
101 for (String ext : getImageExt(false)) {
102 if (entryLName.endsWith(ext)) {
103 imageEntry = true;
104 }
105 }
106
107 if (entry.getName().equals(getDataPrefix() + "version")) {
108 // Nothing to do for now ("first"
109 // version is 3.0)
110 } else if (entryLName.endsWith(".info")) {
111 // Info file
112 IOUtils.write(zipIn, tmpInfo);
113 } else if (imageEntry) {
114 // Cover
115 if (getCover()) {
116 try {
117 cover = IOUtils.toImage(zipIn);
118 } catch (Exception e) {
119 Instance.syserr(e);
120 }
121 }
122 } else if (entry.getName().equals(getDataPrefix() + "URL")) {
123 // Do nothing
124 } else if (entry.getName().equals(getDataPrefix() + "SUMMARY")) {
125 // Do nothing
126 } else {
127 // Hopefully the data file
128 IOUtils.write(zipIn, tmp);
129 }
130 }
131 }
132
133 if (requireInfo() && (!tmp.exists() || !tmpInfo.exists())) {
134 throw new IOException(
135 "file not supported (maybe not created with this program or corrupt)");
136 }
137
138 if (tmp.exists()) {
139 this.fakeIn = new MarkableFileInputStream(new FileInputStream(tmp));
140 }
141
142 if (tmpInfo.exists()) {
143 meta = InfoReader.readMeta(tmpInfo);
144 if (cover != null) {
145 meta.setCover(cover);
146 }
147 tmpInfo.delete();
148 } else {
149 meta = new MetaData();
150 meta.setUuid(source.toString());
151 meta.setLang("EN");
152 meta.setTags(new ArrayList<String>());
153 meta.setSource(getSourceName());
154 meta.setUrl(source.toString());
155 }
156 }
157
158 @Override
159 protected void close() throws IOException {
160 if (tmp != null && tmp.exists()) {
161 if (!tmp.delete()) {
162 tmp.deleteOnExit();
163 }
164 }
165
166 tmp = null;
167
168 fakeIn.close();
169 super.close();
170 }
171
172 protected String getDataPrefix() {
173 return "DATA/";
174 }
175
176 protected boolean requireInfo() {
177 return true;
178 }
179
180 protected boolean getCover() {
181 return true;
182 }
183 }