back to dev
[fanfix.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();
091397cb 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
091397cb 129 // only the description is kept, we do not support hybrid CBZ
298d405a
NR
130 Story origStory = getStoryFromTxt(tmpDir, basename);
131 if (origStory != null) {
27694a13
NR
132 if (origStory.getMeta().getCover() == null) {
133 origStory.getMeta().setCover(story.getMeta().getCover());
134 }
298d405a 135 story.setMeta(origStory.getMeta());
2aac79c7 136 }
091397cb 137 story.setChapters(new ArrayList<Chapter>());
92fb0719 138
2aac79c7
NR
139 if (!imagesList.isEmpty()) {
140 Chapter chap = new Chapter(story.getChapters().size() + 1, null);
141 story.getChapters().add(chap);
2a25f781 142
2aac79c7
NR
143 for (String uuid : imagesList) {
144 try {
145 chap.getParagraphs().add(
146 new Paragraph(images.get(uuid)));
147 } catch (Exception e) {
148 Instance.getTraceHandler().error(e);
149 }
150 }
151 }
d3c84ac3 152
2aac79c7
NR
153 if (meta.getCover() == null && !images.isEmpty()) {
154 meta.setCover(images.get(imagesList.get(0)));
155 meta.setFakeCover(true);
d3c84ac3 156 }
2aac79c7
NR
157 } finally {
158 IOUtils.deltree(tmpDir);
298d405a
NR
159 if (zipIn != null) {
160 zipIn.close();
161 }
162 if (cbzIn != null) {
163 cbzIn.close();
164 }
a9eb3f46
NR
165 }
166
92fb0719 167 pg.setProgress(100);
08fe2e33
NR
168 return story;
169 }
298d405a
NR
170
171 private Story getStoryFromTxt(File tmpDir, String basename) {
172 Story origStory = null;
173
174 File txt = new File(tmpDir, basename + ".txt");
175 if (!txt.exists()) {
176 basename = null;
177 }
178 if (basename != null) {
179 try {
180 BasicSupport support = BasicSupport.getSupport(txt.toURI()
181 .toURL());
182 origStory = support.process(null);
183 } catch (Exception e) {
184 basename = null;
185 }
186 }
187
188 return origStory;
189
190 }
08fe2e33 191}