From: Niki Roo Date: Sat, 1 Jul 2017 23:04:44 +0000 (+0200) Subject: Network server and Library + nikiroo-utils update X-Git-Tag: fanfix-1.6.0~27 X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=b0e88ebd20f8b2950c382694e936da76ac3596b6;p=fanfix.git Network server and Library + nikiroo-utils update --- diff --git a/README.md b/README.md index 826aacb..d80d3c5 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Fanfix is a small Java program that can download stories from some supported web (If you are interested in the recent changes, please check the [Changelog](changelog.md) -- note that starting from version 1.4.0, the changelog is checked at startup (unless the option is disabled)) +TODO: new screenshots + TUI screenshots + ![Main GUI](screenshots/fanfix-1.3.2.png?raw=true "Main GUI") It will convert from a (supported) URL to an .epub file for stories or a .cbz file for comics (a few other output types are also available, like Plain Text, LaTeX, HTML...). @@ -60,7 +62,9 @@ The following arguments are also allowed: - ```--read [id] ([chapter number])```: read the given story denoted by ID from the library - ```--read-url [URL] ([chapter number])```: convert on the fly and read the story denoted by ID, without saving it - ```--list```: list the stories present in the library and their associated IDs -- ```--set-reader [reader type]```: set the reader type to CLI or LOCAL for this command (must be the first option) +- ```--set-reader [reader type]```: set the reader type to CLI, TUI or GUI for this command +- ```--server [port]```: start a story server on this port +- ```--remote [host] [port]```: contact this server instead of the usual library - ```--help```: display the available options ### Environment variables @@ -85,6 +89,7 @@ There are some unit tests you can run, too: - libs/nikiroo-utils-sources.jar: some shared utility functions I also use elsewhere - [libs/unbescape-sources.jar](https://github.com/unbescape/unbescape): a nice library to escape/unescape a lot of text formats; I only use it for HTML +- [libs/jexer-sources.jar](https://github.com/klamonte/jexer): a small library that offers TUI widgets Nothing else but Java 1.6+. @@ -115,8 +120,16 @@ Currently missing, but either in progress or planned: - [x] Implement it from --set-reader to the actual window - [x] List the stories - [ ] Fix the UI layout - - [ ] Status bar and real menus - - [ ] Open a story in the reader and/or natively + - [x] Status bar + - [ ] Real menus + - [x] Open a story in the reader and/or natively + - [ ] Update the screenshots +- [ ] Network support + - [x] A server that can send the stories + - [x] A network implementation of the Library + - [ ] Write access to the library (?) + - [ ] Access rights (?) + - [ ] More tests, especially with the GUI - [ ] Check if it can work on Android - [x] First checks: it should work, but with changes - [ ] Adapt work on images :( diff --git a/changelog.md b/changelog.md index 89b6b00..a27f9c8 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,8 @@ ## Version WIP - New reader type: TUI (a text user interface with windows and menus) +- A server option to offer stories on the network +- A remote library to get said stories from the network ## Version 1.5.3 - FimFiction: Fix tags and chapter handling for some stories diff --git a/libs/nikiroo-utils-1.6.0-sources.jar b/libs/nikiroo-utils-1.6.1-sources.jar similarity index 85% rename from libs/nikiroo-utils-1.6.0-sources.jar rename to libs/nikiroo-utils-1.6.1-sources.jar index 1ec2951..f3b1578 100644 Binary files a/libs/nikiroo-utils-1.6.0-sources.jar and b/libs/nikiroo-utils-1.6.1-sources.jar differ diff --git a/src/be/nikiroo/fanfix/Instance.java b/src/be/nikiroo/fanfix/Instance.java index 28849b3..42e141e 100644 --- a/src/be/nikiroo/fanfix/Instance.java +++ b/src/be/nikiroo/fanfix/Instance.java @@ -27,6 +27,7 @@ public class Instance { private static boolean debug; private static File coverDir; private static File readerTmp; + private static File remoteDir; private static String configDir; static { @@ -84,6 +85,7 @@ public class Instance { coverDir = getFile(Config.DEFAULT_COVERS_DIR); File tmp = getFile(Config.CACHE_DIR); readerTmp = getFile(UiConfig.CACHE_DIR_LOCAL_READER); + remoteDir = new File(getFile(Config.LIBRARY_DIR), "remote"); if (checkEnv("NOUTF")) { trans.setUnicode(false); @@ -185,6 +187,25 @@ public class Instance { return readerTmp; } + /** + * Return the directory where to store temporary files for the remote + * {@link Library}. + * + * @param host + * the remote for this host + * + * @return the directory + */ + public static File getRemoteDir(String host) { + remoteDir.mkdirs(); + + if (host != null) { + return new File(remoteDir, host); + } + + return remoteDir; + } + /** * Check if we need to check that a new version of Fanfix is available. * diff --git a/src/be/nikiroo/fanfix/Library.java b/src/be/nikiroo/fanfix/Library.java index 8a3895a..3868bd3 100644 --- a/src/be/nikiroo/fanfix/Library.java +++ b/src/be/nikiroo/fanfix/Library.java @@ -38,8 +38,8 @@ import be.nikiroo.utils.Progress; public class Library { protected File baseDir; protected boolean localSpeed; + protected Map stories; - private Map stories; private int lastId; private OutputType text; private OutputType image; @@ -156,17 +156,12 @@ public class Library { * * @return the stories */ - public synchronized List getListByType(String type) { - if (type != null) { - // convert the type to dir name - type = getExpectedDir(type).getName(); - } - + public synchronized List getListBySource(String type) { List list = new ArrayList(); - for (Entry entry : getStories(null).entrySet()) { - String storyType = entry.getValue().getParentFile().getName(); + for (MetaData meta : getStories(null).keySet()) { + String storyType = meta.getSource(); if (type == null || type.equalsIgnoreCase(storyType)) { - list.add(entry.getKey()); + list.add(meta); } } diff --git a/src/be/nikiroo/fanfix/Main.java b/src/be/nikiroo/fanfix/Main.java index 5cd3313..38f58af 100644 --- a/src/be/nikiroo/fanfix/Main.java +++ b/src/be/nikiroo/fanfix/Main.java @@ -16,7 +16,7 @@ import be.nikiroo.fanfix.supported.BasicSupport; import be.nikiroo.fanfix.supported.BasicSupport.SupportType; import be.nikiroo.utils.Progress; import be.nikiroo.utils.Version; -import be.nikiroo.utils.ui.UIUtils; +import be.nikiroo.utils.serial.Server; /** * Main program entry point. @@ -25,7 +25,7 @@ import be.nikiroo.utils.ui.UIUtils; */ public class Main { private enum MainAction { - IMPORT, EXPORT, CONVERT, READ, READ_URL, LIST, HELP, SET_READER, START, VERSION, + IMPORT, EXPORT, CONVERT, READ, READ_URL, LIST, HELP, SET_READER, START, VERSION, SERVER, REMOTE, } /** @@ -55,6 +55,8 @@ public class Main { *
  • --set-reader [reader type]: set the reader type to CLI, TUI or LOCAL * for this command
  • *
  • --version: get the version of the program
  • + *
  • --server [port]: start a server on this port
  • + *
  • --remote [host] [port]: use a the given remote library
  • * * * @param args @@ -63,11 +65,13 @@ public class Main { public static void main(String[] args) { String urlString = null; String luid = null; - String typeString = null; + String sourceString = null; String chapString = null; String target = null; MainAction action = MainAction.START; Boolean plusInfo = null; + String host = null; + Integer port = null; boolean noMoreActions = false; @@ -102,8 +106,8 @@ public class Main { case EXPORT: if (luid == null) { luid = args[i]; - } else if (typeString == null) { - typeString = args[i]; + } else if (sourceString == null) { + sourceString = args[i]; } else if (target == null) { target = args[i]; } else { @@ -113,8 +117,8 @@ public class Main { case CONVERT: if (urlString == null) { urlString = args[i]; - } else if (typeString == null) { - typeString = args[i]; + } else if (sourceString == null) { + sourceString = args[i]; } else if (target == null) { target = args[i]; } else if (plusInfo == null) { @@ -128,8 +132,8 @@ public class Main { } break; case LIST: - if (typeString == null) { - typeString = args[i]; + if (sourceString == null) { + sourceString = args[i]; } else { exitCode = 255; } @@ -164,6 +168,30 @@ public class Main { break; case VERSION: exitCode = 255; // no arguments for this option + break; + case SERVER: + if (port == null) { + port = Integer.parseInt(args[i]); + } else { + exitCode = 255; + } + break; + case REMOTE: + if (host == null) { + host = args[i]; + } else if (port == null) { + port = Integer.parseInt(args[i]); + try { + BasicReader.setDefaultLibrary(new RemoteLibrary(host, + port)); + } catch (IOException e) { + Instance.syserr(e); + } + action = MainAction.START; + } else { + exitCode = 255; + } + break; } } @@ -215,16 +243,16 @@ public class Main { updates.ok(); // we consider it read break; case EXPORT: - exitCode = export(luid, typeString, target, pg); + exitCode = export(luid, sourceString, target, pg); updates.ok(); // we consider it read break; case CONVERT: - exitCode = convert(urlString, typeString, target, + exitCode = convert(urlString, sourceString, target, plusInfo == null ? false : plusInfo, pg); updates.ok(); // we consider it read break; case LIST: - exitCode = list(typeString); + exitCode = list(sourceString); break; case READ: exitCode = read(luid, chapString, true); @@ -237,6 +265,7 @@ public class Main { exitCode = 0; break; case SET_READER: + exitCode = 255; break; case VERSION: System.out @@ -247,8 +276,23 @@ public class Main { updates.ok(); // we consider it read break; case START: - //BasicReader.setDefaultReaderType(ReaderType.LOCAL); - BasicReader.getReader().start(null); + BasicReader.getReader().browse(null); + break; + case SERVER: + if (port == null) { + exitCode = 255; + break; + } + try { + Server server = new RemoteLibraryServer(port); + server.start(); + System.out.println("Remote server started on: " + port); + } catch (IOException e) { + Instance.syserr(e); + } + return; + case REMOTE: + exitCode = 255; break; } } @@ -320,17 +364,17 @@ public class Main { } /** - * List the stories of the given type from the {@link Library} (unless NULL - * is passed, in which case all stories will be listed). + * List the stories of the given source from the {@link Library} (unless + * NULL is passed, in which case all stories will be listed). * - * @param type - * the type to list the known stories of, or NULL to list all + * @param source + * the source to list the known stories of, or NULL to list all * stories * * @return the exit return code (0 = success) */ - private static int list(String type) { - BasicReader.getReader().start(type); + private static int list(String source) { + BasicReader.getReader().browse(source); return 0; } diff --git a/src/be/nikiroo/fanfix/RemoteLibrary.java b/src/be/nikiroo/fanfix/RemoteLibrary.java new file mode 100644 index 0000000..cc78be9 --- /dev/null +++ b/src/be/nikiroo/fanfix/RemoteLibrary.java @@ -0,0 +1,109 @@ +package be.nikiroo.fanfix; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.fanfix.data.Story; +import be.nikiroo.fanfix.output.BasicOutput.OutputType; +import be.nikiroo.utils.Progress; +import be.nikiroo.utils.Version; +import be.nikiroo.utils.serial.ConnectActionClient; + +public class RemoteLibrary extends Library { + private String host; + private int port; + + private Library lib; + + public RemoteLibrary(String host, int port) throws IOException { + this.host = host; + this.port = port; + + this.localSpeed = false; + this.baseDir = Instance.getRemoteDir(host); + this.baseDir.mkdirs(); + + this.lib = new Library(baseDir, OutputType.INFO_TEXT, OutputType.CBZ); + } + + @Override + public synchronized Story save(Story story, String luid, Progress pg) + throws IOException { + throw new java.lang.InternalError( + "No write support allowed on remote Libraries"); + } + + @Override + public synchronized boolean delete(String luid) { + throw new java.lang.InternalError( + "No write support allowed on remote Libraries"); + } + + @Override + public synchronized boolean changeType(String luid, String newType) { + throw new java.lang.InternalError( + "No write support allowed on remote Libraries"); + } + + @Override + protected synchronized Map getStories(Progress pg) { + // TODO: progress + if (stories.isEmpty()) { + try { + new ConnectActionClient(host, port, true, null) { + public void action(Version serverVersion) throws Exception { + try { + Object rep = send("GET_METADATA *"); + for (MetaData meta : (MetaData[]) rep) { + stories.put(meta, null); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }.connect(); + } catch (IOException e) { + Instance.syserr(e); + } + } + + return stories; + } + + @Override + public synchronized File getFile(final String luid) { + File file = lib.getFile(luid); + if (file == null) { + final File[] tmp = new File[1]; + try { + new ConnectActionClient(host, port, true, null) { + public void action(Version serverVersion) throws Exception { + try { + Object rep = send("GET_STORY " + luid); + Story story = (Story) rep; + if (story != null) { + lib.save(story, luid, null); + tmp[0] = lib.getFile(luid); + } + } catch (Exception e) { + Instance.syserr(e); + } + } + }.connect(); + } catch (IOException e) { + Instance.syserr(e); + } + + file = tmp[0]; + } + + if (file != null) { + MetaData meta = getInfo(luid); + stories.put(meta, file); + } + + return file; + } +} diff --git a/src/be/nikiroo/fanfix/RemoteLibraryServer.java b/src/be/nikiroo/fanfix/RemoteLibraryServer.java new file mode 100644 index 0000000..9ecbc41 --- /dev/null +++ b/src/be/nikiroo/fanfix/RemoteLibraryServer.java @@ -0,0 +1,51 @@ +package be.nikiroo.fanfix; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import be.nikiroo.fanfix.data.MetaData; +import be.nikiroo.utils.Version; +import be.nikiroo.utils.serial.ConnectActionServer; +import be.nikiroo.utils.serial.Server; + +public class RemoteLibraryServer extends Server { + + public RemoteLibraryServer(int port) throws IOException { + super(Version.getCurrentVersion(), port, true); + } + + @Override + protected Object onRequest(ConnectActionServer action, + Version clientVersion, Object data) throws Exception { + String command = null; + String args = null; + if (data instanceof String) { + command = (String) data; + int pos = command.indexOf(" "); + if (pos >= 0) { + args = command.substring(pos + 1); + command = command.substring(0, pos); + } + } + + System.out.println(String.format("COMMAND: [%s], ARGS: [%s]", command, + args)); + + if (command != null) { + if (command.equals("GET_METADATA")) { + if (args != null && args.equals("*")) { + Map stories = Instance.getLibrary() + .getStories(null); + return stories.keySet().toArray(new MetaData[] {}); + } + } else if (command.equals("GET_STORY")) { + if (args != null) { + return Instance.getLibrary().getStory(args, null); + } + } + } + + return null; + } +} diff --git a/src/be/nikiroo/fanfix/data/Chapter.java b/src/be/nikiroo/fanfix/data/Chapter.java index 7d0a51b..d9f285f 100644 --- a/src/be/nikiroo/fanfix/data/Chapter.java +++ b/src/be/nikiroo/fanfix/data/Chapter.java @@ -16,6 +16,13 @@ public class Chapter implements Iterable { private List empty = new ArrayList(); private long words; + /** + * Empty constructor, not to use. + */ + private Chapter() { + // for serialisation purposes + } + /** * Create a new {@link Chapter} with the given information. * diff --git a/src/be/nikiroo/fanfix/data/Paragraph.java b/src/be/nikiroo/fanfix/data/Paragraph.java index e4c94d4..8a9130b 100644 --- a/src/be/nikiroo/fanfix/data/Paragraph.java +++ b/src/be/nikiroo/fanfix/data/Paragraph.java @@ -30,6 +30,13 @@ public class Paragraph { private String content; private long words; + /** + * Empty constructor, not to use. + */ + private Paragraph() { + // for serialisation purposes + } + /** * Create a new {@link Paragraph} with the given image. * diff --git a/src/be/nikiroo/fanfix/reader/BasicReader.java b/src/be/nikiroo/fanfix/reader/BasicReader.java index 7b9c98c..05e3e3d 100644 --- a/src/be/nikiroo/fanfix/reader/BasicReader.java +++ b/src/be/nikiroo/fanfix/reader/BasicReader.java @@ -14,7 +14,6 @@ import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.supported.BasicSupport; import be.nikiroo.utils.Progress; -import be.nikiroo.utils.ui.UIUtils; import be.nikiroo.utils.serial.SerialUtils; /** @@ -32,22 +31,28 @@ public abstract class BasicReader { GUI, /** A text (UTF-8) reader with menu and text windows */ TUI, - + ; - + public String getTypeName() { String pkg = "be.nikiroo.fanfix.reader."; switch (this) { - case CLI: return pkg + "CliReader"; - case TUI: return pkg + "TuiReader"; - case GUI: return pkg + "LocalReader"; + case CLI: + return pkg + "CliReader"; + case TUI: + return pkg + "TuiReader"; + case GUI: + return pkg + "LocalReader"; } - + return null; } } + private static Library defaultLibrary = Instance.getLibrary(); private static ReaderType defaultType = ReaderType.GUI; + + private Library lib; private Story story; private ReaderType type; @@ -95,9 +100,34 @@ public abstract class BasicReader { return story; } + /** + * The {@link Library} to load the stories from (by default, takes the + * default {@link Library}). + * + * @return the {@link Library} + */ + public Library getLibrary() { + if (lib == null) { + lib = defaultLibrary; + } + + return lib; + } + + /** + * Change the {@link Library} that will be managed by this + * {@link BasicReader}. + * + * @param lib + * the new {@link Library} + */ + public void setLibrary(Library lib) { + this.lib = lib; + } + /** * Create a new {@link BasicReader} for a {@link Story} in the - * {@link Library} . + * {@link Library}. * * @param luid * the {@link Story} ID @@ -108,7 +138,7 @@ public abstract class BasicReader { * in case of I/O error */ public void setStory(String luid, Progress pg) throws IOException { - story = Instance.getLibrary().getStory(luid, pg); + story = lib.getStory(luid, pg); if (story == null) { throw new IOException("Cannot retrieve story from library: " + luid); } @@ -162,14 +192,17 @@ public abstract class BasicReader { public abstract void read(int chapter) throws IOException; /** - * Start the reader in browse mode for the given type (or pass NULL for all - * types). + * Start the reader in browse mode for the given source (or pass NULL for + * all sources). * - * @param type + * @param library + * the library to browse + * + * @param source * the type of {@link Story} to take into account, or NULL for * all */ - public abstract void start(String type); + public abstract void browse(String source); /** * Return a new {@link BasicReader} ready for use if one is configured. @@ -181,8 +214,8 @@ public abstract class BasicReader { public static BasicReader getReader() { try { if (defaultType != null) { - return ((BasicReader)SerialUtils.createObject - (defaultType.getTypeName())).setType(defaultType); + return ((BasicReader) SerialUtils.createObject(defaultType + .getTypeName())).setType(defaultType); } } catch (Exception e) { Instance.syserr(new Exception("Cannot create a reader of type: " @@ -213,6 +246,16 @@ public abstract class BasicReader { BasicReader.defaultType = defaultType; } + /** + * Change the default {@link Library} to open with the {@link BasicReader}s. + * + * @param lib + * the new {@link Library} + */ + public static void setDefaultLibrary(Library lib) { + BasicReader.defaultLibrary = lib; + } + /** * Return an {@link URL} from this {@link String}, be it a file path or an * actual {@link URL}. @@ -242,9 +285,9 @@ public abstract class BasicReader { } // open with external player the related file - public static void open(String luid) throws IOException { - MetaData meta = Instance.getLibrary().getInfo(luid); - File target = Instance.getLibrary().getFile(luid); + public static void open(Library lib, String luid) throws IOException { + MetaData meta = lib.getInfo(luid); + File target = lib.getFile(luid); open(meta, target); } diff --git a/src/be/nikiroo/fanfix/reader/CliReader.java b/src/be/nikiroo/fanfix/reader/CliReader.java index a57de34..7ac69e8 100644 --- a/src/be/nikiroo/fanfix/reader/CliReader.java +++ b/src/be/nikiroo/fanfix/reader/CliReader.java @@ -78,9 +78,9 @@ class CliReader extends BasicReader { } @Override - public void start(String type) { + public void browse(String source) { List stories; - stories = Instance.getLibrary().getListByType(type); + stories = getLibrary().getListBySource(source); for (MetaData story : stories) { String author = ""; diff --git a/src/be/nikiroo/fanfix/reader/LocalReader.java b/src/be/nikiroo/fanfix/reader/LocalReader.java index 2b92e72..6c61503 100644 --- a/src/be/nikiroo/fanfix/reader/LocalReader.java +++ b/src/be/nikiroo/fanfix/reader/LocalReader.java @@ -20,11 +20,19 @@ import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.output.BasicOutput.OutputType; import be.nikiroo.utils.Progress; import be.nikiroo.utils.Version; +import be.nikiroo.utils.ui.UIUtils; class LocalReader extends BasicReader { - private Library lib; + static private boolean nativeLookLoaded; + + private Library localLibrary; public LocalReader() throws IOException { + if (!nativeLookLoaded) { + UIUtils.setLookAndFeel(); + nativeLookLoaded = true; + } + File dir = Instance.getReaderDir(); dir.mkdirs(); if (!dir.exists()) { @@ -58,7 +66,7 @@ class LocalReader extends BasicReader { key, value), e); } - lib = new Library(dir, text, images); + localLibrary = new Library(dir, text, images); } @Override @@ -99,7 +107,7 @@ class LocalReader extends BasicReader { try { Story story = Instance.getLibrary().getStory(luid, pgGetStory); if (story != null) { - story = lib.save(story, luid, pgSave); + story = localLibrary.save(story, luid, pgSave); } else { throw new IOException("Cannot find story in Library: " + luid); } @@ -120,11 +128,11 @@ class LocalReader extends BasicReader { * @return TRUE if it is */ public boolean isCached(String luid) { - return lib.getInfo(luid) != null; + return localLibrary.getInfo(luid) != null; } @Override - public void start(String type) { + public void browse(String type) { // TODO: improve presentation of update message final VersionCheck updates = VersionCheck.check(); StringBuilder builder = new StringBuilder(); @@ -189,28 +197,28 @@ class LocalReader extends BasicReader { // delete from local reader library void clearLocalReaderCache(String luid) { - lib.delete(luid); + localLibrary.delete(luid); } // delete from main library void delete(String luid) { - lib.delete(luid); + localLibrary.delete(luid); Instance.getLibrary().delete(luid); } // open the given book void open(String luid, Progress pg) throws IOException { - File file = lib.getFile(luid); + File file = localLibrary.getFile(luid); if (file == null) { imprt(luid, pg); - file = lib.getFile(luid); + file = localLibrary.getFile(luid); } - open(Instance.getLibrary().getInfo(luid), file); + open(getLibrary().getInfo(luid), file); } void changeType(String luid, String newType) { - lib.changeType(luid, newType); + localLibrary.changeType(luid, newType); Instance.getLibrary().changeType(luid, newType); } } diff --git a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java index 03df7fb..edd1fb6 100644 --- a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java +++ b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java @@ -220,7 +220,7 @@ class LocalReaderFrame extends JFrame { */ private void refreshBooks() { for (LocalReaderGroup group : booksByType.keySet()) { - List stories = Instance.getLibrary().getListByType( + List stories = Instance.getLibrary().getListBySource( booksByType.get(group)); group.refreshBooks(stories, words); } diff --git a/src/be/nikiroo/fanfix/reader/TuiReader.java b/src/be/nikiroo/fanfix/reader/TuiReader.java index d18436f..d00bbc2 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReader.java +++ b/src/be/nikiroo/fanfix/reader/TuiReader.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.List; import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.Library; import be.nikiroo.fanfix.data.MetaData; class TuiReader extends BasicReader { @@ -13,7 +14,7 @@ class TuiReader extends BasicReader { throw new IOException("No story to read"); } - open(getStory().getMeta().getLuid()); + open(getLibrary(), getStory().getMeta().getLuid()); } @Override @@ -23,8 +24,8 @@ class TuiReader extends BasicReader { } @Override - public void start(String type) { - List stories = Instance.getLibrary().getListByType(type); + public void browse(String source) { + List stories = getLibrary().getListBySource(source); try { TuiReaderApplication app = new TuiReaderApplication(stories, this); new Thread(app).start(); diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java index 94ecfd5..9a53498 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java @@ -5,7 +5,6 @@ import java.util.List; import jexer.TApplication; import jexer.TMessageBox; -import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.data.MetaData; public class TuiReaderApplication extends TApplication { @@ -55,21 +54,15 @@ public class TuiReaderApplication extends TApplication { public void open(MetaData meta) { // TODO: open in editor + external option - if (true) { - if (!meta.isImageDocument()) { - new TuiReaderStoryWindow(this, meta); - } else { + if (!meta.isImageDocument()) { + new TuiReaderStoryWindow(this, reader.getLibrary(), meta); + } else { + try { + BasicReader.open(reader.getLibrary(), meta.getLuid()); + } catch (IOException e) { messageBox("Error when trying to open the story", - "Images document not yet supported.", - TMessageBox.Type.OK); + e.getMessage(), TMessageBox.Type.OK); } - return; - } - try { - reader.open(meta.getLuid()); - } catch (IOException e) { - messageBox("Error when trying to open the story", e.getMessage(), - TMessageBox.Type.OK); } } } diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java b/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java index 7eb592f..0d47cde 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java @@ -13,12 +13,14 @@ import jexer.TText; import jexer.TWindow; import jexer.event.TResizeEvent; import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.Library; import be.nikiroo.fanfix.data.Chapter; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Paragraph; import be.nikiroo.fanfix.data.Story; public class TuiReaderStoryWindow extends TWindow { + private Library lib; private MetaData meta; private Story story; private TText textField; @@ -26,12 +28,15 @@ public class TuiReaderStoryWindow extends TWindow { private List navigationButtons; private TLabel chapterName; - public TuiReaderStoryWindow(TApplication app, MetaData meta) { - this(app, meta, 0); + public TuiReaderStoryWindow(TApplication app, Library lib, MetaData meta) { + this(app, lib, meta, 0); } - public TuiReaderStoryWindow(TApplication app, MetaData meta, int chapter) { + public TuiReaderStoryWindow(TApplication app, Library lib, MetaData meta, + int chapter) { super(app, desc(meta), 0, 0, 60, 18, CENTERED | RESIZABLE); + + this.lib = lib; this.meta = meta; // TODO: show all meta info before? @@ -46,7 +51,10 @@ public class TuiReaderStoryWindow extends TWindow { // -3 because 0-based and 2 for borders int row = getHeight() - 3; - navigationButtons.add(addButton(" ", 0, row, null)); // for bg colour when << button is pressed + navigationButtons.add(addButton(" ", 0, row, null)); // for bg colour + // when << + // button is + // pressed navigationButtons.add(addButton("<< ", 0, row, new TAction() { public void DO() { setChapter(0); @@ -67,7 +75,7 @@ public class TuiReaderStoryWindow extends TWindow { setChapter(getStory().getChapters().size()); } })); - + navigationButtons.get(0).setEnabled(false); navigationButtons.get(1).setEnabled(false); navigationButtons.get(2).setEnabled(false); @@ -113,14 +121,14 @@ public class TuiReaderStoryWindow extends TWindow { if (chapter != this.chapter) { this.chapter = chapter; - + int max = getStory().getChapters().size(); navigationButtons.get(0).setEnabled(chapter > 0); navigationButtons.get(1).setEnabled(chapter > 0); navigationButtons.get(2).setEnabled(chapter > 0); navigationButtons.get(3).setEnabled(chapter < max); navigationButtons.get(4).setEnabled(chapter < max); - + Chapter chap; String name; if (chapter == 0) { @@ -128,7 +136,8 @@ public class TuiReaderStoryWindow extends TWindow { name = String.format(" %s", chap.getName()); } else { chap = getStory().getChapters().get(chapter - 1); - name = String.format(" %d/%d: %s", chapter, max, chap.getName()); + name = String + .format(" %d/%d: %s", chapter, max, chap.getName()); } while (name.length() < getWidth() - chapterName.getX()) { @@ -157,7 +166,7 @@ public class TuiReaderStoryWindow extends TWindow { private Story getStory() { if (story == null) { // TODO: progress bar? - story = Instance.getLibrary().getStory(meta.getLuid(), null); + story = lib.getStory(meta.getLuid(), null); } return story; }