From e6249b0f26fd3a7ec4cf5e49ba9f9939018c43d3 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sat, 2 Dec 2017 15:55:52 +0100 Subject: [PATCH] GUI: detect remote connection failures --- changelog.md | 3 +- .../nikiroo/fanfix/library/BasicLibrary.java | 43 ++++--- .../nikiroo/fanfix/library/CacheLibrary.java | 5 + .../nikiroo/fanfix/library/RemoteLibrary.java | 75 +++++++----- .../nikiroo/fanfix/reader/GuiReaderFrame.java | 113 ++++++++++++++---- 5 files changed, 169 insertions(+), 70 deletions(-) diff --git a/changelog.md b/changelog.md index 9c30702..d820412 100644 --- a/changelog.md +++ b/changelog.md @@ -3,11 +3,12 @@ # Version WIP - Bug fixes -- Remote server/client improvements (progress report, can send large files) +- Remote server/client improvements (progress report, can send large files, detect server state) - Better support for some CBZ files (if SUMMARY or URL files are present in it) - Fix cover images not deleted on story delete - Fix some images not supported because not jpeg-able (now try again in png) - Fix some covers not found over the wire (nikiroo-utils) +- Fix cover image files not sent over the wire ## Version 1.6.2 diff --git a/src/be/nikiroo/fanfix/library/BasicLibrary.java b/src/be/nikiroo/fanfix/library/BasicLibrary.java index 4c32e3c..430fb20 100644 --- a/src/be/nikiroo/fanfix/library/BasicLibrary.java +++ b/src/be/nikiroo/fanfix/library/BasicLibrary.java @@ -29,6 +29,22 @@ import be.nikiroo.utils.Progress; * @author niki */ abstract public class BasicLibrary { + /** + * A {@link BasicLibrary} status. + * + * @author niki + */ + public enum Status { + /** The library is ready. */ + READY, + /** The library is invalid (not correctly set up). */ + INVALID, + /** You are not allowed to access this library. */ + UNAUTORIZED, + /** The library is currently out of commission. */ + UNAVAILABLE, + } + /** * Return a name for this library (the UI may display this). *

@@ -40,6 +56,15 @@ abstract public class BasicLibrary { return ""; } + /** + * The library status. + * + * @return the current status + */ + public Status getStatus() { + return Status.READY; + } + /** * Retrieve the main {@link File} corresponding to the given {@link Story}, * which can be passed to an external reader or instance. @@ -147,26 +172,14 @@ abstract public class BasicLibrary { throws IOException; /** - * Refresh the {@link BasicLibrary}, that is, make sure all stories are + * Refresh the {@link BasicLibrary}, that is, make sure all metas are * loaded. * - * @param full - * force the full content of the stories to be loaded, not just - * the {@link MetaData} - * * @param pg * the optional progress reporter */ - public void refresh(boolean full, Progress pg) { - if (full) { - // TODO: progress - List metas = getMetas(pg); - for (MetaData meta : metas) { - getStory(meta.getLuid(), null); - } - } else { - getMetas(pg); - } + public void refresh(Progress pg) { + getMetas(pg); } /** diff --git a/src/be/nikiroo/fanfix/library/CacheLibrary.java b/src/be/nikiroo/fanfix/library/CacheLibrary.java index f665e38..62ac9fa 100644 --- a/src/be/nikiroo/fanfix/library/CacheLibrary.java +++ b/src/be/nikiroo/fanfix/library/CacheLibrary.java @@ -45,6 +45,11 @@ public class CacheLibrary extends BasicLibrary { return lib.getLibraryName(); } + @Override + public Status getStatus() { + return lib.getStatus(); + } + @Override protected List getMetas(Progress pg) { if (pg == null) { diff --git a/src/be/nikiroo/fanfix/library/RemoteLibrary.java b/src/be/nikiroo/fanfix/library/RemoteLibrary.java index e51de45..63d2d7d 100644 --- a/src/be/nikiroo/fanfix/library/RemoteLibrary.java +++ b/src/be/nikiroo/fanfix/library/RemoteLibrary.java @@ -3,6 +3,7 @@ package be.nikiroo.fanfix.library; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; @@ -47,6 +48,50 @@ public class RemoteLibrary extends BasicLibrary { return host + ":" + port; } + @Override + public Status getStatus() { + final Status[] result = new Status[1]; + + result[0] = Status.INVALID; + + ConnectActionClientObject action = null; + try { + action = new ConnectActionClientObject(host, port, true) { + @Override + public void action(Version serverVersion) throws Exception { + Object rep = send(new Object[] { key, "PING" }); + if ("PONG".equals(rep)) { + result[0] = Status.READY; + } else { + result[0] = Status.UNAUTORIZED; + } + } + + @Override + protected void onError(Exception e) { + result[0] = Status.UNAVAILABLE; + } + }; + + } catch (UnknownHostException e) { + result[0] = Status.INVALID; + } catch (IllegalArgumentException e) { + result[0] = Status.INVALID; + } catch (Exception e) { + result[0] = Status.UNAVAILABLE; + } + + if (action != null) { + try { + action.connect(); + } catch (Exception e) { + result[0] = Status.UNAVAILABLE; + } + } + + return result[0]; + } + @Override public BufferedImage getCover(final String luid) { final BufferedImage[] result = new BufferedImage[1]; @@ -224,36 +269,6 @@ public class RemoteLibrary extends BasicLibrary { "Operation not supportorted on remote Libraries"); } - /** - * Check if this {@link RemoteLibraryServer} is able to connect and identify - * to the remote server. - * - * @return TRUE if it is online - */ - public boolean isOnline() { - final Boolean[] result = new Boolean[1]; - - result[0] = false; - try { - new ConnectActionClientObject(host, port, true) { - @Override - public void action(Version serverVersion) throws Exception { - Object rep = send(new Object[] { key, "PING" }); - result[0] = "PONG".equals(rep); - } - - @Override - protected void onError(Exception e) { - Instance.getTraceHandler().error(e); - } - }.connect(); - } catch (Exception e) { - Instance.getTraceHandler().error(e); - } - - return result[0]; - } - @Override protected List getMetas(Progress pg) { final Progress pgF = pg; diff --git a/src/be/nikiroo/fanfix/reader/GuiReaderFrame.java b/src/be/nikiroo/fanfix/reader/GuiReaderFrame.java index cd321ab..4e2630e 100644 --- a/src/be/nikiroo/fanfix/reader/GuiReaderFrame.java +++ b/src/be/nikiroo/fanfix/reader/GuiReaderFrame.java @@ -40,6 +40,8 @@ import be.nikiroo.fanfix.bundles.Config; import be.nikiroo.fanfix.bundles.UiConfig; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; +import be.nikiroo.fanfix.library.BasicLibrary; +import be.nikiroo.fanfix.library.BasicLibrary.Status; import be.nikiroo.fanfix.library.LocalLibrary; import be.nikiroo.fanfix.output.BasicOutput.OutputType; import be.nikiroo.fanfix.reader.GuiReaderBook.BookActionListener; @@ -151,13 +153,43 @@ class GuiReaderFrame extends JFrame { outOfUi(pg, new Runnable() { @Override public void run() { - GuiReaderFrame.this.reader.getLibrary().refresh(false, pg); - invalidate(); - setJMenuBar(createMenu()); - addBookPane(typeF, true); - refreshBooks(); - validate(); - pane.setVisible(true); + BasicLibrary lib = GuiReaderFrame.this.reader.getLibrary(); + Status status = lib.getStatus(); + + if (status == Status.READY) { + lib.refresh(pg); + invalidate(); + setJMenuBar(createMenu(true)); + addBookPane(typeF, true); + refreshBooks(); + validate(); + pane.setVisible(true); + } else { + invalidate(); + setJMenuBar(createMenu(false)); + validate(); + + String err = lib.getLibraryName() + "\n"; + switch (status) { + case INVALID: + err += "Library not valid"; + break; + + case UNAUTORIZED: + err += "You are not allowed to access this library"; + break; + + case UNAVAILABLE: + err += "Library currently unavilable"; + break; + + default: + err += "An error occured when contacting the library"; + break; + } + + error(err, "Library error", null); + } } }); @@ -266,7 +298,7 @@ class GuiReaderFrame extends JFrame { popup.add(createMenuItemOpenBook()); popup.addSeparator(); popup.add(createMenuItemExport()); - popup.add(createMenuItemMove()); + popup.add(createMenuItemMove(true)); popup.add(createMenuItemSetCover()); popup.add(createMenuItemClearCache()); popup.add(createMenuItemRedownload()); @@ -316,9 +348,12 @@ class GuiReaderFrame extends JFrame { /** * Create the main menu bar. * + * @param libOk + * the library can be queried + * * @return the bar */ - private JMenuBar createMenu() { + private JMenuBar createMenu(boolean libOk) { bar = new JMenuBar(); JMenu file = new JMenu("File"); @@ -349,7 +384,7 @@ class GuiReaderFrame extends JFrame { file.add(createMenuItemOpenBook()); file.add(createMenuItemExport()); - file.add(createMenuItemMove()); + file.add(createMenuItemMove(libOk)); file.addSeparator(); file.add(imprt); file.add(imprtF); @@ -395,8 +430,12 @@ class GuiReaderFrame extends JFrame { JMenu sources = new JMenu("Sources"); sources.setMnemonic(KeyEvent.VK_S); - List tt = reader.getLibrary().getSources(); + List tt = new ArrayList(); + if (libOk) { + tt.addAll(reader.getLibrary().getSources()); + } tt.add(0, null); + for (final String type : tt) { JMenuItem item = new JMenuItem(type == null ? "All" : type); item.addActionListener(new ActionListener() { @@ -419,7 +458,10 @@ class GuiReaderFrame extends JFrame { JMenu authors = new JMenu("Authors"); authors.setMnemonic(KeyEvent.VK_A); - List aa = reader.getLibrary().getAuthors(); + List aa = new ArrayList(); + if (libOk) { + aa.addAll(reader.getLibrary().getAuthors()); + } aa.add(0, null); for (final String author : aa) { JMenuItem item = new JMenuItem(author == null ? "All" @@ -627,15 +669,20 @@ class GuiReaderFrame extends JFrame { /** * Create the delete menu item. * + * @param libOk + * the library can be queried + * * @return the item */ - private JMenuItem createMenuItemMove() { + private JMenuItem createMenuItemMove(boolean libOk) { JMenu moveTo = new JMenu("Move to..."); moveTo.setMnemonic(KeyEvent.VK_M); List types = new ArrayList(); types.add(null); - types.addAll(reader.getLibrary().getSources()); + if (libOk) { + types.addAll(reader.getLibrary().getSources()); + } for (String type : types) { JMenuItem item = new JMenuItem(type == null ? "New type..." : type); @@ -677,7 +724,7 @@ class GuiReaderFrame extends JFrame { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - setJMenuBar(createMenu()); + setJMenuBar(createMenu(true)); } }); } @@ -940,15 +987,8 @@ class GuiReaderFrame extends JFrame { pgOnSuccess.setProgress(0); if (!ok) { - Instance.getTraceHandler().error(e); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - JOptionPane.showMessageDialog(GuiReaderFrame.this, - "Cannot import: " + url, e.getMessage(), - JOptionPane.ERROR_MESSAGE); - } - }); + error("Cannot import URL", "Failed to import " + url + + ": \n" + e.getMessage(), e); } else { if (onSuccess != null) { onSuccess.run(story); @@ -985,4 +1025,29 @@ class GuiReaderFrame extends JFrame { super.setEnabled(b); repaint(); } + + /** + * Display an error message and log the linked {@link Exception}. + * + * @param message + * the message + * @param title + * the title of the error message + * @param e + * the exception to log if any + */ + private void error(final String message, final String title, Exception e) { + Instance.getTraceHandler().error(title + ": " + message); + if (e != null) { + Instance.getTraceHandler().error(e); + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JOptionPane.showMessageDialog(GuiReaderFrame.this, message, + title, JOptionPane.ERROR_MESSAGE); + } + }); + } } -- 2.27.0