Merge branch 'subtree'
authorNiki Roo <niki@nikiroo.be>
Tue, 28 Apr 2020 07:42:51 +0000 (09:42 +0200)
committerNiki Roo <niki@nikiroo.be>
Tue, 28 Apr 2020 07:42:51 +0000 (09:42 +0200)
1  2 
src/be/nikiroo/fanfix/Instance.java
src/be/nikiroo/fanfix/supported/Epub.java
src/be/nikiroo/fanfix/supported/InfoReader.java
src/be/nikiroo/fanfix/supported/InfoText.java
src/be/nikiroo/fanfix/supported/Text.java

index f48d05b7d4cd84994eeb7e5e238018e99317afbd,d0d1c84ab7643b65b34a91859a1b75ca59533091..d0d1c84ab7643b65b34a91859a1b75ca59533091
@@@ -48,8 -48,19 +48,19 @@@ public class Instance 
        /**
         * Initialise the instance -- if already initialised, nothing will happen.
         * <p>
-        * Before calling this method, you may call {@link Bundles#setDirectory(String)}
-        * if wanted.
+        * Before calling this method, you may call
+        * {@link Bundles#setDirectory(String)} if wanted.
+        * <p>
+        * Note that this method will honour some environment variables, the 3 most
+        * important ones probably being:
+        * <ul>
+        * <li><tt>DEBUG</tt>: will enable DEBUG output if set to 1 (or Y or TRUE or
+        * ON, case insensitive)</li>
+        * <li><tt>CONFIG_DIR</tt>: will use this directory as configuration
+        * directory (supports $HOME notation, defaults to $HOME/.fanfix</li>
+        * <li><tt>BOOKS_DIR</tt>: will use this directory as library directory
+        * (supports $HOME notation, defaults to $HOME/Books</li>
+        * </ul>
         */
        static public void init() {
                init(false);
                BasicLibrary lib = null;
  
                boolean useRemote = config.getBoolean(Config.REMOTE_LIBRARY_ENABLED, false);
                if (useRemote) {
                        String host = null;
                        int port = -1;
index f8e467831381185244eae24b15d3a96a6cb0f6cb,90a9f458e4fd3ce9c0f8ad331bc407a27dc760ca..90a9f458e4fd3ce9c0f8ad331bc407a27dc760ca
@@@ -42,8 -42,8 +42,8 @@@ class Epub extends InfoText 
                try {
                        return new File(fakeSource.toURI());
                } catch (URISyntaxException e) {
-                       Instance.getInstance().getTraceHandler()
-                                       .error(new IOException("Cannot get the source file from the info-text URL", e));
+                       Instance.getInstance().getTraceHandler().error(new IOException(
+                                       "Cannot get the source file from the info-text URL", e));
                }
  
                return null;
@@@ -55,7 -55,8 +55,8 @@@
                        try {
                                fakeIn.reset();
                        } catch (IOException e) {
-                               Instance.getInstance().getTraceHandler().error(new IOException("Cannot reset the Epub Text stream", e));
+                               Instance.getInstance().getTraceHandler().error(new IOException(
+                                               "Cannot reset the Epub Text stream", e));
                        }
  
                        return fakeIn;
@@@ -83,7 -84,8 +84,8 @@@
                ZipInputStream zipIn = null;
                try {
                        zipIn = new ZipInputStream(in);
-                       tmpDir = Instance.getInstance().getTempFiles().createTempDir("fanfic-reader-parser");
+                       tmpDir = Instance.getInstance().getTempFiles()
+                                       .createTempDir("fanfic-reader-parser");
                        File tmp = new File(tmpDir, "file.txt");
                        File tmpInfo = new File(tmpDir, "file.info");
  
                        String title = null;
                        String author = null;
  
-                       for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn
-                                       .getNextEntry()) {
+                       for (ZipEntry entry = zipIn
+                                       .getNextEntry(); entry != null; entry = zipIn
+                                                       .getNextEntry()) {
                                if (!entry.isDirectory()
                                                && entry.getName().startsWith(getDataPrefix())) {
                                        String entryLName = entry.getName().toLowerCase();
                                                        try {
                                                                cover = new Image(zipIn);
                                                        } catch (Exception e) {
-                                                               Instance.getInstance().getTraceHandler().error(e);
+                                                               Instance.getInstance().getTraceHandler()
+                                                                               .error(e);
                                                        }
                                                }
-                                       } else if (entry.getName().equals(getDataPrefix() + "URL")) {
+                                       } else if (entry.getName()
+                                                       .equals(getDataPrefix() + "URL")) {
                                                String[] descArray = StringUtils
                                                                .unhtml(IOUtils.readSmallStream(zipIn)).trim()
                                                                .split("\n");
                                                if (descArray.length > 0) {
                                                        url = descArray[0].trim();
                                                }
-                                       } else if (entry.getName().equals(
-                                                       getDataPrefix() + "SUMMARY")) {
+                                       } else if (entry.getName().endsWith(".desc")) {
+                                               // // For old files
+                                               // if (this.desc != null) {
+                                               // this.desc = IOUtils.readSmallStream(zipIn).trim();
+                                               // }
+                                       } else if (entry.getName()
+                                                       .equals(getDataPrefix() + "SUMMARY")) {
                                                String[] descArray = StringUtils
                                                                .unhtml(IOUtils.readSmallStream(zipIn)).trim()
                                                                .split("\n");
                                                                skip = 2;
                                                        }
                                                }
-                                               this.desc = "";
-                                               for (int i = skip; i < descArray.length; i++) {
-                                                       this.desc += descArray[i].trim() + "\n";
-                                               }
-                                               this.desc = this.desc.trim();
+                                               // this.desc = "";
+                                               // for (int i = skip; i < descArray.length; i++) {
+                                               // this.desc += descArray[i].trim() + "\n";
+                                               // }
+                                               //
+                                               // this.desc = this.desc.trim();
                                        } else {
                                                // Hopefully the data file
                                                IOUtils.write(zipIn, tmp);
                                if (cover != null) {
                                        meta.setCover(cover);
                                } else {
-                                       meta.setCover(InfoReader
-                                                       .getCoverByName(getSourceFileOriginal().toURI()
-                                                                       .toURL()));
+                                       meta.setCover(InfoReader.getCoverByName(
+                                                       getSourceFileOriginal().toURI().toURL()));
                                }
                        }
                } finally {
index 220350e6dc904495de7de918e4843cf3d15dda01,405b28fb4197be856192e3b8ad31a219f4636cc5..405b28fb4197be856192e3b8ad31a219f4636cc5
@@@ -19,7 -19,8 +19,8 @@@ import be.nikiroo.utils.streams.Markabl
  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 BasicSupportPara bsPara = new BasicSupportPara(new
+       // BasicSupportHelper(), new BasicSupportImages());
  
        public static MetaData readMeta(File infoFile, boolean withCover)
                        throws IOException {
                if (infoFile.exists()) {
                        InputStream in = new MarkableFileInputStream(infoFile);
                        try {
-                               return createMeta(infoFile.toURI().toURL(), in, withCover);
+                               MetaData meta = createMeta(infoFile.toURI().toURL(), in,
+                                               withCover);
+                               // Some old .info files were using UUID for URL...
+                               if (!hasIt(meta.getUrl()) && meta.getUuid() != null
+                                               && (meta.getUuid().startsWith("http://")
+                                                               || meta.getUuid().startsWith("https://"))) {
+                                       meta.setUrl(meta.getUuid());
+                               }
+                               // Some old .info files don't have those now required fields...
+                               // So we check if we can find the info in another way (many
+                               // 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,
+                                                               base.length() - ".info".length());
+                                       }
+                                       File textFile = new File(base);
+                                       if (!textFile.exists()) {
+                                               textFile = new File(base + ".txt");
+                                       }
+                                       if (!textFile.exists()) {
+                                               textFile = new File(base + ".text");
+                                       }
+                                       if (textFile.exists()) {
+                                               final URL source = textFile.toURI().toURL();
+                                               final MetaData[] superMetaA = new MetaData[1];
+                                               @SuppressWarnings("unused")
+                                               Text unused = new Text() {
+                                                       private boolean loaded = loadDocument();
+                                                       @Override
+                                                       public SupportType getType() {
+                                                               return SupportType.TEXT;
+                                                       }
+                                                       protected boolean loadDocument()
+                                                                       throws IOException {
+                                                               loadDocument(source);
+                                                               superMetaA[0] = getMeta();
+                                                               return true;
+                                                       }
+                                                       @Override
+                                                       protected Image getCover(File sourceFile) {
+                                                               return null;
+                                                       }
+                                               };
+                                               MetaData superMeta = superMetaA[0];
+                                               if (!hasIt(meta.getTitle())) {
+                                                       meta.setTitle(superMeta.getTitle());
+                                               }
+                                               if (!hasIt(meta.getAuthor())) {
+                                                       meta.setAuthor(superMeta.getAuthor());
+                                               }
+                                               if (!hasIt(meta.getDate())) {
+                                                       meta.setDate(superMeta.getDate());
+                                               }
+                                               if (!hasIt(meta.getUrl())) {
+                                                       meta.setUrl(superMeta.getUrl());
+                                               }
+                                       }
+                               }
+                               return meta;
                        } finally {
                                in.close();
                        }
                                                + infoFile.getAbsolutePath());
        }
  
+       /**
+        * Check if we have non-empty values for all the given {@link String}s.
+        * 
+        * @param values
+        *            the values to check
+        * 
+        * @return TRUE if none of them was NULL or empty
+        */
+       static private boolean hasIt(String... values) {
+               for (String value : values) {
+                       if (value == null || value.trim().isEmpty()) {
+                               return false;
+                       }
+               }
+               return true;
+       }
        private static MetaData createMeta(URL sourceInfoFile, InputStream in,
                        boolean withCover) throws IOException {
                MetaData meta = new MetaData();
                if (withCover) {
                        String infoTag = getInfoTag(in, "COVER");
                        if (infoTag != null && !infoTag.trim().isEmpty()) {
-                               meta.setCover(bsHelper.getImage(null, sourceInfoFile,
-                                               infoTag));
+                               meta.setCover(bsHelper.getImage(null, sourceInfoFile, infoTag));
                        }
                        if (meta.getCover() == null) {
                                // Second chance: try to check for a cover next to the info file
  
                File basefile = new File(sourceInfoFile.getFile());
  
-               String ext = "."
-                               + Instance.getInstance().getConfig().getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER).toLowerCase();
+               String ext = "." + Instance.getInstance().getConfig()
+                               .getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER).toLowerCase();
  
                // Without removing ext
                cover = bsHelper.getImage(null, sourceInfoFile,
                        String value = getLine(in, key, 0);
                        if (value != null && !value.isEmpty()) {
                                value = value.trim().substring(key.length() - 1).trim();
-                               if (value.startsWith("'") && value.endsWith("'")
-                                               || value.startsWith("\"") && value.endsWith("\"")) {
+                               if (value.length() > 1 && //
+                                               (value.startsWith("'") && value.endsWith("'")
+                                                               || value.startsWith("\"")
+                                                                               && value.endsWith("\""))) {
                                        value = value.substring(1, value.length() - 1).trim();
                                }
  
+                               // Some old files ended up with TITLE="'xxxxx'"
+                               if ("^TITLE=".equals(key)) {
+                                       if (value.startsWith("'") && value.endsWith("'")
+                                                       && value.length() > 1) {
+                                               value = value.substring(1, value.length() - 1).trim();
+                                       }
+                               }
                                return value;
                        }
                }
  
                        if (index == -1) {
                                if (needle.startsWith("^")) {
-                                       if (lines.get(lines.size() - 1).startsWith(
-                                                       needle.substring(1))) {
+                                       if (lines.get(lines.size() - 1)
+                                                       .startsWith(needle.substring(1))) {
                                                index = lines.size() - 1;
                                        }
  
index 42e2c13b6f75a1e32afa10f560361c1670ea9572,2af8c7e2f4880139540aa6f7f4e4895fd6e4742d..2af8c7e2f4880139540aa6f7f4e4895fd6e4742d
@@@ -22,30 -22,7 +22,7 @@@ class InfoText extends Text 
  
        @Override
        protected MetaData getMeta() throws IOException {
-               MetaData meta = InfoReader.readMeta(getInfoFile(), true);
-               // Some old .info files don't have those now required fields...
-               String test = meta.getTitle() == null ? "" : meta.getTitle();
-               test += meta.getAuthor() == null ? "" : meta.getAuthor();
-               test += meta.getDate() == null ? "" : meta.getDate();
-               test += meta.getUrl() == null ? "" : meta.getUrl();
-               if (test.isEmpty()) {
-                       MetaData superMeta = super.getMeta();
-                       if (meta.getTitle() == null || meta.getTitle().isEmpty()) {
-                               meta.setTitle(superMeta.getTitle());
-                       }
-                       if (meta.getAuthor() == null || meta.getAuthor().isEmpty()) {
-                               meta.setAuthor(superMeta.getAuthor());
-                       }
-                       if (meta.getDate() == null || meta.getDate().isEmpty()) {
-                               meta.setDate(superMeta.getDate());
-                       }
-                       if (meta.getUrl() == null || meta.getUrl().isEmpty()) {
-                               meta.setUrl(superMeta.getUrl());
-                       }
-               }
-               return meta;
+               return InfoReader.readMeta(getInfoFile(), true);
        }
  
        @Override
index c54b6a5d44ce0a328d63451420c6a9c00a82bd3c,e082a737f2a7be9c11b9fc133bea0c96f108ae55..e082a737f2a7be9c11b9fc133bea0c96f108ae55
@@@ -97,7 -97,7 +97,7 @@@ class Text extends BasicSupport 
                meta.setType(getType().toString());
                meta.setImageDocument(false);
                meta.setCover(getCover(getSourceFile()));
+               
                return meta;
        }
  
                return content;
        }
  
-       private Image getCover(File sourceFile) {
+       protected Image getCover(File sourceFile) {
                String path = sourceFile.getName();
  
                for (String ext : new String[] { ".txt", ".text", ".story" }) {
        }
  
        /**
-        * Remove the ".txt" extension if it is present.
+        * Remove the ".txt" (or ".text") extension if it is present.
         * 
         * @param file
         *            the file to process
         *         was present
         */
        protected File assureNoTxt(File file) {
-               if (file.getName().endsWith(".txt")) {
-                       file = new File(file.getPath().substring(0,
-                                       file.getPath().length() - 4));
+               for (String ext : new String[] { ".txt", ".text" }) {
+                       if (file.getName().endsWith(ext)) {
+                               file = new File(file.getPath().substring(0,
+                                               file.getPath().length() - ext.length()));
+                       }
                }
  
                return file;