From a8209dd0972f751e59153dd80a53f3062042897a Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Fri, 14 Jul 2017 18:36:15 +0200 Subject: [PATCH] Fix: do not sysout/syserr in TUI mode + some fixes --- src/be/nikiroo/fanfix/Cache.java | 12 +-- src/be/nikiroo/fanfix/Instance.java | 86 +++++++++++++++++-- src/be/nikiroo/fanfix/bundles/Config.java | 4 +- .../nikiroo/fanfix/bundles/config.properties | 18 ++-- .../fanfix/reader/TuiReaderApplication.java | 19 ++++ .../fanfix/supported/FimfictionApi.java | 43 +++++++--- 6 files changed, 147 insertions(+), 35 deletions(-) diff --git a/src/be/nikiroo/fanfix/Cache.java b/src/be/nikiroo/fanfix/Cache.java index 9983d78..383fa7c 100644 --- a/src/be/nikiroo/fanfix/Cache.java +++ b/src/be/nikiroo/fanfix/Cache.java @@ -141,10 +141,8 @@ public class Cache { // MUST NOT return null try { InputStream in = load(originalUrl, false, stable); - if (Instance.isDebug()) { - System.err.println("Cache " + (in != null ? "hit" : "miss") - + ": " + url); - } + Instance.trace("Cache " + (in != null ? "hit" : "miss") + ": " + + url); if (in == null) { @@ -226,7 +224,7 @@ public class Cache { * @param getParams * the GET parameters (priority over POST) * @param oauth - * OAuth authorization (aka, "bearer XXXXXXX") + * OAuth authorisation (aka, "bearer XXXXXXX") * @return the {@link InputStream} of the opened page * * @throws IOException @@ -236,9 +234,7 @@ public class Cache { final URL originalUrl, Map postParams, Map getParams, String oauth) throws IOException { - if (Instance.isDebug()) { - System.err.println("Open no cache: " + url); - } + Instance.trace("Open no cache: " + url); URLConnection conn = openConnectionWithCookies(url, support); if (support != null) { diff --git a/src/be/nikiroo/fanfix/Instance.java b/src/be/nikiroo/fanfix/Instance.java index 9b6448e..4cf6e86 100644 --- a/src/be/nikiroo/fanfix/Instance.java +++ b/src/be/nikiroo/fanfix/Instance.java @@ -21,17 +21,57 @@ import be.nikiroo.utils.resources.Bundles; * @author niki */ public class Instance { + /** + * A handler when a recoverable exception was caught by the program. + * + * @author niki + */ + public interface SyserrHandler { + /** + * An exception happened, log it. + * + * @param e + * the exception + * @param showDetails + * show more details (usually equivalent to the value of + * DEBUG) + */ + public void notify(Exception e, boolean showDetails); + } + + /** + * A handler when a trace message is sent. + * + * @author niki + */ + public interface TraceHandler { + /** + * A trace happened, show it. + *

+ * Will only be called if TRACE is true. + * + * @param message + * the trace message + */ + public void trace(String message); + } + private static ConfigBundle config; private static UiConfigBundle uiconfig; private static StringIdBundle trans; private static Cache cache; private static LocalLibrary lib; private static boolean debug; + private static boolean trace; private static File coverDir; private static File readerTmp; private static File remoteDir; private static String configDir; + private static SyserrHandler syserrHandler; + + private static TraceHandler traceHandler; + static { // Most of the rest is dependent upon this: config = new ConfigBundle(); @@ -84,6 +124,7 @@ public class Instance { } debug = Instance.getConfig().getBoolean(Config.DEBUG_ERR, false); + trace = Instance.getConfig().getBoolean(Config.DEBUG_TRACE, false); coverDir = getFile(Config.DEFAULT_COVERS_DIR); File tmp = getFile(Config.CACHE_DIR); readerTmp = getFile(UiConfig.CACHE_DIR_LOCAL_READER); @@ -248,6 +289,26 @@ public class Instance { } } + /** + * Replace the global syserr handler. + * + * @param syserrHandler + * the new syserr handler + */ + public static void setSyserrHandler(SyserrHandler syserrHandler) { + Instance.syserrHandler = syserrHandler; + } + + /** + * Replace the global trace handler. + * + * @param traceHandler + * the new trace handler + */ + public static void setTraceHandler(TraceHandler traceHandler) { + Instance.traceHandler = traceHandler; + } + /** * Report an error to the user * @@ -255,20 +316,31 @@ public class Instance { * the {@link Exception} to report */ public static void syserr(Exception e) { - if (debug) { - e.printStackTrace(); + if (syserrHandler != null) { + syserrHandler.notify(e, debug); } else { - System.err.println(e.getMessage()); + if (debug) { + e.printStackTrace(); + } else { + System.err.println(e.getMessage()); + } } } /** - * The program is in DEBUG mode (more verbose). + * Notify of a debug message. * - * @return TRUE if it is + * @param message + * the message */ - public static boolean isDebug() { - return debug; + public static void trace(String message) { + if (trace) { + if (traceHandler != null) { + traceHandler.trace(message); + } else { + System.out.println(message); + } + } } /** diff --git a/src/be/nikiroo/fanfix/bundles/Config.java b/src/be/nikiroo/fanfix/bundles/Config.java index ae60b75..bd27edf 100644 --- a/src/be/nikiroo/fanfix/bundles/Config.java +++ b/src/be/nikiroo/fanfix/bundles/Config.java @@ -29,6 +29,8 @@ public enum Config { LIBRARY_DIR, // @Meta(description = "boolean", format = Format.BOOLEAN, info = "Show debug information on errors") DEBUG_ERR, // + @Meta(description = "boolean", format = Format.BOOLEAN, info = "Show debug trace information") + DEBUG_TRACE, // @Meta(description = "image format", format = Format.COMBO_LIST, list = { "PNG", "JPG", "BMP" }, info = "Image format to use for cover images") IMAGE_FORMAT_COVER, // @@ -59,7 +61,7 @@ public enum Config { LOGIN_FIMFICTION_APIKEY_CLIENT_ID, // @Meta(description = "An API key required to create a token from FimFiction", format = Format.PASSWORD) LOGIN_FIMFICTION_APIKEY_CLIENT_SECRET, // - @Meta(description = "Do not use the new API, even if we have a token, and force HTML scraping", format = Format.BOOLEAN) + @Meta(description = "Do not use the new API, even if we have a token, and force HTML scraping (default is false, use API if token or ID present)", format = Format.BOOLEAN) LOGIN_FIMFICTION_APIKEY_FORCE_HTML, // @Meta(description = "A token is required to use the beta APIv2 from FimFiction (see APIKEY_CLIENT_*)", format = Format.PASSWORD) LOGIN_FIMFICTION_APIKEY_TOKEN, // diff --git a/src/be/nikiroo/fanfix/bundles/config.properties b/src/be/nikiroo/fanfix/bundles/config.properties index 937c421..6e59fe6 100644 --- a/src/be/nikiroo/fanfix/bundles/config.properties +++ b/src/be/nikiroo/fanfix/bundles/config.properties @@ -17,7 +17,7 @@ CACHE_DIR = CACHE_MAX_TIME_CHANGING = 24 # delay in hours, or 0 for no cache, or -1 for infinite time (default) # (FORMAT: INT) The delay after which a cached resource that is thought to change rarely is considered too old and triggers a refresh -CACHE_MAX_TIME_STABLE = +CACHE_MAX_TIME_STABLE = 720 # string (FORMAT: STRING) The user-agent to use to download files USER_AGENT = Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0 -- ELinks/0.9.3 (Linux 2.6.11 i686; 80x24) # absolute path, $HOME variable supported, / is always accepted as dir separator @@ -28,6 +28,8 @@ DEFAULT_COVERS_DIR = $HOME/bin/epub/ LIBRARY_DIR = $HOME/Books # boolean (FORMAT: BOOLEAN) Show debug information on errors DEBUG_ERR = false +# boolean (FORMAT: BOOLEAN) Show debug trace information +DEBUG_TRACE = false # image format (FORMAT: COMBO_LIST) Image format to use for cover images # ALLOWED VALUES: "PNG" "JPG" "BMP" IMAGE_FORMAT_COVER = png @@ -65,9 +67,15 @@ LOGIN_YIFFSTAR_PASS = # If the last update check was done at least that many days, check for updates at startup (-1 for 'no checks' -- default is 1 day) # (FORMAT: INT) UPDATE_INTERVAL = -# An API key required to use the beta APIv2 from FimFiction +# An API key required to create a token from FimFiction +# (FORMAT: STRING) +LOGIN_FIMFICTION_APIKEY_CLIENT_ID = +# An API key required to create a token from FimFiction # (FORMAT: PASSWORD) -LOGIN_FIMFICTION_APIKEY = -# Do not use the new API, even if we have an API key, and force HTML scraping +LOGIN_FIMFICTION_APIKEY_CLIENT_SECRET = +# Do not use the new API, even if we have a token, and force HTML scraping (default is false, use API if token or ID present) # (FORMAT: BOOLEAN) -LOGIN_FIMFICTION_FORCE_HTML = +LOGIN_FIMFICTION_APIKEY_FORCE_HTML = +# A token is required to use the beta APIv2 from FimFiction (see APIKEY_CLIENT_*) +# (FORMAT: PASSWORD) +LOGIN_FIMFICTION_APIKEY_TOKEN = diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java index f95cbf3..3d6a949 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java @@ -7,6 +7,9 @@ import java.util.List; import jexer.TApplication; import jexer.TMessageBox; import jexer.TWindow; +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.Instance.SyserrHandler; +import be.nikiroo.fanfix.Instance.TraceHandler; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.library.BasicLibrary; @@ -121,6 +124,22 @@ class TuiReaderApplication extends TApplication implements Reader { private void init(Reader reader) { this.reader = reader; + // Do not allow traces/debug to pollute the screen: + Instance.setSyserrHandler(new SyserrHandler() { + @Override + public void notify(Exception e, boolean showDetails) { + // TODO + } + }); + + Instance.setTraceHandler(new TraceHandler() { + @Override + public void trace(String message) { + // TODO + } + }); + // + // Add the menus addFileMenu(); addEditMenu(); diff --git a/src/be/nikiroo/fanfix/supported/FimfictionApi.java b/src/be/nikiroo/fanfix/supported/FimfictionApi.java index 59b593e..b2d75df 100644 --- a/src/be/nikiroo/fanfix/supported/FimfictionApi.java +++ b/src/be/nikiroo/fanfix/supported/FimfictionApi.java @@ -160,14 +160,7 @@ class FimfictionApi extends BasicSupport { @Override protected String getDesc(URL source, InputStream in) { String desc = getKeyJson(json, 0, "type", "story", "description"); - - // TODO: if the description becomes available in html, use it - desc = desc.replace("\\r\\n", "
"); - desc = desc.replace("[i]", "_").replace("[/i]", "_") - .replace("[b]", "*").replace("[/b]", "*"); - desc = desc.replaceAll("\\[[^\\]]*\\]", ""); - - return desc; + return unbbcode(desc); } @Override @@ -228,6 +221,24 @@ class FimfictionApi extends BasicSupport { || "www.fimfiction.net".equals(url.getHost()); } + /** + * Generate a new token from the client ID and secret. + *

+ * Note that those tokens are long-lived, and it would be badly seen to + * create a lot of them without due cause. + *

+ * So, please cache and re-use them. + * + * @param clientId + * the client ID offered on FimFiction + * @param clientSecret + * the client secret that goes with it + * + * @return a new generated token linked to that client ID + * + * @throws IOException + * in case of I/O errors + */ static private String generateOAuth(String clientId, String clientSecret) throws IOException { URL url = new URL("https://www.fimfiction.net/api/v2/token"); @@ -241,18 +252,13 @@ class FimfictionApi extends BasicSupport { String jsonToken = IOUtils.readSmallStream(in); // Extract token type and token from: { - // token_type = "bearer", + // token_type = "Bearer", // access_token = "xxxxxxxxxxxxxx" // } String token = getKeyText(jsonToken, "\"access_token\"", "\"", "\""); String tokenType = getKeyText(jsonToken, "\"token_type\"", "\"", "\""); - // TODO: remove this once the bug is fixed on the server side - if ("bearer".equals(tokenType)) { - tokenType = "Bearer"; - } - return tokenType + " " + token; } @@ -319,4 +325,13 @@ class FimfictionApi extends BasicSupport { return pos; } + + // quick & dirty filter + static private String unbbcode(String bbcode) { + String text = bbcode.replace("\\r\\n", "
") // + .replace("[i]", "_").replace("[/i]", "_") // + .replace("[b]", "*").replace("[/b]", "*") // + .replaceAll("\\[[^\\]]*\\]", ""); + return text; + } } -- 2.27.0