fix typo in Enum i18n + fix Import
[fanfix.git] / src / be / nikiroo / fanfix / supported / Epub.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix.supported;
2
08fe2e33
NR
3import java.io.File;
4import java.io.FileInputStream;
5import java.io.IOException;
6import java.io.InputStream;
7445f856 7import java.net.URISyntaxException;
08fe2e33 8import java.net.URL;
778d8d85 9import java.net.URLDecoder;
68686a37 10import java.util.ArrayList;
08fe2e33
NR
11import java.util.zip.ZipEntry;
12import java.util.zip.ZipInputStream;
13
7445f856
NR
14import org.jsoup.nodes.Document;
15
08fe2e33 16import be.nikiroo.fanfix.Instance;
68686a37 17import be.nikiroo.fanfix.data.MetaData;
08fe2e33 18import be.nikiroo.utils.IOUtils;
16a81ef7 19import be.nikiroo.utils.Image;
67837328 20import be.nikiroo.utils.streams.MarkableFileInputStream;
b7afbe42 21import be.nikiroo.utils.StringUtils;
08fe2e33
NR
22
23/**
24 * Support class for EPUB files created with this program (as we need some
25 * metadata available in those we create).
26 *
27 * @author niki
28 */
68686a37 29class Epub extends InfoText {
7445f856 30 private MetaData meta;
2aac79c7 31 private File tmpDir;
b7afbe42 32 private String desc;
08fe2e33 33
68686a37
NR
34 private URL fakeSource;
35 private InputStream fakeIn;
08fe2e33 36
7445f856 37 public File getSourceFileOriginal() {
298d405a 38 return super.getSourceFile();
08fe2e33
NR
39 }
40
41 @Override
7445f856
NR
42 protected File getSourceFile() {
43 try {
44 return new File(fakeSource.toURI());
45 } catch (URISyntaxException e) {
46 Instance.getTraceHandler()
47 .error(new IOException(
48 "Cannot get the source file from the info-text URL",
49 e));
08fe2e33
NR
50 }
51
52 return null;
53 }
54
55 @Override
7445f856 56 protected InputStream getInput() {
298d405a
NR
57 if (fakeIn != null) {
58 try {
59 fakeIn.reset();
60 } catch (IOException e) {
61 Instance.getTraceHandler()
62 .error(new IOException(
63 "Cannot reset the Epub Text stream", e));
64 }
65
66 return fakeIn;
67 }
68
69 return null;
08fe2e33
NR
70 }
71
72 @Override
7445f856
NR
73 protected boolean supports(URL url) {
74 return url.getPath().toLowerCase().endsWith(".epub");
75 }
08fe2e33 76
7445f856
NR
77 @Override
78 protected MetaData getMeta() throws IOException {
79 return meta;
08fe2e33
NR
80 }
81
82 @Override
7445f856
NR
83 protected Document loadDocument(URL source) throws IOException {
84 super.loadDocument(source); // prepares super.getSourceFile() and
85 // super.getInput()
86
87 InputStream in = super.getInput();
88 ZipInputStream zipIn = null;
89 try {
90 zipIn = new ZipInputStream(in);
91 tmpDir = Instance.getTempFiles().createTempDir(
92 "fanfic-reader-parser");
93 File tmp = new File(tmpDir, "file.txt");
94 File tmpInfo = new File(tmpDir, "file.info");
95
96 fakeSource = tmp.toURI().toURL();
97 Image cover = null;
98
99 String url;
100 try {
101 url = getSource().toURI().toURL().toString();
102 } catch (URISyntaxException e1) {
103 url = getSource().toString();
104 }
105 String title = null;
106 String author = null;
107
108 for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
109 .getNextEntry()) {
110 if (!entry.isDirectory()
111 && entry.getName().startsWith(getDataPrefix())) {
112 String entryLName = entry.getName().toLowerCase();
113
114 boolean imageEntry = false;
115 for (String ext : BasicSupportImages.getImageExt(false)) {
116 if (entryLName.endsWith(ext)) {
117 imageEntry = true;
118 }
08fe2e33 119 }
08fe2e33 120
7445f856
NR
121 if (entry.getName().equals(getDataPrefix() + "version")) {
122 // Nothing to do for now ("first"
123 // version is 3.0)
124 } else if (entryLName.endsWith(".info")) {
125 // Info file
126 IOUtils.write(zipIn, tmpInfo);
127 } else if (imageEntry) {
128 // Cover
129 if (getCover()) {
130 try {
131 cover = new Image(zipIn);
132 } catch (Exception e) {
133 Instance.getTraceHandler().error(e);
134 }
08fe2e33 135 }
7445f856
NR
136 } else if (entry.getName().equals(getDataPrefix() + "URL")) {
137 String[] descArray = StringUtils
138 .unhtml(IOUtils.readSmallStream(zipIn)).trim()
139 .split("\n");
140 if (descArray.length > 0) {
141 url = descArray[0].trim();
142 }
143 } else if (entry.getName().equals(
144 getDataPrefix() + "SUMMARY")) {
145 String[] descArray = StringUtils
146 .unhtml(IOUtils.readSmallStream(zipIn)).trim()
147 .split("\n");
148 int skip = 0;
149 if (descArray.length > 1) {
150 title = descArray[0].trim();
151 skip = 1;
152 if (descArray.length > 2
153 && descArray[1].startsWith("©")) {
154 author = descArray[1].substring(1).trim();
155 skip = 2;
156 }
157 }
158 this.desc = "";
159 for (int i = skip; i < descArray.length; i++) {
160 this.desc += descArray[i].trim() + "\n";
b7afbe42 161 }
b7afbe42 162
7445f856
NR
163 this.desc = this.desc.trim();
164 } else {
165 // Hopefully the data file
166 IOUtils.write(zipIn, tmp);
167 }
08fe2e33
NR
168 }
169 }
08fe2e33 170
7445f856
NR
171 if (requireInfo() && (!tmp.exists() || !tmpInfo.exists())) {
172 throw new IOException(
173 "file not supported (maybe not created with this program or corrupt)");
174 }
68686a37 175
7445f856 176 if (tmp.exists()) {
67837328 177 this.fakeIn = new MarkableFileInputStream(tmp);
68686a37 178 }
7445f856
NR
179
180 if (tmpInfo.exists()) {
181 meta = InfoReader.readMeta(tmpInfo, true);
7445f856
NR
182 tmpInfo.delete();
183 } else {
184 if (title == null || title.isEmpty()) {
185 title = getSourceFileOriginal().getName();
186 if (title.toLowerCase().endsWith(".cbz")) {
187 title = title.substring(0, title.length() - 4);
188 }
189 title = URLDecoder.decode(title, "UTF-8").trim();
778d8d85 190 }
778d8d85 191
7445f856
NR
192 meta = new MetaData();
193 meta.setLang("en");
194 meta.setTags(new ArrayList<String>());
727108fe 195 meta.setSource(getType().getSourceName());
7445f856
NR
196 meta.setUuid(url);
197 meta.setUrl(url);
198 meta.setTitle(title);
199 meta.setAuthor(author);
200 meta.setImageDocument(isImagesDocumentByDefault());
201 }
bb7021f2
NR
202
203 if (meta.getCover() == null) {
204 if (cover != null) {
205 meta.setCover(cover);
206 } else {
bb7021f2
NR
207 meta.setCover(InfoReader
208 .getCoverByName(getSourceFileOriginal().toURI()
209 .toURL()));
210 }
211 }
7445f856
NR
212 } finally {
213 if (zipIn != null) {
214 zipIn.close();
215 }
216 if (in != null) {
217 in.close();
218 }
08fe2e33 219 }
7445f856
NR
220
221 return null;
08fe2e33
NR
222 }
223
224 @Override
0ffa4754 225 protected void close() {
2aac79c7
NR
226 if (tmpDir != null) {
227 IOUtils.deltree(tmpDir);
08fe2e33
NR
228 }
229
2aac79c7 230 tmpDir = null;
dea63313 231
68686a37 232 super.close();
08fe2e33
NR
233 }
234
235 protected String getDataPrefix() {
236 return "DATA/";
237 }
238
239 protected boolean requireInfo() {
240 return true;
241 }
242
243 protected boolean getCover() {
244 return true;
245 }
e4fa48a0
NR
246
247 protected boolean isImagesDocumentByDefault() {
248 return false;
249 }
08fe2e33 250}