use a .summary file
authorNiki Roo <niki@nikiroo.be>
Sun, 17 May 2020 20:00:28 +0000 (22:00 +0200)
committerNiki Roo <niki@nikiroo.be>
Sun, 17 May 2020 20:00:28 +0000 (22:00 +0200)
src/be/nikiroo/fanfix/data/MetaData.java
src/be/nikiroo/fanfix/library/BasicLibrary.java
src/be/nikiroo/fanfix/library/LocalLibrary.java
src/be/nikiroo/fanfix/output/BasicOutput.java
src/be/nikiroo/fanfix/output/InfoCover.java
src/be/nikiroo/fanfix/supported/BasicSupportPara.java
src/be/nikiroo/fanfix/supported/InfoReader.java
src/be/nikiroo/fanfix/supported/Text.java

index bcebf754b7dc2b6ee71204d9aaf8a1efe2c20dbf..2e34ef98ad27bda10ff34a009fa3d3d314aaf6b2 100644 (file)
@@ -9,6 +9,12 @@ import be.nikiroo.utils.StringUtils;
 
 /**
  * The meta data associated to a {@link Story} object.
+ * <p>
+ * Note that some earlier version of the program did not save the resume as an
+ * external file; for those stories, the resume is not fetched until the story
+ * is.
+ * <p>
+ * The cover is never fetched until the story is.
  * 
  * @author niki
  */
@@ -120,6 +126,10 @@ public class MetaData implements Cloneable, Comparable<MetaData>, Serializable {
         * The story resume (a.k.a. description).
         * <p>
         * This can be NULL if we don't have a resume for this {@link Story}.
+        * <p>
+        * Note that some earlier version of the program did not save the resume as
+        * an external file; for those stories, the resume is not fetched until the
+        * story is.
         * 
         * @return the resume
         */
@@ -129,6 +139,10 @@ public class MetaData implements Cloneable, Comparable<MetaData>, Serializable {
 
        /**
         * The story resume (a.k.a. description).
+        * <p>
+        * Note that some earlier version of the program did not save the resume as
+        * an external file; for those stories, the resume is not fetched until the
+        * story is.
         * 
         * @param resume
         *            the resume to set
@@ -139,6 +153,8 @@ public class MetaData implements Cloneable, Comparable<MetaData>, Serializable {
 
        /**
         * The cover image of the story if any (can be NULL).
+        * <p>
+        * The cover is not fetched until the story is.
         * 
         * @return the cover
         */
@@ -148,6 +164,8 @@ public class MetaData implements Cloneable, Comparable<MetaData>, Serializable {
 
        /**
         * The cover image of the story if any (can be NULL).
+        * <p>
+        * The cover is not fetched until the story is.
         * 
         * @param cover
         *            the cover to set
index 8b72f19b3a92ad1c1d7ada09d915440596330ee2..f77d0edcef5ae64b186942be2a6048fa7eca7745 100644 (file)
@@ -475,6 +475,8 @@ abstract public class BasicLibrary {
 
        /**
         * Retrieve a specific {@link Story}.
+        * <p>
+        * Note that it will update both the cover and the resume in <tt>meta</tt>.
         * 
         * @param luid
         *            the Library UID of the story
@@ -513,6 +515,8 @@ abstract public class BasicLibrary {
 
        /**
         * Retrieve a specific {@link Story}.
+        * <p>
+        * Note that it will update both the cover and the resume in <tt>meta</tt>.
         * 
         * @param luid
         *            the LUID of the story
index f655d4d03bb43b5df69d00fc8b30b2adbad6c113..25f2ec960627ab354295289f73a7c93d6bbbe3ed 100644 (file)
@@ -625,6 +625,18 @@ public class LocalLibrary extends BasicLibrary {
                        files.add(coverFile);
                }
 
+               String summaryExt = ".summary";
+               File summaryFile = new File(path + summaryExt);
+               if (!summaryFile.exists()) {
+                       summaryFile = new File(
+                                       path.substring(0, path.length() - fileExt.length())
+                                                       + summaryExt);
+               }
+
+               if (summaryFile.exists()) {
+                       files.add(summaryFile);
+               }
+
                return files;
        }
 
index 41634faaddbceabc89b4ad1be016c88bbaedc0de..62a008c001b8b3697671079ab34b839fef74bf31 100644 (file)
@@ -299,27 +299,21 @@ public abstract class BasicOutput {
                return "";
        }
 
-       @SuppressWarnings("unused")
        protected void writeStoryHeader(Story story) throws IOException {
        }
 
-       @SuppressWarnings("unused")
        protected void writeChapterHeader(Chapter chap) throws IOException {
        }
 
-       @SuppressWarnings("unused")
        protected void writeParagraphHeader(Paragraph para) throws IOException {
        }
 
-       @SuppressWarnings("unused")
        protected void writeStoryFooter(Story story) throws IOException {
        }
 
-       @SuppressWarnings("unused")
        protected void writeChapterFooter(Chapter chap) throws IOException {
        }
 
-       @SuppressWarnings("unused")
        protected void writeParagraphFooter(Paragraph para) throws IOException {
        }
 
index d8ca49a6876bcb1a759845d117b26cdd302bdfe6..fe530a852b1547ee498c0b66afa8e9fa0fe7a05f 100644 (file)
@@ -5,22 +5,45 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
+import java.util.Arrays;
 
 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.Story;
 
+/**
+ * Helper class to write info, cover and summary (resume) files.
+ * 
+ * @author niki
+ */
 public class InfoCover {
+       /**
+        * Write both the <tt>.info<tt> and the <tt>.summary</tt> files by taking
+        * the information from the {@link MetaData}.
+        * 
+        * @param targetDir
+        *            the directory where to write the 2 files
+        * @param targetName
+        *            the target name (no extension) to use (so you will get
+        *            <tt>targetName.info</tt> and <tt>targetName.summary</tt>)
+        * @param meta
+        *            the {@link MetaData} to get the data out of
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
        public static void writeInfo(File targetDir, String targetName,
                        MetaData meta) throws IOException {
                File info = new File(targetDir, targetName + ".info");
 
-               BufferedWriter infoWriter = null;
-               try {
-                       infoWriter = new BufferedWriter(new OutputStreamWriter(
-                                       new FileOutputStream(info), "UTF-8"));
+               if (meta != null) {
+                       BufferedWriter infoWriter = null;
+                       try {
+                               infoWriter = new BufferedWriter(new OutputStreamWriter(
+                                               new FileOutputStream(info), "UTF-8"));
 
-                       if (meta != null) {
                                String tags = "";
                                if (meta.getTags() != null) {
                                        for (String tag : meta.getTags()) {
@@ -47,7 +70,8 @@ public class InfoCover {
                                writeMeta(infoWriter, "TYPE", meta.getType());
                                if (meta.getCover() != null) {
                                        String format = Instance.getInstance().getConfig()
-                                                       .getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER).toLowerCase();
+                                                       .getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER)
+                                                       .toLowerCase();
                                        writeMeta(infoWriter, "COVER", targetName + "." + format);
                                } else {
                                        writeMeta(infoWriter, "COVER", "");
@@ -59,14 +83,69 @@ public class InfoCover {
                                writeMeta(infoWriter, "CREATION_DATE", meta.getCreationDate());
                                writeMeta(infoWriter, "FAKE_COVER",
                                                Boolean.toString(meta.isFakeCover()));
+                       } finally {
+                               if (infoWriter != null) {
+                                       infoWriter.close();
+                               }
                        }
-               } finally {
-                       if (infoWriter != null) {
-                               infoWriter.close();
+
+                       if (meta.getResume() != null) {
+                               Story fakeStory = new Story();
+                               fakeStory.setMeta(meta);
+                               fakeStory.setChapters(Arrays.asList(meta.getResume()));
+
+                               Text summaryText = new Text() {
+                                       @Override
+                                       protected boolean isWriteCover() {
+                                               return false;
+                                       }
+
+                                       @Override
+                                       protected boolean isWriteInfo() {
+                                               return false; // infinite loop if not!
+                                       }
+
+                                       @Override
+                                       public String getDefaultExtension(boolean readerTarget) {
+                                               return ".summary";
+                                       }
+
+                                       @Override
+                                       protected void writeStoryHeader(Story story)
+                                                       throws IOException {
+                                       }
+
+                                       @Override
+                                       protected void writeStoryFooter(Story story)
+                                                       throws IOException {
+                                       }
+
+                                       @Override
+                                       protected void writeChapterHeader(Chapter chap)
+                                                       throws IOException {
+                                       }
+
+                                       @Override
+                                       protected void writeChapterFooter(Chapter chap)
+                                                       throws IOException {
+                                       }
+                               };
+
+                               summaryText.process(fakeStory, targetDir, targetName);
                        }
                }
        }
 
+       /**
+        * Write the cover file.
+        * 
+        * @param targetDir
+        *            the target directory
+        * @param targetName
+        *            the target name for the cover (the extension will be added)
+        * @param meta
+        *            the meta to get the information out of
+        */
        public static void writeCover(File targetDir, String targetName,
                        MetaData meta) {
                if (meta != null && meta.getCover() != null) {
index 1dbedc9cc326b0bdcb18e11753c8d78ccc611e22..e550d82ee0257ffb84bd8a9aee0eddf044d3c55e 100644 (file)
@@ -35,6 +35,17 @@ public class BasicSupportPara {
        BasicSupportHelper bsHelper;
        BasicSupportImages bsImages;
        
+       /**
+        * Create a new {@link BasicSupportPara}.
+        * <p>
+        * Note that you need an instance of both {@link BasicSupportHelper} and
+        * {@link BasicSupportImages} for it to work.
+        * 
+        * @param bsHelper
+        *            the required {@link BasicSupportHelper}
+        * @param bsImages
+        *            the required {@link BasicSupportImages}
+        */
        public BasicSupportPara(BasicSupportHelper bsHelper, BasicSupportImages bsImages) {
                this.bsHelper = bsHelper;
                this.bsImages = bsImages;
@@ -45,7 +56,7 @@ public class BasicSupportPara {
         * the content as it should be.
         * 
         * @param support
-        *            the linked {@link BasicSupport}
+        *            the linked {@link BasicSupport} (can be NULL)
         * @param source
         *            the source of the story (for image lookup in the same path if
         *            the source is a file, can be NULL)
index d5eeeb1d9190a022db4bf360cb243710decc493e..22afc92f8d3521bfc16ba05e38461ac2f4ef77a9 100644 (file)
@@ -11,27 +11,30 @@ import java.util.Scanner;
 
 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.utils.IOUtils;
 import be.nikiroo.utils.Image;
 import be.nikiroo.utils.streams.MarkableFileInputStream;
 
-// not complete: no "description" tag
 public class InfoReader {
        static protected BasicSupportHelper bsHelper = new BasicSupportHelper();
-       // static protected BasicSupportImages bsImages = new BasicSupportImages();
-       // static protected BasicSupportPara bsPara = new BasicSupportPara(new
-       // BasicSupportHelper(), new BasicSupportImages());
+       static protected BasicSupportImages bsImages = new BasicSupportImages();
+       static protected BasicSupportPara bsPara = new BasicSupportPara(
+                       new BasicSupportHelper(), new BasicSupportImages());
 
        public static MetaData readMeta(File infoFile, boolean withCover)
                        throws IOException {
                if (infoFile == null) {
                        throw new IOException("File is null");
                }
+               
+               MetaData meta = null;
 
                if (infoFile.exists()) {
                        InputStream in = new MarkableFileInputStream(infoFile);
                        try {
-                               MetaData meta = createMeta(infoFile.toURI().toURL(), in,
+                               meta = createMeta(infoFile.toURI().toURL(), in,
                                                withCover);
 
                                // Some old .info files were using UUID for URL...
@@ -46,8 +49,6 @@ public class InfoReader {
                                // formats have a copy of the original text file)
                                if (!hasIt(meta.getTitle(), meta.getAuthor(), meta.getDate(),
                                                meta.getUrl())) {
-
-                                       // TODO: not nice, would be better to do it properly...
                                        String base = infoFile.getPath();
                                        if (base.endsWith(".info")) {
                                                base = base.substring(0,
@@ -62,15 +63,34 @@ public class InfoReader {
                                        }
 
                                        completeMeta(textFile, meta);
-                                       //
                                }
 
-                               return meta;
+                               
                        } finally {
                                in.close();
                        }
                }
 
+               if (meta != null) {
+                       try {
+                               File summaryFile = new File(infoFile.getAbsolutePath()
+                                               .replaceFirst("\\.info$", ".summary"));
+                               InputStream in = new MarkableFileInputStream(summaryFile);
+                               try {
+                                       String content = IOUtils.readSmallStream(in);
+                                       Chapter desc = bsPara.makeChapter(null, null, 0,
+                                                       "Description", content, false, null);
+                                       meta.setResume(desc);
+                               } finally {
+                                       in.close();
+                               }
+                       } catch (IOException e) {
+                               // ignore absent or bad summary
+                       }
+                       
+                       return meta;
+               }
+
                throw new FileNotFoundException(
                                "File given as argument does not exists: "
                                                + infoFile.getAbsolutePath());
@@ -90,6 +110,7 @@ public class InfoReader {
         */
        static public void completeMeta(File textFile,
                        MetaData meta)  throws IOException {
+               // TODO: not nice, would be better to do it properly...
                if (textFile != null && textFile.exists()) {
                        final URL source = textFile.toURI().toURL();
                        final MetaData[] superMetaA = new MetaData[1];
index 232eab6ec4f7736b6b470011f51d09548fe733e8..71e30c3252220c76f6ae5724e9632d33e67878cf 100644 (file)
@@ -15,9 +15,7 @@ import org.jsoup.nodes.Document;
 
 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.utils.Image;
 import be.nikiroo.utils.ImageUtils;
 import be.nikiroo.utils.Progress;
@@ -172,20 +170,7 @@ class Text extends BasicSupport {
 
        @Override
        protected String getDesc() throws IOException {
-               String content = getChapterContent(null, 0, null).trim();
-               if (!content.isEmpty()) {
-                       Chapter desc = bsPara.makeChapter(this, null, 0, "Description",
-                                       content, isHtml(), null);
-                       StringBuilder builder = new StringBuilder();
-                       for (Paragraph para : desc) {
-                               if (builder.length() > 0) {
-                                       builder.append("\n");
-                               }
-                               builder.append(para.getContent());
-                       }
-               }
-
-               return content;
+               return getChapterContent(null, 0, null).trim();
        }
 
        protected Image getCover(File sourceFile) {