import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import be.nikiroo.fanfix.Instance;
import be.nikiroo.fanfix.bundles.Config;
-import be.nikiroo.fanfix.bundles.UiConfig;
import be.nikiroo.fanfix.data.Chapter;
import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Paragraph;
private NanoHTTPD server;
protected TraceHandler tracer = new TraceHandler();
+ WebLibraryServerTemplates templates = WebLibraryServerTemplates
+ .getInstance();
+
abstract protected WLoginResult login(String who, String cookie);
abstract protected WLoginResult login(String who, String key,
private Response loginPage(WLoginResult login, String uri)
throws IOException {
- StringBuilder builder = new StringBuilder();
-
- builder.append(getTemplateIndexPreBanner(true));
+ List<Template> content = new ArrayList<Template>();
if (login.isBadLogin()) {
- builder.append(
- "\t\t<div class='error'>Bad login or password</div>");
+ content.add(templates.message("Bad login or password", true));
} else if (login.isBadCookie()) {
- builder.append(
- "\t\t<div class='error'>Your session timed out</div>");
- }
-
- if (WebLibraryUrls.LOGOUT_URL.equals(uri)) {
- uri = WebLibraryUrls.INDEX_URL;
+ content.add(templates.message("Your session timed out", true));
}
- builder.append("\t\t<form method='POST' action='" + uri
- + "' class='login'>\n");
- builder.append(
- "\t\t\t<p>You must be logged into the system to see the stories.</p>");
- builder.append("\t\t\t<input type='text' name='login' />\n");
- builder.append("\t\t\t<input type='password' name='password' />\n");
- builder.append("\t\t\t<input type='submit' value='Login' />\n");
- builder.append("\t\t</form>\n");
-
- builder.append(getTemplate("index.post"));
+ content.add(templates.login(uri));
- return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
- NanoHTTPD.MIME_HTML, builder.toString());
+ return NanoHTTPD.newChunkedResponse(Status.FORBIDDEN,
+ NanoHTTPD.MIME_HTML, templates.index(true, content).read());
}
private Response root(IHTTPSession session, Map<String, String> cookies,
WLoginResult login) throws IOException {
BasicLibrary lib = Instance.getInstance().getLibrary();
MetaResultList result = new MetaResultList(metas(login));
- StringBuilder builder = new StringBuilder();
-
- builder.append(getTemplateIndexPreBanner(true));
Map<String, String> params = session.getParms();
// TODO: javascript in realtime, using visible=false + hide [submit]
- StringBuilder selects = new StringBuilder();
+ List<Template> selects = new ArrayList<Template>();
boolean sourcesSel = false;
boolean authorsSel = false;
boolean tagsSel = false;
- String selectTemplate = getTemplate("browser.select");
-
if (!browser.isEmpty()) {
- StringBuilder options = new StringBuilder();
+ List<Template> options = new ArrayList<Template>();
if (browser.equals("sources")) {
sourcesSel = true;
// TODO: if 1 group -> no group
Map<String, List<String>> sources = result.getSourcesGrouped();
for (String source : sources.keySet()) {
- options.append(
- getTemplateBrowserOption(source, source, browser2));
+ options.add(
+ templates.browserOption(source, source, browser2));
}
} else if (browser.equals("authors")) {
authorsSel = true;
// TODO: if 1 group -> no group
Map<String, List<String>> authors = result.getAuthorsGrouped();
for (String author : authors.keySet()) {
- options.append(
- getTemplateBrowserOption(author, author, browser2));
+ options.add(
+ templates.browserOption(author, author, browser2));
}
} else if (browser.equals("tags")) {
tagsSel = true;
filterTag = browser2.isEmpty() ? filterTag : browser2;
for (String tag : result.getTags()) {
- options.append(
- getTemplateBrowserOption(tag, tag, browser2));
+ options.add(templates.browserOption(tag, tag, browser2));
}
}
- selects.append(selectTemplate //
- .replace("${name}", "browser2") //
- .replace("${value}", browser2) //
- .replace("${options}", options.toString()) //
- );
+ selects.add(templates.browserSelect("browser2", browser2, options));
}
if (!browser2.isEmpty()) {
- StringBuilder options = new StringBuilder();
+ List<Template> options = new ArrayList<Template>();
if (browser.equals("sources")) {
filterSource = browser3.isEmpty() ? filterSource : browser3;
if (sources != null && !sources.isEmpty()) {
// TODO: single empty value
for (String source : sources) {
- options.append(getTemplateBrowserOption(source, source,
+ options.add(templates.browserOption(source, source,
browser3));
}
}
if (authors != null && !authors.isEmpty()) {
// TODO: single empty value
for (String author : authors) {
- options.append(getTemplateBrowserOption(author, author,
+ options.add(templates.browserOption(author, author,
browser3));
}
}
}
- selects.append(selectTemplate //
- .replace("${name}", "browser3") //
- .replace("${value}", browser3) //
- .replace("${options}", options.toString()) //
- );
+ selects.add(templates.browserSelect("browser3", browser3, options));
}
- String sel = "selected='selected'";
- builder.append(getTemplate("browser") //
- .replace("${sourcesSelected}", sourcesSel ? sel : "") //
- .replace("${authorsSelected}", authorsSel ? sel : "") //
- .replace("${tagsSelected}", tagsSel ? sel : "") //
- .replace("${filter}", filter) //
- .replace("${selects}", selects.toString()) //
- );
-
- builder.append("\t\t<div class='books'>\n");
+ List<Template> booklines = new ArrayList<Template>();
for (MetaData meta : result.getMetas()) {
if (!filter.isEmpty() && !meta.getTitle().toLowerCase()
.contains(filter.toLowerCase())) {
author = "(" + meta.getAuthor() + ")";
}
- String cachedClass = "cached";
- String cached = "◉";
- if (!lib.isCached(meta.getLuid())) {
- cachedClass = "uncached";
- cached = "○";
- }
-
- 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) //
- );
+ booklines.add(templates.bookline( //
+ meta.getLuid(), //
+ WebLibraryUrls.getViewUrl(meta.getLuid(), null, null), //
+ meta.getTitle(), //
+ author, //
+ lib.isCached(meta.getLuid()) //
+ ));
}
- builder.append("\t\t</div>\n");
- builder.append(getTemplate("index.post"));
+ // Add the browser in front of the booklines
+ booklines.add(0, templates.browser(browser, filter, selects));
- return NanoHTTPD.newFixedLengthResponse(builder.toString());
+ return newInputStreamResponse(NanoHTTPD.MIME_HTML,
+ templates.index(true, booklines).read());
}
private Response getViewer(Map<String, String> cookies, String uri,
String first, previous, next, last;
- String viewer = "";
-
- String disabledLeft = "";
- String disabledRight = "";
- String disabledZoomReal = "";
- String disabledZoomWidth = "";
- String disabledZoomHeight = "";
+ boolean disabledLeft = false;
+ boolean disabledRight = false;
+ boolean disabledZoomReal = false;
+ boolean disabledZoomWidth = false;
+ boolean disabledZoomHeight = false;
+ Template viewerItem = null;
if (paragraph <= 0) {
first = WebLibraryUrls.getViewUrl(luid, 0, null);
previous = WebLibraryUrls.getViewUrl(luid,
last = WebLibraryUrls.getViewUrl(luid,
story.getChapters().size(), null);
- String desc = "";
+ Template desc = null;
if (chapter <= 0) {
- StringBuilder desclines = new StringBuilder();
+ List<Template> desclines = new ArrayList<Template>();
Map<String, String> details = BasicLibrary
.getMetaDesc(story.getMeta());
for (String key : details.keySet()) {
- desclines.append(getTemplate("viewer.descline") //
- .replace("${key}", key) //
- .replace("${value}", details.get(key)) //
- );
+ desclines.add(templates.viewerDescline(key,
+ details.get(key)));
}
- desc = getTemplate("viewer.desc") //
- .replace("${title}", story.getMeta().getTitle()) //
- .replace("${href}", next) //
- .replace("${cover}",
- WebLibraryUrls.getStoryUrlCover(luid)) //
- .replace("${details}", desclines.toString()) //
- ;
+ desc = templates.viewerDesc( //
+ story.getMeta().getTitle(), //
+ next, //
+ WebLibraryUrls.getStoryUrlCover(luid), //
+ desclines //
+ );
}
- viewer = getTemplate("viewer.text") //
- .replace("${desc}", desc) //
- ;
+ String content;
if (chap.getParagraphs().size() <= 0) {
- viewer = viewer.replace("${content}",
- "No content provided.");
+ content = "No content provided.";
} else {
- viewer = viewer.replace("${content}",
- new TextOutput(false).convert(chap, chapter > 0));
+ content = new TextOutput(false).convert(chap, chapter > 0);
}
+ viewerItem = templates.viewerText(desc, content);
+
if (chapter <= 0)
- disabledLeft = " disabled='disbaled'";
+ disabledLeft = true;
if (chapter >= story.getChapters().size())
- disabledRight = " disabled='disbaled'";
+ disabledRight = true;
} else {
first = WebLibraryUrls.getViewUrl(luid, chapter, 1);
previous = WebLibraryUrls.getViewUrl(luid, chapter,
chap.getParagraphs().size());
if (paragraph <= 1)
- disabledLeft = " disabled='disbaled'";
+ disabledLeft = true;
if (paragraph >= chap.getParagraphs().size())
- disabledRight = " disabled='disbaled'";
+ disabledRight = true;
// First -> previous *chapter*
if (chapter > 0)
- disabledLeft = "";
+ disabledLeft = false;
first = WebLibraryUrls.getViewUrl(luid,
(Math.max(chapter - 1, 0)), null);
if (paragraph <= 1) {
if (para.getType() == ParagraphType.IMAGE) {
String zoomStyle = "max-width: 100%;";
- disabledZoomWidth = " disabled='disabled'";
+ disabledZoomWidth = true;
String zoomOption = cookies.get("zoom");
if (zoomOption != null && !zoomOption.isEmpty()) {
if (zoomOption.equals("real")) {
zoomStyle = "";
- disabledZoomWidth = "";
- disabledZoomReal = " disabled='disabled'";
+ disabledZoomWidth = false;
+ disabledZoomReal = true;
} else if (zoomOption.equals("width")) {
zoomStyle = "max-width: 100%;";
} else if (zoomOption.equals("height")) {
// see height of navbar + optionbar
zoomStyle = "max-height: calc(100% - 128px);";
- disabledZoomWidth = "";
- disabledZoomHeight = " disabled='disabled'";
+ disabledZoomWidth = false;
+ disabledZoomHeight = true;
}
}
- viewer = getTemplate("viewer.image") //
- .replace("${href}", next) //
- .replace("${zoomStyle}", zoomStyle) //
- .replace("${src}", WebLibraryUrls.getStoryUrl(luid,
- chapter, paragraph)) //
- ;
+ viewerItem = templates.viewerImage(WebLibraryUrls
+ .getStoryUrl(luid, chapter, paragraph), next,
+ zoomStyle);
} else {
- viewer = getTemplate("viewer.text") //
- .replace("${desc}", "") //
- .replace("${content}",
- new TextOutput(false).convert(para)) //
- ;
+ viewerItem = templates.viewerText(null,
+ new TextOutput(false).convert(para));
}
}
- // List of chap/para links
- 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") //
- );
+ // List of chap/para links for navbar
+
+ List<Template> links = new ArrayList<Template>();
+ links.add(templates.viewerLink( //
+ "Description", //
+ WebLibraryUrls.getViewUrl(luid, 0, null), //
+ paragraph == 0 && chapter == 0 //
+ ));
if (paragraph > 0) {
for (int i = 1; i <= chap.getParagraphs().size(); i++) {
- links.append(getTemplate("viewer.link") //
- .replace("${link}",
- WebLibraryUrls.getViewUrl(luid, chapter, i)) //
- .replace("${class}",
- paragraph == i ? "selected" : "") //
- .replace("${name}", "Image " + i) //
- );
+ links.add(templates.viewerLink( //
+ "Image " + i, //
+ WebLibraryUrls.getViewUrl(luid, chapter, i), //
+ paragraph == i //
+ ));
}
} else {
int i = 1;
chapName += ": " + c.getName();
}
- links.append(getTemplate("viewer.link") //
- .replace("${link}",
- WebLibraryUrls.getViewUrl(luid, i, null)) //
- .replace("${class}", chapter == i ? "selected" : "") //
- .replace("${name}", chapName) //
- );
+ links.add(templates.viewerLink( //
+ chapName, //
+ WebLibraryUrls.getViewUrl(luid, i, null), //
+ chapter == i //
+ ));
i++;
}
}
+ // Navbar
+
+ Template navbar = templates.viewerNavbar( //
+ paragraph > 0 ? paragraph : chapter, //
+ links, //
+ first, //
+ previous, //
+ next, //
+ last, //
+ disabledLeft, //
+ disabledLeft, //
+ disabledRight, //
+ disabledRight //
+ );
+
// Buttons on the optionbar
- StringBuilder buttons = new StringBuilder();
- buttons.append(getTemplate("viewer.optionbar.button") //
- .replace("${disabled}", "") //
- .replace("${class}", "back") //
- .replace("${href}", "/") //
- .replace("${value}", "Back") //
- );
+ List<Template> buttons = new ArrayList<Template>();
+ buttons.add(templates.viewerOptionbarButton( //
+ "Back", "/", "back", false));
if (paragraph > 0) {
- buttons.append(getTemplate("viewer.optionbar.button") //
- .replace("${disabled}", disabledZoomReal) //
- .replace("${class}", "zoomreal") //
- .replace("${href}",
- uri + "?optionName=zoom&optionValue=real") //
- .replace("${value}", "1:1") //
- );
- buttons.append(getTemplate("viewer.optionbar.button") //
- .replace("${disabled}", disabledZoomWidth) //
- .replace("${class}", "zoomwidth") //
- .replace("${href}",
- uri + "?optionName=zoom&optionValue=width") //
- .replace("${value}", "Width") //
- );
- buttons.append(getTemplate("viewer.optionbar.button") //
- .replace("${disabled}", disabledZoomHeight) //
- .replace("${class}", "zoomheight") //
- .replace("${href}",
- uri + "?optionName=zoom&optionValue=height") //
- .replace("${value}", "Height") //
- );
+ buttons.add(templates.viewerOptionbarButton( //
+ "1:1", uri + "?optionName=zoom&optionValue=real",
+ "zoomreal", disabledZoomReal));
+ buttons.add(templates.viewerOptionbarButton( //
+ "Width", uri + "?optionName=zoom&optionValue=width",
+ "zoomwidth", disabledZoomWidth));
+ buttons.add(templates.viewerOptionbarButton( //
+ "Height", uri + "?optionName=zoom&optionValue=height",
+ "zoomHeight", disabledZoomHeight));
}
- // 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);
+ // Optionbar
- builder.append(getTemplate("viewer.optionbar") //
- .replace("${classSize}", (paragraph > 0 ? "s4" : "s1")) //
- .replace("${buttons}", buttons.toString()) //
+ Template optionbar = templates.viewerOptionbar( //
+ (paragraph > 0) ? 4 : 1, //
+ buttons //
);
- builder.append(getTemplate("index.post"));
+ // Full content
- return NanoHTTPD.newFixedLengthResponse(Status.OK,
- NanoHTTPD.MIME_HTML, builder.toString());
+ return newInputStreamResponse(NanoHTTPD.MIME_HTML, //
+ templates.index(false, Arrays.asList( //
+ navbar, //
+ viewerItem, //
+ optionbar //
+ )).read());
} catch (IOException e) {
Instance.getInstance().getTraceHandler()
.error(new IOException("Cannot get image: " + uri, e));
}
return NanoHTTPD.newChunkedResponse(Status.OK, mimeType, in);
}
-
- private String getTemplateIndexPreBanner(boolean banner)
- throws IOException {
- String favicon = "favicon.ico";
- String icon = Instance.getInstance().getUiConfig()
- .getString(UiConfig.PROGRAM_ICON);
- if (icon != null) {
- favicon = "icon_" + icon.replace("-", "_") + ".png";
- }
-
- String html = getTemplate("index.pre") //
- .replace("${title}", "Fanfix") //
- .replace("${favicon}", favicon) //
- ;
-
- if (banner) {
- html += getTemplate("index.banner") //
- .replace("${favicon}", favicon) //
- .replace("${version}",
- Version.getCurrentVersion().toString()) //
- ;
- }
-
- return html;
- }
-
- private String getTemplateBrowserOption(String name, String value,
- String selected) throws IOException {
- String selectedAttribute = "";
- if (value.equals(selected)) {
- selectedAttribute = " selected='selected'";
- }
-
- return getTemplate("browser.option" //
- .replace("${value}", value) //
- .replace("${selected}", selectedAttribute) //
- .replace("${name}", name) //
- );
- }
-
- private String getTemplate(String template) throws IOException {
- // TODO: check if it is "slow" -> map cache
- InputStream in = IOUtils.openResource(WebLibraryServerTemplates.class,
- template + ".html");
- try {
- return IOUtils.readSmallStream(in);
- } finally {
- in.close();
- }
- }
}