do not allow empty cover images
[fanfix.git] / src / be / nikiroo / fanfix / supported / Cbz.java
index 7113248ba485fb4b91ad06f5b614cd49f1b7a3c7..a5391d07575e9f6102ab531e4a756c1be718f711 100644 (file)
@@ -1,23 +1,28 @@
 package be.nikiroo.fanfix.supported;
 
-import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
-import javax.imageio.ImageIO;
-
 import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.bundles.Config;
 import be.nikiroo.fanfix.data.Chapter;
+import be.nikiroo.fanfix.data.MetaData;
 import be.nikiroo.fanfix.data.Paragraph;
+import be.nikiroo.fanfix.data.Paragraph.ParagraphType;
 import be.nikiroo.fanfix.data.Story;
+import be.nikiroo.utils.IOUtils;
+import be.nikiroo.utils.Image;
 import be.nikiroo.utils.Progress;
+import be.nikiroo.utils.streams.MarkableFileInputStream;
 
 /**
  * Support class for CBZ files (works better with CBZ created with this program,
@@ -31,11 +36,6 @@ class Cbz extends Epub {
                return url.toString().toLowerCase().endsWith(".cbz");
        }
 
-       @Override
-       public String getSourceName() {
-               return "cbz";
-       }
-
        @Override
        protected String getDataPrefix() {
                return "";
@@ -47,84 +47,182 @@ class Cbz extends Epub {
        }
 
        @Override
-       protected boolean getCover() {
-               return false;
+       protected boolean isImagesDocumentByDefault() {
+               return true;
        }
 
        @Override
-       protected void preprocess(URL source, InputStream in) throws IOException {
-               super.preprocess(source, in);
-               meta.setImageDocument(true);
+       protected boolean getCover() {
+               return false;
        }
 
        @Override
-       public Story process(URL url, Progress pg) throws IOException {
+       public Story doProcess(Progress pg) throws IOException {
                if (pg == null) {
                        pg = new Progress();
                } else {
                        pg.setMinMax(0, 100);
                }
+               
+               pg.setName("Initialising");
+
+               Progress pgMeta = new Progress();
+               pg.addProgress(pgMeta, 10);
+               Story story = processMeta(true, pgMeta);
+               MetaData meta = story.getMeta();
+
+               pgMeta.done(); // 10%
+               
+               File tmpDir = Instance.getInstance().getTempFiles().createTempDir("info-text");
+               String basename = null;
+
+               Map<String, Image> images = new HashMap<String, Image>();
+               InputStream cbzIn = null;
+               ZipInputStream zipIn = null;
+               try {
+                       cbzIn = new MarkableFileInputStream(getSourceFileOriginal());
+                       zipIn = new ZipInputStream(cbzIn);
+                       for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
+                                       .getNextEntry()) {
+                               if (!entry.isDirectory()
+                                               && entry.getName().startsWith(getDataPrefix())) {
+                                       String entryLName = entry.getName().toLowerCase();
+                                       boolean imageEntry = false;
+                                       for (String ext : bsImages.getImageExt(false)) {
+                                               if (entryLName.endsWith(ext)) {
+                                                       imageEntry = true;
+                                               }
+                                       }
+                                       
+                                       if (imageEntry) {
+                                               String uuid = meta.getUuid() + "_" + entry.getName();
+                                               try {
+                                                       Image img = new Image(zipIn);
+                                                       if (img.getSize() == 0) {
+                                                               img.close();
+                                                               throw new IOException(
+                                                                               "Empty image not accepted");
+                                                       }
+                                                       images.put(uuid, img);
+                                               } catch (Exception e) {
+                                                       Instance.getInstance().getTraceHandler().error(e);
+                                               }
+
+                                               if (pg.getProgress() < 85) {
+                                                       pg.add(1);
+                                               }
+                                       } else if (entryLName.endsWith(".info")) {
+                                               basename = entryLName.substring(0, entryLName.length()
+                                                               - ".info".length());
+                                               IOUtils.write(zipIn, new File(tmpDir, entryLName));
+                                       } else if (entryLName.endsWith(".txt")) {
+                                               IOUtils.write(zipIn, new File(tmpDir, entryLName));
+                                       }
+                               }
+                       }
+                       
+                       String ext = "."
+                                       + Instance.getInstance().getConfig().getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER).toLowerCase();
+                       String coverName = meta.getUuid() + "_" + basename + ext;
+                       Image cover = images.get(coverName);
+                       images.remove(coverName);
+
+                       pg.setProgress(85);
+
+                       // ZIP order is not correct for us
+                       List<String> imagesList = new ArrayList<String>(images.keySet());
+                       Collections.sort(imagesList);
+
+                       pg.setProgress(90);
+
+                       // only the description/cover is kept
+                       Story origStory = getStoryFromTxt(tmpDir, basename);
+                       if (origStory != null) {
+                               if (origStory.getMeta().getCover() == null) {
+                                       origStory.getMeta().setCover(story.getMeta().getCover());
+                               }
+                               story.setMeta(origStory.getMeta());
+                       }
+                       if (story.getMeta().getCover() == null) {
+                               story.getMeta().setCover(cover);
+                       }
+                       story.setChapters(new ArrayList<Chapter>());
+
+                       // Check if we can find non-images chapters, for hybrid-cbz support
+                       if (origStory != null) {
+                               for (Chapter chap : origStory) {
+                                       Boolean isImages = null;
+                                       for (Paragraph para : chap) {
+                                               ParagraphType t = para.getType();
+                                               if (isImages == null && !t.isText(true)) {
+                                                       isImages = true;
+                                               }
+                                               if (t.isText(false)) {
+                                                       String line = para.getContent();
+                                                       // Images are saved in text mode as "[image-link]"
+                                                       if (!(line.startsWith("[") && line.endsWith("]"))) {
+                                                               isImages = false;
+                                                       }
+                                               }
+                                       }
 
-               Story story = processMeta(url, false, true);
-               story.setChapters(new ArrayList<Chapter>());
-               Chapter chap = new Chapter(1, null);
-               story.getChapters().add(chap);
-
-               ZipInputStream zipIn = new ZipInputStream(getInput());
-
-               pg.setProgress(10);
-               List<String> images = new ArrayList<String>();
-               for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
-                               .getNextEntry()) {
-                       if (!entry.isDirectory()
-                                       && entry.getName().startsWith(getDataPrefix())) {
-                               String entryLName = entry.getName().toLowerCase();
-                               boolean imageEntry = false;
-                               for (String ext : getImageExt(false)) {
-                                       if (entryLName.endsWith(ext)) {
-                                               imageEntry = true;
+                                       if (isImages != null && !isImages) {
+                                               story.getChapters().add(chap);
+                                               chap.setNumber(story.getChapters().size());
                                        }
                                }
+                       }
+
+                       if (!imagesList.isEmpty()) {
+                               Chapter chap = new Chapter(story.getChapters().size() + 1, "");
+                               story.getChapters().add(chap);
 
-                               if (imageEntry) {
-                                       String uuid = meta.getUuid() + "_" + entry.getName();
+                               for (String uuid : imagesList) {
                                        try {
-                                               File tmp = Instance.getCache().addToCache(zipIn, uuid);
-                                               images.add(tmp.toURI().toURL().toString());
+                                               chap.getParagraphs().add(
+                                                               new Paragraph(images.get(uuid)));
                                        } catch (Exception e) {
-                                               Instance.syserr(e);
+                                               Instance.getInstance().getTraceHandler().error(e);
                                        }
                                }
                        }
+
+                       if (meta.getCover() == null && !images.isEmpty()) {
+                               meta.setCover(images.get(imagesList.get(0)));
+                               meta.setFakeCover(true);
+                       }
+               } finally {
+                       IOUtils.deltree(tmpDir);
+                       if (zipIn != null) {
+                               zipIn.close();
+                       }
+                       if (cbzIn != null) {
+                               cbzIn.close();
+                       }
                }
 
-               pg.setProgress(80);
+               pg.done();
+               return story;
+       }
 
-               // ZIP order is not correct for us
-               Collections.sort(images);
-               pg.setProgress(90);
+       private Story getStoryFromTxt(File tmpDir, String basename) {
+               Story origStory = null;
 
-               for (String uuid : images) {
+               File txt = new File(tmpDir, basename + ".txt");
+               if (!txt.exists()) {
+                       basename = null;
+               }
+               if (basename != null) {
                        try {
-                               chap.getParagraphs().add(new Paragraph(new URL(uuid)));
+                               BasicSupport support = BasicSupport.getSupport(txt.toURI()
+                                               .toURL());
+                               origStory = support.process(null);
                        } catch (Exception e) {
-                               Instance.syserr(e);
+                               basename = null;
                        }
                }
 
-               if (meta.getCover() == null && !images.isEmpty()) {
-                       InputStream in = Instance.getCache().open(new URL(images.get(0)),
-                                       this, true);
-                       try {
-                               BufferedImage fcover = ImageIO.read(in);
-                               meta.setCover(fcover);
-                               meta.setFakeCover(true);
-                       } finally {
-                               in.close();
-                       }
-               }
+               return origStory;
 
-               pg.setProgress(100);
-               return story;
        }
 }