Fixes:
[fanfix.git] / src / be / nikiroo / fanfix / supported / Cbz.java
1 package be.nikiroo.fanfix.supported;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.zip.ZipEntry;
14 import java.util.zip.ZipInputStream;
15
16 import be.nikiroo.fanfix.Instance;
17 import be.nikiroo.fanfix.data.Chapter;
18 import be.nikiroo.fanfix.data.MetaData;
19 import be.nikiroo.fanfix.data.Paragraph;
20 import be.nikiroo.fanfix.data.Story;
21 import be.nikiroo.utils.IOUtils;
22 import be.nikiroo.utils.Image;
23 import be.nikiroo.utils.MarkableFileInputStream;
24 import be.nikiroo.utils.Progress;
25
26 /**
27 * Support class for CBZ files (works better with CBZ created with this program,
28 * as they have some metadata available).
29 *
30 * @author niki
31 */
32 class Cbz extends Epub {
33 @Override
34 protected boolean supports(URL url) {
35 return url.toString().toLowerCase().endsWith(".cbz");
36 }
37
38 @Override
39 public String getSourceName() {
40 return "cbz";
41 }
42
43 @Override
44 protected String getDataPrefix() {
45 return "";
46 }
47
48 @Override
49 protected boolean requireInfo() {
50 return false;
51 }
52
53 @Override
54 protected boolean isImagesDocumentByDefault() {
55 return true;
56 }
57
58 @Override
59 protected boolean getCover() {
60 return false;
61 }
62
63 @Override
64 public Story doProcess(Progress pg) throws IOException {
65 if (pg == null) {
66 pg = new Progress();
67 } else {
68 pg.setMinMax(0, 100);
69 }
70
71 Progress pgMeta = new Progress();
72 pg.addProgress(pgMeta, 10);
73 Story story = processMeta(true, pgMeta);
74 MetaData meta = story.getMeta();
75
76 pgMeta.done(); // 10%
77
78 File tmpDir = Instance.getTempFiles().createTempDir("info-text");
79 String basename = null;
80
81 Map<String, Image> images = new HashMap<String, Image>();
82 InputStream cbzIn = null;
83 ZipInputStream zipIn = null;
84 try {
85 cbzIn = new MarkableFileInputStream(new FileInputStream(
86 getSourceFileOriginal()));
87 zipIn = new ZipInputStream(cbzIn);
88 for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
89 .getNextEntry()) {
90 if (!entry.isDirectory()
91 && entry.getName().startsWith(getDataPrefix())) {
92 String entryLName = entry.getName().toLowerCase();
93 boolean imageEntry = false;
94 for (String ext : BasicSupportImages.getImageExt(false)) {
95 if (entryLName.endsWith(ext)) {
96 imageEntry = true;
97 }
98 }
99
100 if (imageEntry) {
101 String uuid = meta.getUuid() + "_" + entry.getName();
102 try {
103 images.put(uuid, new Image(zipIn));
104 } catch (Exception e) {
105 Instance.getTraceHandler().error(e);
106 }
107
108 if (pg.getProgress() < 85) {
109 pg.add(1);
110 }
111 } else if (entryLName.endsWith(".info")) {
112 basename = entryLName.substring(0, entryLName.length()
113 - ".info".length());
114 IOUtils.write(zipIn, new File(tmpDir, entryLName));
115 } else if (entryLName.endsWith(".txt")) {
116 IOUtils.write(zipIn, new File(tmpDir, entryLName));
117 }
118 }
119 }
120
121 pg.setProgress(85);
122
123 // ZIP order is not correct for us
124 List<String> imagesList = new ArrayList<String>(images.keySet());
125 Collections.sort(imagesList);
126
127 pg.setProgress(90);
128
129 // include original story
130 Story origStory = getStoryFromTxt(tmpDir, basename);
131 if (origStory != null) {
132 story.setChapters(origStory.getChapters());
133 if (origStory.getMeta().getCover() == null) {
134 origStory.getMeta().setCover(story.getMeta().getCover());
135 }
136 story.setMeta(origStory.getMeta());
137 } else {
138 story.setChapters(new ArrayList<Chapter>());
139 }
140
141 if (!imagesList.isEmpty()) {
142 Chapter chap = new Chapter(story.getChapters().size() + 1, null);
143 story.getChapters().add(chap);
144
145 for (String uuid : imagesList) {
146 try {
147 chap.getParagraphs().add(
148 new Paragraph(images.get(uuid)));
149 } catch (Exception e) {
150 Instance.getTraceHandler().error(e);
151 }
152 }
153 }
154
155 if (meta.getCover() == null && !images.isEmpty()) {
156 meta.setCover(images.get(imagesList.get(0)));
157 meta.setFakeCover(true);
158 }
159 } finally {
160 IOUtils.deltree(tmpDir);
161 if (zipIn != null) {
162 zipIn.close();
163 }
164 if (cbzIn != null) {
165 cbzIn.close();
166 }
167 }
168
169 pg.setProgress(100);
170 return story;
171 }
172
173 private Story getStoryFromTxt(File tmpDir, String basename) {
174 Story origStory = null;
175
176 File txt = new File(tmpDir, basename + ".txt");
177 if (!txt.exists()) {
178 basename = null;
179 }
180 if (basename != null) {
181 try {
182 BasicSupport support = BasicSupport.getSupport(txt.toURI()
183 .toURL());
184 origStory = support.process(null);
185 } catch (Exception e) {
186 basename = null;
187 }
188 }
189
190 return origStory;
191
192 }
193 }