update chanelog
[nikiroo-utils.git] / src / be / nikiroo / fanfix / supported / Cbz.java
CommitLineData
08fe2e33
NR
1package be.nikiroo.fanfix.supported;
2
2aac79c7 3import java.io.File;
298d405a 4import java.io.FileInputStream;
08fe2e33 5import java.io.IOException;
298d405a 6import java.io.InputStream;
08fe2e33
NR
7import java.net.URL;
8import java.util.ArrayList;
d3c84ac3 9import java.util.Collections;
2a25f781 10import java.util.HashMap;
d3c84ac3 11import java.util.List;
2a25f781 12import java.util.Map;
08fe2e33
NR
13import java.util.zip.ZipEntry;
14import java.util.zip.ZipInputStream;
15
16import be.nikiroo.fanfix.Instance;
17import be.nikiroo.fanfix.data.Chapter;
7445f856 18import be.nikiroo.fanfix.data.MetaData;
08fe2e33
NR
19import be.nikiroo.fanfix.data.Paragraph;
20import be.nikiroo.fanfix.data.Story;
2aac79c7 21import be.nikiroo.utils.IOUtils;
16a81ef7 22import be.nikiroo.utils.Image;
298d405a 23import be.nikiroo.utils.MarkableFileInputStream;
3b2b638f 24import be.nikiroo.utils.Progress;
08fe2e33
NR
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 */
32class 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 }
08fe2e33
NR
52
53 @Override
e4fa48a0
NR
54 protected boolean isImagesDocumentByDefault() {
55 return true;
08fe2e33
NR
56 }
57
68686a37 58 @Override
e4fa48a0
NR
59 protected boolean getCover() {
60 return false;
68686a37
NR
61 }
62
08fe2e33 63 @Override
9005532f 64 public Story doProcess(Progress pg) throws IOException {
92fb0719
NR
65 if (pg == null) {
66 pg = new Progress();
67 } else {
68 pg.setMinMax(0, 100);
69 }
70
ed08c171
NR
71 Progress pgMeta = new Progress();
72 pg.addProgress(pgMeta, 10);
7445f856
NR
73 Story story = processMeta(true, pgMeta);
74 MetaData meta = story.getMeta();
27694a13 75
2a25f781 76 pgMeta.done(); // 10%
ed08c171 77
2aac79c7
NR
78 File tmpDir = Instance.getTempFiles().createTempDir("info-text");
79 String basename = null;
08fe2e33 80
16a81ef7 81 Map<String, Image> images = new HashMap<String, Image>();
298d405a
NR
82 InputStream cbzIn = null;
83 ZipInputStream zipIn = null;
2aac79c7 84 try {
298d405a
NR
85 cbzIn = new MarkableFileInputStream(new FileInputStream(
86 getSourceFileOriginal()));
87 zipIn = new ZipInputStream(cbzIn);
2aac79c7
NR
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;
7445f856 94 for (String ext : BasicSupportImages.getImageExt(false)) {
2aac79c7
NR
95 if (entryLName.endsWith(ext)) {
96 imageEntry = true;
97 }
08fe2e33 98 }
08fe2e33 99
2aac79c7
NR
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));
08fe2e33 117 }
2aac79c7
NR
118 }
119 }
2a25f781 120
2aac79c7
NR
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
298d405a
NR
129 // include original story
130 Story origStory = getStoryFromTxt(tmpDir, basename);
131 if (origStory != null) {
132 story.setChapters(origStory.getChapters());
27694a13
NR
133 if (origStory.getMeta().getCover() == null) {
134 origStory.getMeta().setCover(story.getMeta().getCover());
135 }
298d405a
NR
136 story.setMeta(origStory.getMeta());
137 } else {
2aac79c7
NR
138 story.setChapters(new ArrayList<Chapter>());
139 }
92fb0719 140
2aac79c7
NR
141 if (!imagesList.isEmpty()) {
142 Chapter chap = new Chapter(story.getChapters().size() + 1, null);
143 story.getChapters().add(chap);
2a25f781 144
2aac79c7
NR
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 }
d3c84ac3 154
2aac79c7
NR
155 if (meta.getCover() == null && !images.isEmpty()) {
156 meta.setCover(images.get(imagesList.get(0)));
157 meta.setFakeCover(true);
d3c84ac3 158 }
2aac79c7
NR
159 } finally {
160 IOUtils.deltree(tmpDir);
298d405a
NR
161 if (zipIn != null) {
162 zipIn.close();
163 }
164 if (cbzIn != null) {
165 cbzIn.close();
166 }
a9eb3f46
NR
167 }
168
92fb0719 169 pg.setProgress(100);
08fe2e33
NR
170 return story;
171 }
298d405a
NR
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 }
08fe2e33 193}