From 599b05c7917edbe2fe4d6449628f2b261eae2f5e Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Wed, 13 May 2020 10:46:07 +0200 Subject: [PATCH] WebServer: add story description --- .../nikiroo/fanfix/library/BasicLibrary.java | 78 ++++++- .../fanfix/library/WebLibraryServer.java | 219 ++++++++++-------- src/be/nikiroo/fanfix/library/web/style.css | 64 ++++- 3 files changed, 258 insertions(+), 103 deletions(-) diff --git a/src/be/nikiroo/fanfix/library/BasicLibrary.java b/src/be/nikiroo/fanfix/library/BasicLibrary.java index d435f8d7..78f0f620 100644 --- a/src/be/nikiroo/fanfix/library/BasicLibrary.java +++ b/src/be/nikiroo/fanfix/library/BasicLibrary.java @@ -4,11 +4,9 @@ import java.io.File; import java.io.IOException; import java.net.URL; import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.data.MetaData; @@ -122,12 +120,24 @@ abstract public class BasicLibrary { */ public abstract Image getCover(String luid) throws IOException; - // TODO: ensure it is the main used interface + /** + * Retrieve the list of {@link MetaData} known by this {@link BasicLibrary} + * in a easy-to-filter version. + * + * @param pg + * the optional {@link Progress} + * @return the list of {@link MetaData} as a {@link MetaResultList} you can + * query + * @throws IOException + * in case of I/O eror + */ public MetaResultList getList(Progress pg) throws IOException { + // TODO: ensure it is the main used interface + return new MetaResultList(getMetas(pg)); } - // TODO: make something for (normal and custom) not-story covers + // TODO: make something for (normal and custom) non-story covers /** * Return the cover image associated to this source. @@ -378,6 +388,9 @@ abstract public class BasicLibrary { } /** + * @return the same as getList() + * @throws IOException + * in case of I/O error * @deprecated please use {@link BasicLibrary#getList()} and * {@link MetaResultList#getSources()} instead. */ @@ -387,6 +400,9 @@ abstract public class BasicLibrary { } /** + * @return the same as getList() + * @throws IOException + * in case of I/O error * @deprecated please use {@link BasicLibrary#getList()} and * {@link MetaResultList#getSourcesGrouped()} instead. */ @@ -396,6 +412,9 @@ abstract public class BasicLibrary { } /** + * @return the same as getList() + * @throws IOException + * in case of I/O error * @deprecated please use {@link BasicLibrary#getList()} and * {@link MetaResultList#getAuthors()} instead. */ @@ -405,9 +424,13 @@ abstract public class BasicLibrary { } /** + * @return the same as getList() + * @throws IOException + * in case of I/O error * @deprecated please use {@link BasicLibrary#getList()} and * {@link MetaResultList#getAuthorsGrouped()} instead. */ + @Deprecated public Map> getAuthorsGrouped() throws IOException { return getList().getAuthorsGrouped(); } @@ -901,4 +924,49 @@ abstract public class BasicLibrary { pg.done(); } + + /** + * Describe a {@link Story} from its {@link MetaData} and return a list of + * title/value that represent this {@link Story}. + * + * @param meta + * the {@link MetaData} to represent + * + * @return the information, translated and sorted + */ + static public Map getMetaDesc(MetaData meta) { + Map metaDesc = new LinkedHashMap(); + + // TODO: i18n + + StringBuilder tags = new StringBuilder(); + for (String tag : meta.getTags()) { + if (tags.length() > 0) { + tags.append(", "); + } + tags.append(tag); + } + + // TODO: i18n + metaDesc.put("Author", meta.getAuthor()); + metaDesc.put("Published on", meta.getPublisher()); + metaDesc.put("Publication date", meta.getDate()); + metaDesc.put("Creation date", meta.getCreationDate()); + String count = ""; + if (meta.getWords() > 0) { + count = StringUtils.formatNumber(meta.getWords()); + } + if (meta.isImageDocument()) { + metaDesc.put("Number of images", count); + } else { + metaDesc.put("Number of words", count); + } + metaDesc.put("Source", meta.getSource()); + metaDesc.put("Subject", meta.getSubject()); + metaDesc.put("Language", meta.getLang()); + metaDesc.put("Tags", tags.toString()); + metaDesc.put("URL", meta.getUrl()); + + return metaDesc; + } } diff --git a/src/be/nikiroo/fanfix/library/WebLibraryServer.java b/src/be/nikiroo/fanfix/library/WebLibraryServer.java index 7c5cf425..fe79f96a 100644 --- a/src/be/nikiroo/fanfix/library/WebLibraryServer.java +++ b/src/be/nikiroo/fanfix/library/WebLibraryServer.java @@ -93,8 +93,8 @@ public class WebLibraryServer implements Runnable { subkeys.add(""); for (String subkey : subkeys) { - if (CookieUtils.validateCookie(wookie + subkey - + opts, rehashed)) { + if (CookieUtils.validateCookie( + wookie + subkey + opts, rehashed)) { this.wookie = wookie; this.token = token; this.success = true; @@ -148,7 +148,8 @@ public class WebLibraryServer implements Runnable { Integer port = Instance.getInstance().getConfig() .getInteger(Config.SERVER_PORT); if (port == null) { - throw new IOException("Cannot start web server: port not specified"); + throw new IOException( + "Cannot start web server: port not specified"); } int cacheMb = Instance.getInstance().getConfig() @@ -172,8 +173,8 @@ public class WebLibraryServer implements Runnable { if (!keystorePath.isEmpty()) { File keystoreFile = new File(keystorePath); try { - KeyStore keystore = KeyStore.getInstance(KeyStore - .getDefaultType()); + KeyStore keystore = KeyStore + .getInstance(KeyStore.getDefaultType()); InputStream keystoreStream = new FileInputStream( keystoreFile); try { @@ -225,8 +226,8 @@ public class WebLibraryServer implements Runnable { params.get("login"), whitelist); } else { String token = cookies.get("token"); - login = login(who, token, Instance.getInstance() - .getConfig().getList(Config.SERVER_ALLOWED_SUBKEYS)); + login = login(who, token, Instance.getInstance().getConfig() + .getList(Config.SERVER_ALLOWED_SUBKEYS)); } if (login.isSuccess()) { @@ -235,21 +236,21 @@ public class WebLibraryServer implements Runnable { } // refresh token - session.getCookies() - .set(new Cookie("token", login.getToken(), - "30; path=/")); + session.getCookies().set(new Cookie("token", + login.getToken(), "30; path=/")); // set options String optionName = params.get("optionName"); if (optionName != null && !optionName.isEmpty()) { + String optionNo = params.get("optionNo"); String optionValue = params.get("optionValue"); - if (optionValue == null || optionValue.isEmpty()) { + if (optionNo != null || optionValue == null + || optionValue.isEmpty()) { session.getCookies().delete(optionName); cookies.remove(optionName); } else { - session.getCookies().set( - new Cookie(optionName, optionValue, - "; path=/")); + session.getCookies().set(new Cookie(optionName, + optionValue, "; path=/")); cookies.put(optionName, optionValue); } } @@ -259,7 +260,7 @@ public class WebLibraryServer implements Runnable { if (!login.isSuccess() && (uri.equals("/") // || uri.startsWith(STORY_URL_BASE) // || uri.startsWith(VIEWER_URL_BASE) // - || uri.startsWith(LIST_URL))) { + || uri.startsWith(LIST_URL))) { rep = loginPage(login, uri); } @@ -303,10 +304,9 @@ public class WebLibraryServer implements Runnable { NanoHTTPD.MIME_PLAINTEXT, "Not Found"); } } catch (Exception e) { - Instance.getInstance() - .getTraceHandler() - .error(new IOException( - "Cannot process web request", e)); + Instance.getInstance().getTraceHandler().error( + new IOException("Cannot process web request", + e)); rep = newFixedLengthResponse(Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "An error occured"); } @@ -415,8 +415,8 @@ public class WebLibraryServer implements Runnable { wl = false; } - rw = Instance.getInstance().getConfig() - .getBoolean(Config.SERVER_RW, rw); + rw = Instance.getInstance().getConfig().getBoolean(Config.SERVER_RW, + rw); if (!subkey.isEmpty()) { List allowed = Instance.getInstance().getConfig() .getList(Config.SERVER_ALLOWED_SUBKEYS); @@ -450,9 +450,10 @@ public class WebLibraryServer implements Runnable { uri = "/"; } - builder.append("