From 68e370a441d8e6b10bfaa904ecacb29e7d6160d8 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 19 Feb 2017 23:46:39 +0100 Subject: [PATCH] Move default tmp dirs, fix BLANK handling - tmp is now in $config ($HOME/.fanfix)/tmp - reader tmp is now $config/tmp.reader - blanks were not correctly handled in BasicSupport - some tests were added --- src/be/nikiroo/fanfix/Instance.java | 20 +- src/be/nikiroo/fanfix/bundles/Config.java | 2 +- src/be/nikiroo/fanfix/bundles/UiConfig.java | 2 +- .../nikiroo/fanfix/bundles/config.properties | 2 +- src/be/nikiroo/fanfix/bundles/ui.properties | 2 +- .../fanfix/supported/BasicSupport.java | 171 ++++++++++------- .../nikiroo/fanfix/test/BasicSupportTest.java | 172 ++++++++++++++++++ src/be/nikiroo/fanfix/test/Test.java | 3 +- 8 files changed, 295 insertions(+), 79 deletions(-) create mode 100644 src/be/nikiroo/fanfix/test/BasicSupportTest.java diff --git a/src/be/nikiroo/fanfix/Instance.java b/src/be/nikiroo/fanfix/Instance.java index cd57efe..aacf0c5 100644 --- a/src/be/nikiroo/fanfix/Instance.java +++ b/src/be/nikiroo/fanfix/Instance.java @@ -87,20 +87,14 @@ public class Instance { debug = true; } - if (tmp == null || readerTmp == null) { - String tmpDir = System.getProperty("java.io.tmpdir"); - if (tmpDir != null) { - if (tmp == null) { - tmp = new File(tmpDir, "fanfic-tmp"); - } - if (readerTmp == null) { - readerTmp = new File(tmpDir, "fanfic-reader"); - } - } else { - syserr(new IOException( - "The system does not have a default temporary directory")); - } + // Could have used: System.getProperty("java.io.tmpdir") + if (tmp == null) { + tmp = new File(configDir, "tmp"); + } + if (readerTmp == null) { + readerTmp = new File(configDir, "tmp-reader"); } + // if (coverDir != null && !coverDir.exists()) { syserr(new IOException( diff --git a/src/be/nikiroo/fanfix/bundles/Config.java b/src/be/nikiroo/fanfix/bundles/Config.java index 48de5b5..18fda5a 100644 --- a/src/be/nikiroo/fanfix/bundles/Config.java +++ b/src/be/nikiroo/fanfix/bundles/Config.java @@ -12,7 +12,7 @@ public enum Config { LANG, // @Meta(what = "reader type", where = "", format = "CLI or LOCAL", info = "Select the reader to use to read stories (CLI = simple output to console, LOCAL = use local system file handler)") READER_TYPE, // - @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to a directory 'fanfic-tmp' in the system default temporary directory") + @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to directory 'tmp' in the conig directory (usually $HOME/.fanfix)") CACHE_DIR, // @Meta(what = "delay in hours", where = "", format = "integer | 0: no cache | -1: infinite time cache which is default", info = "The delay after which a cached resource that is thought to change ~often is considered too old and triggers a refresh") CACHE_MAX_TIME_CHANGING, // diff --git a/src/be/nikiroo/fanfix/bundles/UiConfig.java b/src/be/nikiroo/fanfix/bundles/UiConfig.java index ee97491..dd2018d 100644 --- a/src/be/nikiroo/fanfix/bundles/UiConfig.java +++ b/src/be/nikiroo/fanfix/bundles/UiConfig.java @@ -8,7 +8,7 @@ import be.nikiroo.utils.resources.Meta; * @author niki */ public enum UiConfig { - @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to a directory 'fanfic-reader' in the system default temporary directory") + @Meta(what = "directory", where = "", format = "absolute path, $HOME variable supported, / is always accepted as dir separator", info = "The directory where to store temporary files, defaults to directory 'tmp.reader' in the conig directory (usually $HOME/.fanfix)") CACHE_DIR_LOCAL_READER, // @Meta(what = "Output type", where = "Local Reader", format = "One of the known output type", info = "The type of output for the Local Reader for non-images documents") LOCAL_READER_NON_IMAGES_DOCUMENT_TYPE, // diff --git a/src/be/nikiroo/fanfix/bundles/config.properties b/src/be/nikiroo/fanfix/bundles/config.properties index c8a9e71..fa53914 100644 --- a/src/be/nikiroo/fanfix/bundles/config.properties +++ b/src/be/nikiroo/fanfix/bundles/config.properties @@ -9,7 +9,7 @@ LANG = # Select the reader to use to read stories (CLI = simple output to console, LOCAL = use local system file handler) READER_TYPE = # (WHAT: directory, FORMAT: absolute path, $HOME variable supported, / is always accepted as dir separator) -# The directory where to store temporary files, defaults to a directory 'fanfic-tmp' in the system default temporary directory +# The directory where to store temporary files, defaults to directory 'tmp' in the conig directory (usually $HOME/.fanfix) CACHE_DIR = # (WHAT: delay in hours, FORMAT: integer | 0: no cache | -1: infinite time cache which is default) # The delay after which a cached resource that is thought to change ~often is considered too old and triggers a refresh diff --git a/src/be/nikiroo/fanfix/bundles/ui.properties b/src/be/nikiroo/fanfix/bundles/ui.properties index f0caf3a..8f72914 100644 --- a/src/be/nikiroo/fanfix/bundles/ui.properties +++ b/src/be/nikiroo/fanfix/bundles/ui.properties @@ -3,7 +3,7 @@ # (WHAT: directory, FORMAT: absolute path, $HOME variable supported, / is always accepted as dir separator) -# The directory where to store temporary files, defaults to a directory 'fanfic-reader' in the system default temporary directory +# The directory where to store temporary files, defaults to directory 'tmp.reader' in the conig directory (usually $HOME/.fanfix) CACHE_DIR_LOCAL_READER = # (WHAT: Output type, WHERE: Local Reader, FORMAT: One of the known output type) # The type of output for the Local Reader for non-images documents diff --git a/src/be/nikiroo/fanfix/supported/BasicSupport.java b/src/be/nikiroo/fanfix/supported/BasicSupport.java index be19841..b6fd1e2 100644 --- a/src/be/nikiroo/fanfix/supported/BasicSupport.java +++ b/src/be/nikiroo/fanfix/supported/BasicSupport.java @@ -1,10 +1,12 @@ package be.nikiroo.fanfix.supported; import java.awt.image.BufferedImage; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -510,90 +512,137 @@ public abstract class BasicSupport { Chapter chap = new Chapter(number, chapterName); - if (content == null) { - return chap; + if (content != null) { + chap.setParagraphs(makeParagraphs(source, content)); } + return chap; + + } + + /** + * Convert the given content into {@link Paragraph}s. + * + * @param source + * the source URL of the story + * @param content + * the textual content + * + * @return the {@link Paragraph}s + * + * @throws IOException + * in case of I/O error + */ + protected List makeParagraphs(URL source, String content) + throws IOException { if (isHtml()) { // Special
processing: content = content.replaceAll("(
]*>)|(
)|(
)", "\n* * *\n"); } + List paras = new ArrayList(); InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); try { - @SuppressWarnings("resource") - Scanner scan = new Scanner(in, "UTF-8"); - scan.useDelimiter("(\\n|

)"); // \n for test,

for html - - List paras = new ArrayList(); - while (scan.hasNext()) { - String line = scan.next().trim(); - boolean image = false; - if (line.startsWith("[") && line.endsWith("]")) { - URL url = getImageUrl(this, source, - line.substring(1, line.length() - 1).trim()); - if (url != null) { - paras.add(new Paragraph(url)); - image = true; - } + BufferedReader buff = new BufferedReader(new InputStreamReader(in, + "UTF-8")); + + for (String encodedLine = buff.readLine(); encodedLine != null; encodedLine = buff + .readLine()) { + String lines[]; + if (isHtml()) { + lines = encodedLine.split("(

|

|
|
|\\n)"); + } else { + lines = new String[] { encodedLine }; } - if (!image) { - paras.add(processPara(line)); + for (String aline : lines) { + String line = aline.trim(); + + URL image = null; + if (line.startsWith("[") && line.endsWith("]")) { + image = getImageUrl(this, source, + line.substring(1, line.length() - 1).trim()); + } + + if (image != null) { + paras.add(new Paragraph(image)); + } else { + paras.add(processPara(line)); + } } } + } finally { + in.close(); + } - // Check quotes for "bad" format - List newParas = new ArrayList(); - for (Paragraph para : paras) { - newParas.addAll(requotify(para)); - } - paras = newParas; - - // Remove double blanks/brks - boolean space = false; - boolean brk = true; - for (int i = 0; i < paras.size(); i++) { - Paragraph para = paras.get(i); - boolean thisSpace = para.getType() == ParagraphType.BLANK; - boolean thisBrk = para.getType() == ParagraphType.BREAK; - - if (space && thisBrk) { - paras.remove(i - 1); - i--; - } else if ((space || brk) && (thisSpace || thisBrk)) { - paras.remove(i); - i--; - } + // Check quotes for "bad" format + List newParas = new ArrayList(); + for (Paragraph para : paras) { + newParas.addAll(requotify(para)); + } + paras = newParas; - space = thisSpace; - brk = thisBrk; - } + // Remove double blanks/brks + fixBlanksBreaks(paras); - // Remove blank/brk at start - if (paras.size() > 0 - && (paras.get(0).getType() == ParagraphType.BLANK || paras - .get(0).getType() == ParagraphType.BREAK)) { - paras.remove(0); - } + return paras; + } - // Remove blank/brk at end - int last = paras.size() - 1; - if (paras.size() > 0 - && (paras.get(last).getType() == ParagraphType.BLANK || paras - .get(last).getType() == ParagraphType.BREAK)) { - paras.remove(last); + /** + * Fix the {@link ParagraphType#BLANK}s and {@link ParagraphType#BREAK}s of + * those {@link Paragraph}s. + *

+ * The resulting list will not contain a starting or trailing blank/break + * nor 2 blanks or breaks following each other. + * + * @param paras + * the list of {@link Paragraph}s to fix + */ + protected void fixBlanksBreaks(List paras) { + boolean space = false; + boolean brk = true; + for (int i = 0; i < paras.size(); i++) { + Paragraph para = paras.get(i); + boolean thisSpace = para.getType() == ParagraphType.BLANK; + boolean thisBrk = para.getType() == ParagraphType.BREAK; + + if (i > 0 && space && thisBrk) { + paras.remove(i - 1); + i--; + } else if ((space || brk) && (thisSpace || thisBrk)) { + paras.remove(i); + i--; } - chap.setParagraphs(paras); + space = thisSpace; + brk = thisBrk; + } - return chap; - } finally { - in.close(); + // Remove blank/brk at start + if (paras.size() > 0 + && (paras.get(0).getType() == ParagraphType.BLANK || paras.get( + 0).getType() == ParagraphType.BREAK)) { + paras.remove(0); + } + + // Remove blank/brk at end + int last = paras.size() - 1; + if (paras.size() > 0 + && (paras.get(last).getType() == ParagraphType.BLANK || paras + .get(last).getType() == ParagraphType.BREAK)) { + paras.remove(last); } } + /** + * Get the default cover related to this subject (see .info files). + * + * @param subject + * the subject + * + * @return the cover if any, or NULL + */ static BufferedImage getDefaultCover(String subject) { if (subject != null && !subject.isEmpty() && Instance.getCoverDir() != null) { @@ -772,7 +821,7 @@ public abstract class BasicSupport { * * @return the correctly (or so we hope) quotified paragraphs */ - private List requotify(Paragraph para) { + protected List requotify(Paragraph para) { List newParas = new ArrayList(); if (para.getType() == ParagraphType.QUOTE diff --git a/src/be/nikiroo/fanfix/test/BasicSupportTest.java b/src/be/nikiroo/fanfix/test/BasicSupportTest.java new file mode 100644 index 0000000..ed585d9 --- /dev/null +++ b/src/be/nikiroo/fanfix/test/BasicSupportTest.java @@ -0,0 +1,172 @@ +package be.nikiroo.fanfix.test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.fanfix.data.Paragraph; +import be.nikiroo.fanfix.data.Paragraph.ParagraphType; +import be.nikiroo.fanfix.supported.BasicSupport; +import be.nikiroo.utils.test.TestCase; +import be.nikiroo.utils.test.TestLauncher; + +public class BasicSupportTest extends TestLauncher { + + public BasicSupportTest(String[] args) { + super("BasicSupport", args); + + addSeries(new TestLauncher("General", args) { + { + addTest(new TestCase("BasicSupport.makeParagraphs()") { + @Override + public void test() throws Exception { + BasicSupportEmpty support = new BasicSupportEmpty() { + @Override + protected boolean isHtml() { + return true; + } + + @Override + public void fixBlanksBreaks(List paras) { + } + + @Override + protected List requotify(Paragraph para) { + List paras = new ArrayList( + 1); + paras.add(para); + return paras; + } + }; + + List paras = null; + + paras = support.makeParagraphs(null, ""); + assertEquals( + "An empty content should not generate paragraphs", + 0, paras.size()); + + paras = support.makeParagraphs(null, + "Line 1

Line 2

Line 3

"); + assertEquals(5, paras.size()); + assertEquals("Line 1", paras.get(0).getContent()); + assertEquals(ParagraphType.BLANK, paras.get(1) + .getType()); + assertEquals("Line 2", paras.get(2).getContent()); + assertEquals(ParagraphType.BLANK, paras.get(3) + .getType()); + assertEquals("Line 3", paras.get(4).getContent()); + + paras = support.makeParagraphs(null, + "

Line1

Line2

Line3

"); + assertEquals(6, paras.size()); + } + }); + + addTest(new TestCase("BasicSupport.removeDoubleBlanks()") { + @Override + public void test() throws Exception { + BasicSupportEmpty support = new BasicSupportEmpty() { + @Override + protected boolean isHtml() { + return true; + } + }; + + List paras = null; + + paras = support + .makeParagraphs(null, + "

Line1

Line2

Line3

"); + assertEquals(5, paras.size()); + + paras = support + .makeParagraphs(null, + "

Line1

Line2

Line3

* * *"); + assertEquals(5, paras.size()); + + paras = support.makeParagraphs(null, "1

* * *

2"); + assertEquals(3, paras.size()); + assertEquals(ParagraphType.BREAK, paras.get(1) + .getType()); + + paras = support.makeParagraphs(null, + "1


* * *

2"); + assertEquals(3, paras.size()); + assertEquals(ParagraphType.BREAK, paras.get(1) + .getType()); + + paras = support.makeParagraphs(null, + "1

* * *


2"); + assertEquals(3, paras.size()); + assertEquals(ParagraphType.BREAK, paras.get(1) + .getType()); + + paras = support.makeParagraphs(null, + "1



* * *


2"); + assertEquals(3, paras.size()); + assertEquals(ParagraphType.BREAK, paras.get(1) + .getType()); + } + }); + } + }); + } + + private class BasicSupportEmpty extends BasicSupport { + @Override + protected String getSourceName() { + return null; + } + + @Override + protected boolean supports(URL url) { + return false; + } + + @Override + protected boolean isHtml() { + return false; + } + + @Override + protected MetaData getMeta(URL source, InputStream in) + throws IOException { + return null; + } + + @Override + protected String getDesc(URL source, InputStream in) throws IOException { + return null; + } + + @Override + protected List> getChapters(URL source, + InputStream in) throws IOException { + return null; + } + + @Override + protected String getChapterContent(URL source, InputStream in, + int number) throws IOException { + return null; + } + + @Override + // and make it public! + public List makeParagraphs(URL source, String content) + throws IOException { + return super.makeParagraphs(source, content); + } + + @Override + // and make it public! + public void fixBlanksBreaks(List paras) { + super.fixBlanksBreaks(paras); + } + } +} diff --git a/src/be/nikiroo/fanfix/test/Test.java b/src/be/nikiroo/fanfix/test/Test.java index 2eaeff0..36ef701 100644 --- a/src/be/nikiroo/fanfix/test/Test.java +++ b/src/be/nikiroo/fanfix/test/Test.java @@ -9,7 +9,8 @@ import be.nikiroo.utils.test.TestLauncher; */ public class Test extends TestLauncher { public Test(String[] args) { - super("Fanfix (empty: all tests were moved to nikiroo-utils...)", args); + super("Fanfix", args); + addSeries(new BasicSupportTest(args)); } /** -- 2.27.0