GUI: detect remote connection failures
authorNiki Roo <niki@nikiroo.be>
Sat, 2 Dec 2017 14:55:52 +0000 (15:55 +0100)
committerNiki Roo <niki@nikiroo.be>
Sat, 2 Dec 2017 14:55:52 +0000 (15:55 +0100)
changelog.md
src/be/nikiroo/fanfix/library/BasicLibrary.java
src/be/nikiroo/fanfix/library/CacheLibrary.java
src/be/nikiroo/fanfix/library/RemoteLibrary.java
src/be/nikiroo/fanfix/reader/GuiReaderFrame.java

index 9c30702c885a9f84eac4ca57c8dab86f81e4d50a..d8204124173095e80de7614f55643f616b380e6f 100644 (file)
@@ -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
 
index 4c32e3c2a6cbb68d85efb17a3df113026c82ef4d..430fb2026a256510bb7705eea22ce799005ab48e 100644 (file)
@@ -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).
         * <p>
@@ -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<MetaData> metas = getMetas(pg);
-                       for (MetaData meta : metas) {
-                               getStory(meta.getLuid(), null);
-                       }
-               } else {
-                       getMetas(pg);
-               }
+       public void refresh(Progress pg) {
+               getMetas(pg);
        }
 
        /**
index f665e383cad2f43f6c0b1807d56e5fdb69705b13..62ac9fa77bb4f3f7efd4a463863896961ce7abce 100644 (file)
@@ -45,6 +45,11 @@ public class CacheLibrary extends BasicLibrary {
                return lib.getLibraryName();
        }
 
+       @Override
+       public Status getStatus() {
+               return lib.getStatus();
+       }
+
        @Override
        protected List<MetaData> getMetas(Progress pg) {
                if (pg == null) {
index e51de45daf1d17aaf5ee294073b7e58ff3de726a..63d2d7d345952820ff42a5ef3c9c8b395492c55b 100644 (file)
@@ -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<MetaData> getMetas(Progress pg) {
                final Progress pgF = pg;
index cd321ab49ad15ee7ebe5e6262074f9040bd10d25..4e2630ec9e3258fc6b9be5d2373f3027582e9eed 100644 (file)
@@ -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<String> tt = reader.getLibrary().getSources();
+               List<String> tt = new ArrayList<String>();
+               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<String> aa = reader.getLibrary().getAuthors();
+               List<String> aa = new ArrayList<String>();
+               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<String> types = new ArrayList<String>();
                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);
+                       }
+               });
+       }
 }