From e992c260c059c53c4aabc980db85efd58f190205 Mon Sep 17 00:00:00 2001
From: Niki Roo
Date: Sun, 17 May 2020 22:02:52 +0200
Subject: [PATCH] update from master
---
data/MetaData.java | 18 +
library/BasicLibrary.java | 4 +
library/LocalLibrary.java | 12 +
library/WebLibraryServerHtml.java | 494 +++++++++---------
library/web/index.post.html | 2 -
library/web/index.pre.html | 6 +-
library/web/package-info.java | 1 +
library/web/style.css | 4 +-
.../templates/WebLibraryServerTemplates.java | 4 +
library/web/templates/bookline.html | 1 +
library/web/templates/browser.html | 18 +
library/web/templates/browser.option.html | 1 +
library/web/templates/browser.select.html | 3 +
library/web/templates/index.banner.html | 5 +
library/web/templates/index.post.html | 2 +
library/web/templates/package-info.java | 1 +
library/web/templates/viewer.desc.html | 9 +
library/web/templates/viewer.descline.html | 1 +
library/web/templates/viewer.image.html | 6 +
library/web/templates/viewer.link.html | 1 +
library/web/templates/viewer.navbar.html | 11 +
.../templates/viewer.optionbar.button.html | 1 +
library/web/templates/viewer.optionbar.html | 2 +
library/web/templates/viewer.text.html | 4 +
output/BasicOutput.java | 6 -
output/InfoCover.java | 97 +++-
reader/TextOutput.java | 14 +
supported/BasicSupportPara.java | 13 +-
supported/InfoReader.java | 39 +-
supported/Text.java | 17 +-
30 files changed, 495 insertions(+), 302 deletions(-)
delete mode 100644 library/web/index.post.html
create mode 100644 library/web/package-info.java
create mode 100644 library/web/templates/WebLibraryServerTemplates.java
create mode 100644 library/web/templates/bookline.html
create mode 100644 library/web/templates/browser.html
create mode 100644 library/web/templates/browser.option.html
create mode 100644 library/web/templates/browser.select.html
create mode 100644 library/web/templates/index.banner.html
create mode 100644 library/web/templates/index.post.html
create mode 100644 library/web/templates/package-info.java
create mode 100644 library/web/templates/viewer.desc.html
create mode 100644 library/web/templates/viewer.descline.html
create mode 100644 library/web/templates/viewer.image.html
create mode 100644 library/web/templates/viewer.link.html
create mode 100644 library/web/templates/viewer.navbar.html
create mode 100644 library/web/templates/viewer.optionbar.button.html
create mode 100644 library/web/templates/viewer.optionbar.html
create mode 100644 library/web/templates/viewer.text.html
diff --git a/data/MetaData.java b/data/MetaData.java
index bcebf754..2e34ef98 100644
--- a/data/MetaData.java
+++ b/data/MetaData.java
@@ -9,6 +9,12 @@ import be.nikiroo.utils.StringUtils;
/**
* The meta data associated to a {@link Story} object.
+ *
+ * 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.
+ *
+ * The cover is never fetched until the story is.
*
* @author niki
*/
@@ -120,6 +126,10 @@ public class MetaData implements Cloneable, Comparable, Serializable {
* The story resume (a.k.a. description).
*
* This can be NULL if we don't have a resume for this {@link Story}.
+ *
+ * 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, Serializable {
/**
* The story resume (a.k.a. description).
+ *
+ * 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, Serializable {
/**
* The cover image of the story if any (can be NULL).
+ *
+ * The cover is not fetched until the story is.
*
* @return the cover
*/
@@ -148,6 +164,8 @@ public class MetaData implements Cloneable, Comparable, Serializable {
/**
* The cover image of the story if any (can be NULL).
+ *
+ * The cover is not fetched until the story is.
*
* @param cover
* the cover to set
diff --git a/library/BasicLibrary.java b/library/BasicLibrary.java
index 8b72f19b..f77d0edc 100644
--- a/library/BasicLibrary.java
+++ b/library/BasicLibrary.java
@@ -475,6 +475,8 @@ abstract public class BasicLibrary {
/**
* Retrieve a specific {@link Story}.
+ *
+ * Note that it will update both the cover and the resume in meta .
*
* @param luid
* the Library UID of the story
@@ -513,6 +515,8 @@ abstract public class BasicLibrary {
/**
* Retrieve a specific {@link Story}.
+ *
+ * Note that it will update both the cover and the resume in meta .
*
* @param luid
* the LUID of the story
diff --git a/library/LocalLibrary.java b/library/LocalLibrary.java
index f655d4d0..25f2ec96 100644
--- a/library/LocalLibrary.java
+++ b/library/LocalLibrary.java
@@ -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;
}
diff --git a/library/WebLibraryServerHtml.java b/library/WebLibraryServerHtml.java
index 8895fb83..69d86717 100644
--- a/library/WebLibraryServerHtml.java
+++ b/library/WebLibraryServerHtml.java
@@ -22,6 +22,7 @@ import be.nikiroo.fanfix.data.Paragraph.ParagraphType;
import be.nikiroo.fanfix.data.Story;
import be.nikiroo.fanfix.library.WebLibraryServer.WLoginResult;
import be.nikiroo.fanfix.library.web.WebLibraryServerIndex;
+import be.nikiroo.fanfix.library.web.templates.WebLibraryServerTemplates;
import be.nikiroo.fanfix.reader.TextOutput;
import be.nikiroo.utils.IOUtils;
import be.nikiroo.utils.NanoHTTPD;
@@ -173,13 +174,13 @@ abstract class WebLibraryServerHtml implements Runnable {
}
Response rep = null;
- if (!login.isSuccess()
- && WebLibraryUrls.isSupportedUrl(uri, true)) {
- rep = loginPage(login, uri);
- }
+ try {
+ if (!login.isSuccess()
+ && WebLibraryUrls.isSupportedUrl(uri, true)) {
+ rep = loginPage(login, uri);
+ }
- if (rep == null) {
- try {
+ if (rep == null) {
if (WebLibraryUrls.isSupportedUrl(uri, false)) {
if (WebLibraryUrls.INDEX_URL.equals(uri)) {
rep = root(session, cookies, login);
@@ -253,13 +254,12 @@ abstract class WebLibraryServerHtml implements Runnable {
NanoHTTPD.MIME_PLAINTEXT, "Not Found");
}
}
- } catch (Exception e) {
- Instance.getInstance().getTraceHandler().error(
- new IOException("Cannot process web request",
- e));
- rep = newFixedLengthResponse(Status.INTERNAL_ERROR,
- NanoHTTPD.MIME_PLAINTEXT, "An error occured");
}
+ } catch (Exception e) {
+ Instance.getInstance().getTraceHandler().error(
+ new IOException("Cannot process web request", e));
+ rep = newFixedLengthResponse(Status.INTERNAL_ERROR,
+ NanoHTTPD.MIME_PLAINTEXT, "An error occured");
}
return rep;
@@ -309,31 +309,34 @@ abstract class WebLibraryServerHtml implements Runnable {
this.tracer = tracer;
}
- private Response loginPage(WLoginResult login, String uri) {
+ private Response loginPage(WLoginResult login, String uri)
+ throws IOException {
StringBuilder builder = new StringBuilder();
- appendPreHtml(builder, true);
+ builder.append(getTemplateIndexPreBanner(true));
if (login.isBadLogin()) {
- builder.append("
Bad login or password
");
+ builder.append(
+ "\t\tBad login or password
");
} else if (login.isBadCookie()) {
- builder.append("Your session timed out
");
+ builder.append(
+ "\t\tYour session timed out
");
}
if (WebLibraryUrls.LOGOUT_URL.equals(uri)) {
uri = WebLibraryUrls.INDEX_URL;
}
+ builder.append("\t\t\n");
+ "\t\t\tYou must be logged into the system to see the stories.
");
+ builder.append("\t\t\t \n");
+ builder.append("\t\t\t \n");
+ builder.append("\t\t\t \n");
+ builder.append("\t\t\n");
- appendPostHtml(builder);
+ builder.append(getTemplate("index.post"));
return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
NanoHTTPD.MIME_HTML, builder.toString());
@@ -345,7 +348,7 @@ abstract class WebLibraryServerHtml implements Runnable {
MetaResultList result = new MetaResultList(metas(login));
StringBuilder builder = new StringBuilder();
- appendPreHtml(builder, true);
+ builder.append(getTemplateIndexPreBanner(true));
Map params = session.getParms();
@@ -369,45 +372,56 @@ abstract class WebLibraryServerHtml implements Runnable {
// TODO: javascript in realtime, using visible=false + hide [submit]
- builder.append("\n");
-
- builder.append("\t");
+ builder.append("\t\t
\n");
for (MetaData meta : result.getMetas()) {
if (!filter.isEmpty() && !meta.getTitle().toLowerCase()
.contains(filter.toLowerCase())) {
@@ -478,38 +487,33 @@ abstract class WebLibraryServerHtml implements Runnable {
continue;
}
- builder.append("
\n");
+
+ builder.append(getTemplate("bookline") //
+ .replace("${href}",
+ WebLibraryUrls.getViewUrl(meta.getLuid(), null,
+ null)) //
+ .replace("${luid}", meta.getLuid()) //
+ .replace("${title}", meta.getTitle()) //
+ .replace("${author}", author) //
+ .replace("${cachedClass}", cachedClass) //
+ .replace("${cached}", cached) //
+ );
}
- builder.append("
");
+ builder.append("\t\t
\n");
+
+ builder.append(getTemplate("index.post"));
- appendPostHtml(builder);
return NanoHTTPD.newFixedLengthResponse(builder.toString());
}
@@ -563,9 +567,6 @@ abstract class WebLibraryServerHtml implements Runnable {
NanoHTTPD.MIME_PLAINTEXT, "Story not found");
}
- StringBuilder builder = new StringBuilder();
- appendPreHtml(builder, false);
-
// For images documents, always go to the images if not chap 0 desc
if (story.getMeta().isImageDocument()) {
if (chapter > 0 && paragraph <= 0)
@@ -586,7 +587,7 @@ abstract class WebLibraryServerHtml implements Runnable {
String first, previous, next, last;
- StringBuilder content = new StringBuilder();
+ String viewer = "";
String disabledLeft = "";
String disabledRight = "";
@@ -604,35 +605,37 @@ abstract class WebLibraryServerHtml implements Runnable {
last = WebLibraryUrls.getViewUrl(luid,
story.getChapters().size(), null);
- StringBuilder desc = new StringBuilder();
-
+ String desc = "";
if (chapter <= 0) {
- desc.append("");
- desc.append(story.getMeta().getTitle());
- desc.append(" \n");
- desc.append("\n");
- desc.append("\t
\n");
- desc.append("\t\t \n");
- desc.append("\t \n");
- desc.append("\t
\n");
+ StringBuilder desclines = new StringBuilder();
Map details = BasicLibrary
.getMetaDesc(story.getMeta());
for (String key : details.keySet()) {
- appendTableRow(desc, 2, key, details.get(key));
+ desclines.append(getTemplate("viewer.descline") //
+ .replace("${key}", key) //
+ .replace("${value}", details.get(key)) //
+ );
}
- desc.append("\t
\n");
- desc.append("
\n");
- desc.append("Description \n");
+
+ desc = getTemplate("viewer.desc") //
+ .replace("${title}", story.getMeta().getTitle()) //
+ .replace("${href}", next) //
+ .replace("${cover}",
+ WebLibraryUrls.getStoryUrlCover(luid)) //
+ .replace("${details}", desclines.toString()) //
+ ;
}
- content.append("\n");
- content.append(desc);
- String description = new TextOutput(false).convert(chap,
- chapter > 0);
- content.append(chap.getParagraphs().size() <= 0
- ? "No content provided."
- : description);
- content.append("
\n");
+ viewer = getTemplate("viewer.text") //
+ .replace("${desc}", desc) //
+ ;
+ if (chap.getParagraphs().size() <= 0) {
+ viewer = viewer.replace("${content}",
+ "No content provided.");
+ } else {
+ viewer = viewer.replace("${content}",
+ new TextOutput(false).convert(chap, chapter > 0));
+ }
if (chapter <= 0)
disabledLeft = " disabled='disbaled'";
@@ -689,44 +692,39 @@ abstract class WebLibraryServerHtml implements Runnable {
}
}
- String javascript = "document.getElementById(\"previous\").click(); return false;";
- content.append(String.format("" //
- + ""
- + " "
- + " ", //
- javascript, //
- next, //
- zoomStyle, //
- WebLibraryUrls.getStoryUrl(luid, chapter,
- paragraph)));
+ viewer = getTemplate("viewer.image") //
+ .replace("${href}", next) //
+ .replace("${zoomStyle}", zoomStyle) //
+ .replace("${src}", WebLibraryUrls.getStoryUrl(luid,
+ chapter, paragraph)) //
+ ;
} else {
- content.append(String.format("" //
- + "%s
", //
- para.getContent()));
+ viewer = getTemplate("viewer.text") //
+ .replace("${desc}", "") //
+ .replace("${content}",
+ new TextOutput(false).convert(para)) //
+ ;
}
}
- builder.append(String.format("" //
- + "\n" //
- + "\t
<< \n"//
- + "\t
< \n" //
- + "\t
\n" //
- + "\t\t
%d
\n" //
- + "\t\t
\n", //
- disabledLeft, first, //
- disabledLeft, previous, //
- paragraph > 0 ? paragraph : chapter //
- ));
-
// List of chap/para links
-
- appendItemA(builder, 3, WebLibraryUrls.getViewUrl(luid, 0, null),
- "Description", paragraph == 0 && chapter == 0);
+ StringBuilder links = new StringBuilder();
+ links.append(getTemplate("viewer.link") //
+ .replace("${link}",
+ WebLibraryUrls.getViewUrl(luid, 0, null)) //
+ .replace("${class}",
+ paragraph == 0 && chapter == 0 ? "selected" : "") //
+ .replace("${name}", "Description") //
+ );
if (paragraph > 0) {
for (int i = 1; i <= chap.getParagraphs().size(); i++) {
- appendItemA(builder, 3,
- WebLibraryUrls.getViewUrl(luid, chapter, i),
- "Image " + i, paragraph == i);
+ links.append(getTemplate("viewer.link") //
+ .replace("${link}",
+ WebLibraryUrls.getViewUrl(luid, chapter, i)) //
+ .replace("${class}",
+ paragraph == i ? "selected" : "") //
+ .replace("${name}", "Image " + i) //
+ );
}
} else {
int i = 1;
@@ -736,51 +734,79 @@ abstract class WebLibraryServerHtml implements Runnable {
chapName += ": " + c.getName();
}
- appendItemA(builder, 3,
- WebLibraryUrls.getViewUrl(luid, i, null), chapName,
- chapter == i);
+ links.append(getTemplate("viewer.link") //
+ .replace("${link}",
+ WebLibraryUrls.getViewUrl(luid, i, null)) //
+ .replace("${class}", chapter == i ? "selected" : "") //
+ .replace("${name}", chapName) //
+ );
i++;
}
}
- builder.append(String.format("" //
- + "\t\t
\n" //
- + "\t
\n" //
- + "\t
> \n" //
- + "\t
>> \n"//
- + "
\n", //
- disabledRight, next, //
- disabledRight, last //
- ));
-
- builder.append(content);
+ // Buttons on the optionbar
- builder.append("\n", //
- disabledZoomReal,
- uri + "?optionName=zoom&optionValue=real", //
- disabledZoomWidth,
- uri + "?optionName=zoom&optionValue=width", //
- disabledZoomHeight,
- uri + "?optionName=zoom&optionValue=height" //
- ));
- }
+ // Full content
+
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(getTemplateIndexPreBanner(false));
+
+ builder.append(getTemplate("viewer.navbar") //
+ .replace("${disabledFirst}", disabledLeft) //
+ .replace("${disabledPrevious}", disabledLeft) //
+ .replace("${disabledNext}", disabledRight) //
+ .replace("${disabledLast}", disabledRight) //
+ .replace("${hrefFirst}", first) //
+ .replace("${hrefPrevious}", previous) //
+ .replace("${hrefNext}", next) //
+ .replace("${hrefLast}", last) //
+ .replace("${current}",
+ "" + (paragraph > 0 ? paragraph : chapter)) //
+ .replace("${links}", links.toString()) //
+ );
+
+ builder.append(viewer);
+
+ builder.append(getTemplate("viewer.optionbar") //
+ .replace("${classSize}", (paragraph > 0 ? "s4" : "s1")) //
+ .replace("${buttons}", buttons.toString()) //
+ );
+
+ builder.append(getTemplate("index.post"));
- appendPostHtml(builder);
return NanoHTTPD.newFixedLengthResponse(Status.OK,
NanoHTTPD.MIME_HTML, builder.toString());
} catch (IOException e) {
@@ -799,22 +825,8 @@ abstract class WebLibraryServerHtml implements Runnable {
return NanoHTTPD.newChunkedResponse(Status.OK, mimeType, in);
}
- private String getContentOf(String file) {
- InputStream in = IOUtils.openResource(WebLibraryServerIndex.class,
- file);
- if (in != null) {
- try {
- return IOUtils.readSmallStream(in);
- } catch (IOException e) {
- Instance.getInstance().getTraceHandler().error(
- new IOException("Cannot get file: index.pre.html", e));
- }
- }
-
- return "";
- }
-
- private void appendPreHtml(StringBuilder builder, boolean banner) {
+ private String getTemplateIndexPreBanner(boolean banner)
+ throws IOException {
String favicon = "favicon.ico";
String icon = Instance.getInstance().getUiConfig()
.getString(UiConfig.PROGRAM_ICON);
@@ -822,70 +834,44 @@ abstract class WebLibraryServerHtml implements Runnable {
favicon = "icon_" + icon.replace("-", "_") + ".png";
}
- builder.append(
- getContentOf("index.pre.html").replace("favicon.ico", favicon));
+ String html = getTemplate("index.pre") //
+ .replace("${title}", "Fanfix") //
+ .replace("${favicon}", favicon) //
+ ;
if (banner) {
- builder.append("\n");
- builder.append("\t
\n");
- builder.append("\t
Fanfix \n");
- builder.append("\t
") //
- .append(Version.getCurrentVersion()) //
- .append(" \n");
- builder.append("
\n");
+ html += getTemplate("index.banner") //
+ .replace("${favicon}", favicon) //
+ .replace("${version}",
+ Version.getCurrentVersion().toString()) //
+ ;
}
- }
- private void appendPostHtml(StringBuilder builder) {
- builder.append(getContentOf("index.post.html"));
+ return html;
}
- private void appendOption(StringBuilder builder, int depth, String name,
- String value, String selected) {
- for (int i = 0; i < depth; i++) {
- builder.append("\t");
- }
- builder.append("").append(name).append(" \n");
- }
-
- private void appendTableRow(StringBuilder builder, int depth,
- String... tds) {
- for (int i = 0; i < depth; i++) {
- builder.append("\t");
+ selectedAttribute = " selected='selected'";
}
- int col = 1;
- builder.append("");
- for (String td : tds) {
- builder.append("");
- builder.append(td);
- builder.append(" ");
- }
- builder.append(" \n");
+ return getTemplate("browser.option" //
+ .replace("${value}", value) //
+ .replace("${selected}", selectedAttribute) //
+ .replace("${name}", name) //
+ );
}
- private void appendItemA(StringBuilder builder, int depth, String link,
- String name, boolean selected) {
- for (int i = 0; i < depth; i++) {
- builder.append("\t");
- }
-
- builder.append("");
- builder.append(name);
- builder.append(" \n");
}
}
diff --git a/library/web/index.post.html b/library/web/index.post.html
deleted file mode 100644
index d4e09056..00000000
--- a/library/web/index.post.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
-
+
diff --git a/library/web/package-info.java b/library/web/package-info.java
new file mode 100644
index 00000000..69bff54a
--- /dev/null
+++ b/library/web/package-info.java
@@ -0,0 +1 @@
+package be.nikiroo.fanfix.library.web;
\ No newline at end of file
diff --git a/library/web/style.css b/library/web/style.css
index 4196aeba..b12a24fa 100644
--- a/library/web/style.css
+++ b/library/web/style.css
@@ -310,13 +310,13 @@ a.viewer.link:hover {
display: block;
}
-.desc .details .col1 {
+.desc .details .col.key {
font-weight: bold;
padding-left: 5px;
padding-right: 5px;
}
-.desc .details .col2 {
+.desc .details .col.value {
color: #AAA391;
}
diff --git a/library/web/templates/WebLibraryServerTemplates.java b/library/web/templates/WebLibraryServerTemplates.java
new file mode 100644
index 00000000..482a1b82
--- /dev/null
+++ b/library/web/templates/WebLibraryServerTemplates.java
@@ -0,0 +1,4 @@
+package be.nikiroo.fanfix.library.web.templates;
+
+public class WebLibraryServerTemplates {
+}
diff --git a/library/web/templates/bookline.html b/library/web/templates/bookline.html
new file mode 100644
index 00000000..9b1a6b78
--- /dev/null
+++ b/library/web/templates/bookline.html
@@ -0,0 +1 @@
+
diff --git a/library/web/templates/browser.html b/library/web/templates/browser.html
new file mode 100644
index 00000000..f3f30478
--- /dev/null
+++ b/library/web/templates/browser.html
@@ -0,0 +1,18 @@
+
diff --git a/library/web/templates/browser.option.html b/library/web/templates/browser.option.html
new file mode 100644
index 00000000..49f7b5b1
--- /dev/null
+++ b/library/web/templates/browser.option.html
@@ -0,0 +1 @@
+
${name}
diff --git a/library/web/templates/browser.select.html b/library/web/templates/browser.select.html
new file mode 100644
index 00000000..447d845a
--- /dev/null
+++ b/library/web/templates/browser.select.html
@@ -0,0 +1,3 @@
+
+
+${options}
diff --git a/library/web/templates/index.banner.html b/library/web/templates/index.banner.html
new file mode 100644
index 00000000..c2cd1e7f
--- /dev/null
+++ b/library/web/templates/index.banner.html
@@ -0,0 +1,5 @@
+
+
+
Fanfix
+
${version}
+
diff --git a/library/web/templates/index.post.html b/library/web/templates/index.post.html
new file mode 100644
index 00000000..52ba19e7
--- /dev/null
+++ b/library/web/templates/index.post.html
@@ -0,0 +1,2 @@
+
+