Update nikiroo-utils, bugfixes:
authorNiki Roo <niki@nikiroo.be>
Wed, 29 Nov 2017 20:02:19 +0000 (21:02 +0100)
committerNiki Roo <niki@nikiroo.be>
Wed, 29 Nov 2017 20:02:19 +0000 (21:02 +0100)
- covers were sometimes not found (so not displayed or not deleted)
- images could fail to save in JPG mode (now, we retry in PNG)
- covers were not sent over the network (still need more tests)
- some tmp files were not deleted in case of an import failure

15 files changed:
changelog.md
libs/nikiroo-utils-3.1.2-sources.jar [moved from libs/nikiroo-utils-3.0.0-sources.jar with 80% similarity]
src/be/nikiroo/fanfix/DataLoader.java
src/be/nikiroo/fanfix/data/Paragraph.java
src/be/nikiroo/fanfix/library/LocalLibrary.java
src/be/nikiroo/fanfix/library/RemoteLibraryServer.java
src/be/nikiroo/fanfix/output/Cbz.java
src/be/nikiroo/fanfix/output/Epub.java
src/be/nikiroo/fanfix/output/Text.java
src/be/nikiroo/fanfix/supported/BasicSupport.java
src/be/nikiroo/fanfix/supported/Cbz.java
src/be/nikiroo/fanfix/supported/InfoReader.java
src/be/nikiroo/fanfix/test/BasicSupportTest.java
src/be/nikiroo/fanfix/test/LibraryTest.java
src/be/nikiroo/fanfix/test/Test.java

index d36c87f65d49bfae9c96b4e5c62d8c1f827fd025..410281270894b06b2be2d0b6d49bf3d5f6f532d3 100644 (file)
@@ -5,6 +5,9 @@
 - Bug fixes
 - Remote server/client improvements
 - Better support for some CBZ files (if SUMMARY or URL files are present in it)
+- Fix cover images not deleted on story delete
+- Fix some images not supported because not jpeg-able (now try again in png)
+- Fix some covers not found (normal and remote hopefully)
 
 ## Version 1.6.2
 
similarity index 80%
rename from libs/nikiroo-utils-3.0.0-sources.jar
rename to libs/nikiroo-utils-3.1.2-sources.jar
index 82feb00ed344bcc6ad54ea0ec897f03e8f454406..ec1ed6edf838b46b9fbb7d4c3eb3ab343690d42c 100644 (file)
Binary files a/libs/nikiroo-utils-3.0.0-sources.jar and b/libs/nikiroo-utils-3.1.2-sources.jar differ
index 2fd59d89764783cd9622fcc0249039dc012f1043..25300130116214d8202bc88e1acc83de98addf3d 100644 (file)
@@ -1,5 +1,6 @@
 package be.nikiroo.fanfix;
 
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -228,16 +229,48 @@ public class DataLoader {
        public void saveAsImage(URL url, File target) throws IOException {
                InputStream in = open(url, null, true);
                try {
-                       ImageIO.write(ImageUtils.fromStream(in), Instance.getConfig()
-                                       .getString(Config.IMAGE_FORMAT_CONTENT).toLowerCase(),
-                                       target);
-               } catch (IOException e) {
-                       throw new IOException("Cannot write image " + url, e);
+                       saveAsImage(ImageUtils.fromStream(in), target);
                } finally {
                        in.close();
                }
        }
 
+       /**
+        * Save the given resource as an image on disk using the default image
+        * format for content.
+        * 
+        * @param image
+        *            the resource
+        * @param target
+        *            the target file
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       public void saveAsImage(BufferedImage image, File target)
+                       throws IOException {
+               try {
+                       String format = Instance.getConfig()
+                                       .getString(Config.IMAGE_FORMAT_CONTENT).toLowerCase();
+                       boolean ok = ImageIO.write(image, format, target);
+                       if (!ok) {
+                               // Some formats are not reliable
+                               // Second change: PNG
+                               if (!format.equals("png")) {
+                                       ok = ImageIO.write(image, "png", target);
+                               }
+
+                               if (!ok) {
+                                       throw new IOException(
+                                                       "Cannot find a writer for this image and format: "
+                                                                       + format);
+                               }
+                       }
+               } catch (IOException e) {
+                       throw new IOException("Cannot write image to " + target, e);
+               }
+       }
+
        /**
         * Manually add this item to the cache.
         * 
index 273aca3af7884f4ed3de556b84837465b151015f..a731c328ce0a2ef4a0bc373689fe275c2abfb663 100644 (file)
@@ -1,6 +1,6 @@
 package be.nikiroo.fanfix.data;
 
-import java.net.URL;
+import java.awt.image.BufferedImage;
 
 /**
  * A paragraph in a chapter of the story.
@@ -28,6 +28,7 @@ public class Paragraph {
 
        private ParagraphType type;
        private String content;
+       private BufferedImage contentImage;
        private long words;
 
        /**
@@ -41,11 +42,12 @@ public class Paragraph {
        /**
         * Create a new {@link Paragraph} with the given image.
         * 
-        * @param imageUrl
-        *            the image as an URL
+        * @param contentImage
+        *            the image
         */
-       public Paragraph(URL imageUrl) {
-               this(ParagraphType.IMAGE, imageUrl.toString(), 1);
+       public Paragraph(BufferedImage contentImage) {
+               this(ParagraphType.IMAGE, null, 1);
+               this.contentImage = contentImage;
        }
 
        /**
@@ -84,7 +86,7 @@ public class Paragraph {
        }
 
        /**
-        * The content of this {@link Paragraph}.
+        * The content of this {@link Paragraph} if it is not an image.
         * 
         * @return the content
         */
@@ -102,6 +104,15 @@ public class Paragraph {
                this.content = content;
        }
 
+       /**
+        * The content of this {@link Paragraph} if it is an image.
+        * 
+        * @return the content
+        */
+       public BufferedImage getContentImage() {
+               return contentImage;
+       }
+
        /**
         * The number of words (or images) in this {@link Paragraph}.
         * 
index 917ce093b20ebd8b58cad71a37a75d263c173490..4c4542551410d06cbe9d9e074961214d64c48129 100644 (file)
@@ -383,7 +383,8 @@ public class LocalLibrary extends BasicLibrary {
                }
 
                String coverExt = "."
-                               + Instance.getConfig().getString(Config.IMAGE_FORMAT_COVER);
+                               + Instance.getConfig().getString(Config.IMAGE_FORMAT_COVER)
+                                               .toLowerCase();
                File coverFile = new File(path + coverExt);
                if (!coverFile.exists()) {
                        coverFile = new File(path.substring(0,
@@ -472,8 +473,10 @@ public class LocalLibrary extends BasicLibrary {
                                        } catch (IOException e) {
                                                // We should not have not-supported files in the
                                                // library
-                                               Instance.getTraceHandler().error(new IOException(
-                                                               "Cannot load file from library: " + infoFile, e));
+                                               Instance.getTraceHandler().error(
+                                                               new IOException(
+                                                                               "Cannot load file from library: "
+                                                                                               + infoFile, e));
                                        }
                                        pgFiles.add(1);
                                }
index 583629382662294b9e6fb7e1279cd6001c35dc02..b26899930bc35e806634536c57d4882d111e6332 100644 (file)
@@ -14,20 +14,23 @@ import be.nikiroo.utils.serial.server.ServerObject;
 /**
  * Create a new remote server that will listen for order on the given port.
  * <p>
- * The available commands are given as String arrays (first item is the key,
- * second is the command, the rest are the arguments):
+ * The available commands are given as arrays of objects (first item is the key,
+ * second is the command, the rest are the arguments).
+ * <p>
+ * The key is always a String, the commands are also Strings; the parameters
+ * vary depending upon the command.
  * <ul>
- * <li>KEY GET_METADATA *: will return the metadata of all the stories in the
+ * <li>[key] GET_METADATA *: will return the metadata of all the stories in the
  * library</li>
- * <li>KEY GET_STORY [luid]: will return the given story if it exists (or NULL
+ * <li>[key] GET_STORY [luid]: will return the given story if it exists (or NULL
  * if not)</li>
- * <li>KEY SAVE_STORY [story] [luid]: save the story with the given LUID</li>
- * <li>KEY DELETE_STORY [luid]: delete the story of LUID luid</li>
- * <li>KEY GET_COVER [luid]: return the cover of the story</li>
- * <li>KEY GET_SOURCE_COVER [source]: return the cover for this source</li>
- * <li>KEY SET_SOURCE_COVER [source], [luid]: set the default cover for the
+ * <li>[key] SAVE_STORY [story] [luid]: save the story with the given LUID</li>
+ * <li>[key] DELETE_STORY [luid]: delete the story of LUID luid</li>
+ * <li>[key] GET_COVER [luid]: return the cover of the story</li>
+ * <li>[key] GET_SOURCE_COVER [source]: return the cover for this source</li>
+ * <li>[key] SET_SOURCE_COVER [source], [luid]: set the default cover for the
  * given source to the cover of the story denoted by luid</li>
- * <li>KEY EXIT: stop the server</li>
+ * <li>[key] EXIT: stop the server</li>
  * </ul>
  * 
  * @author niki
index c350eb24d0f88716251551cd192164765c14c980..c70cc4123d3e05970d9a36ea29d0da089ecbb98c 100644 (file)
@@ -25,25 +25,27 @@ class Cbz extends BasicOutput {
                dir = File.createTempFile("fanfic-reader-cbz-dir", ".wip");
                dir.delete();
                dir.mkdir();
+               try {
+                       // will also save the images!
+                       new InfoText().process(story, dir, targetNameOrig);
 
-               // will also save the images!
-               new InfoText().process(story, dir, targetNameOrig);
+                       InfoCover.writeInfo(dir, targetNameOrig, story.getMeta());
+                       if (story.getMeta() != null && !story.getMeta().isFakeCover()) {
+                               InfoCover.writeCover(dir, targetNameOrig, story.getMeta());
+                       }
 
-               InfoCover.writeInfo(dir, targetNameOrig, story.getMeta());
-               if (story.getMeta() != null && !story.getMeta().isFakeCover()) {
-                       InfoCover.writeCover(dir, targetNameOrig, story.getMeta());
-               }
+                       IOUtils.writeSmallFile(dir, "version", "3.0");
 
-               IOUtils.writeSmallFile(dir, "version", "3.0");
+                       try {
+                               super.process(story, targetDir, targetNameOrig);
+                       } finally {
+                       }
 
-               try {
-                       super.process(story, targetDir, targetNameOrig);
+                       IOUtils.zip(dir, target, true);
                } finally {
+                       IOUtils.deltree(dir);
                }
 
-               IOUtils.zip(dir, target, true);
-               IOUtils.deltree(dir);
-
                return target;
        }
 
index 869a0bc2647f3e7642ee458faf389684ed48186b..2c47dcbcad68c5d12c2626f22b0771a867eabcd3 100644 (file)
@@ -6,7 +6,6 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
-import java.net.URL;
 
 import javax.imageio.ImageIO;
 
@@ -209,7 +208,7 @@ class Epub extends BasicOutput {
                        break;
                case IMAGE:
                        File file = new File(images, getCurrentImageBestName(false));
-                       Instance.getCache().saveAsImage(new URL(para.getContent()), file);
+                       Instance.getCache().saveAsImage(para.getContentImage(), file);
                        writer.write("                  <img class='page-image' src='images/"
                                        + getCurrentImageBestName(false) + "'/>");
                        break;
index 28f3894b78b3b23f0d25c052006c3c7d0158d32a..ee72385b32220c479e1e03ad2d8a378f59539e49 100644 (file)
@@ -5,7 +5,6 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.net.URL;
 
 import be.nikiroo.fanfix.Instance;
 import be.nikiroo.fanfix.bundles.StringId;
@@ -105,7 +104,7 @@ class Text extends BasicOutput {
        protected void writeParagraphHeader(Paragraph para) throws IOException {
                if (para.getType() == ParagraphType.IMAGE) {
                        File file = new File(targetDir, getCurrentImageBestName(true));
-                       Instance.getCache().saveAsImage(new URL(para.getContent()), file);
+                       Instance.getCache().saveAsImage(para.getContentImage(), file);
                }
        }
 
index ae7521ef279dc0dc025cc9eb399260fdc59825a1..c609c70324dd665313cc07b1de4eaa91ccb48060 100644 (file)
@@ -757,10 +757,10 @@ public abstract class BasicSupport {
         * @return the {@link Paragraph}
         */
        private Paragraph makeParagraph(URL source, String line) {
-               URL image = null;
+               BufferedImage image = null;
                if (line.startsWith("[") && line.endsWith("]")) {
-                       image = getImageUrl(this, source,
-                                       line.substring(1, line.length() - 1).trim());
+                       image = getImage(this, source, line.substring(1, line.length() - 1)
+                                       .trim());
                }
 
                if (image != null) {
index 02c667c1032be681186b4e786907243c046eafd9..f67f28ae6f936af9235305b8c568e4ad8ed7310f 100644 (file)
@@ -1,22 +1,22 @@
 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.data.Chapter;
 import be.nikiroo.fanfix.data.Paragraph;
 import be.nikiroo.fanfix.data.Story;
+import be.nikiroo.utils.ImageUtils;
 import be.nikiroo.utils.Progress;
 
 /**
@@ -68,9 +68,7 @@ class Cbz extends Epub {
                Progress pgMeta = new Progress();
                pg.addProgress(pgMeta, 10);
                Story story = processMeta(url, false, true, pgMeta);
-               if (!pgMeta.isDone()) {
-                       pgMeta.setProgress(pgMeta.getMax()); // 10%
-               }
+               pgMeta.done(); // 10%
 
                story.setChapters(new ArrayList<Chapter>());
                Chapter chap = new Chapter(1, null);
@@ -78,7 +76,7 @@ class Cbz extends Epub {
 
                ZipInputStream zipIn = new ZipInputStream(getInput());
 
-               List<String> images = new ArrayList<String>();
+               Map<String, BufferedImage> images = new HashMap<String, BufferedImage>();
                for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
                                .getNextEntry()) {
                        if (!entry.isDirectory()
@@ -94,39 +92,36 @@ class Cbz extends Epub {
                                if (imageEntry) {
                                        String uuid = meta.getUuid() + "_" + entry.getName();
                                        try {
-                                               File tmp = Instance.getCache().addToCache(zipIn, uuid);
-                                               images.add(tmp.toURI().toURL().toString());
+                                               images.put(uuid, ImageUtils.fromStream(zipIn));
                                        } catch (Exception e) {
                                                Instance.getTraceHandler().error(e);
                                        }
+
+                                       if (pg.getProgress() < 85) {
+                                               pg.add(1);
+                                       }
                                }
                        }
                }
 
-               pg.setProgress(80);
+               pg.setProgress(85);
 
                // ZIP order is not correct for us
-               Collections.sort(images);
+               List<String> imagesList = new ArrayList<String>(images.keySet());
+               Collections.sort(imagesList);
+
                pg.setProgress(90);
 
-               for (String uuid : images) {
+               for (String uuid : imagesList) {
                        try {
-                               chap.getParagraphs().add(new Paragraph(new URL(uuid)));
+                               chap.getParagraphs().add(new Paragraph(images.get(uuid)));
                        } catch (Exception e) {
                                Instance.getTraceHandler().error(e);
                        }
                }
 
                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();
-                       }
+                       meta.setCover(images.get(imagesList.get(0)));
                }
 
                pg.setProgress(100);
index 466a88539bd375e236376b24f3d0fa5772b7489d..ccffd7c9d27205713cfe6e623b3a8c4c56532aac 100644 (file)
@@ -64,8 +64,9 @@ public class InfoReader {
                                if (info.endsWith(".info")) {
                                        info = info.substring(0, info.length() - ".info".length());
                                        String ext = "."
-                                                       + Instance.getConfig().getString(
-                                                                       Config.IMAGE_FORMAT_COVER);
+                                                       + Instance.getConfig()
+                                                                       .getString(Config.IMAGE_FORMAT_COVER)
+                                                                       .toLowerCase();
                                        meta.setCover(BasicSupport.getImage(null, sourceInfoFile,
                                                        info + ext));
                                }
index af33f9d0695494bb3b954b3aa72605f2998a115a..dba0ef027f8be86e593019f5cacaccb13eeba511 100644 (file)
@@ -21,7 +21,7 @@ import be.nikiroo.utils.Progress;
 import be.nikiroo.utils.test.TestCase;
 import be.nikiroo.utils.test.TestLauncher;
 
-public class BasicSupportTest extends TestLauncher {
+class BasicSupportTest extends TestLauncher {
        // quote chars
        private char openQuote = Instance.getTrans().getCharacter(
                        StringId.OPEN_SINGLE_QUOTE);
index 43ca0879d60ed61fe1d7fc072820d03022bfd6ba..fc61e7ddf86bb5ec8688b390b26ae706295c31c4 100644 (file)
@@ -15,7 +15,7 @@ import be.nikiroo.utils.IOUtils;
 import be.nikiroo.utils.test.TestCase;
 import be.nikiroo.utils.test.TestLauncher;
 
-public class LibraryTest extends TestLauncher {
+class LibraryTest extends TestLauncher {
        private BasicLibrary lib;
        private File tmp;
 
index 0dc544b8d71d93ba4a74b9fdd903b81ecfb19d50..3ff9a7ab8d139ad3e42c46f9caed8d504021f5e7 100644 (file)
@@ -17,6 +17,13 @@ import be.nikiroo.utils.test.TestLauncher;
  * @author niki
  */
 public class Test extends TestLauncher {
+       /**
+        * Create the Fanfix {@link TestLauncher}.
+        * 
+        * @param args
+        *            the arguments to configure the number of columns and the ok/ko
+        *            {@link String}s
+        */
        public Test(String[] args) {
                super("Fanfix", args);
                Instance.setTraceHandler(null);
@@ -30,6 +37,7 @@ public class Test extends TestLauncher {
         * @param args
         *            the arguments passed to the {@link TestLauncher}s.
         * @throws IOException
+        *             in case of I/O error
         */
        static public void main(String[] args) throws IOException {
                File tmpConfig = File.createTempFile("fanfix-config_", ".test");