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