fix STOP server
[fanfix.git] / src / be / nikiroo / fanfix / library / WebLibraryServer.java
index 55e8ed3d146658f5529471eb645d3caa26c1fe77..22f36e91f5729a7bfef72fe9c98d2a7fa157a6ec 100644 (file)
@@ -3,6 +3,7 @@ package be.nikiroo.fanfix.library;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -26,13 +27,10 @@ import be.nikiroo.utils.LoginResult;
 import be.nikiroo.utils.NanoHTTPD;
 import be.nikiroo.utils.NanoHTTPD.Response;
 import be.nikiroo.utils.NanoHTTPD.Response.Status;
+import be.nikiroo.utils.Progress;
 
 public class WebLibraryServer extends WebLibraryServerHtml {
        class WLoginResult extends LoginResult {
-               private boolean rw;
-               private boolean wl;
-               private boolean bl;
-
                public WLoginResult(boolean badLogin, boolean badCookie) {
                        super(badLogin, badCookie);
                }
@@ -41,9 +39,6 @@ public class WebLibraryServer extends WebLibraryServerHtml {
                                boolean wl, boolean bl) {
                        super(who, key, subkey, (rw ? "|rw" : "") + (wl ? "|wl" : "")
                                        + (bl ? "|bl" : "") + "|");
-                       this.rw = rw;
-                       this.wl = wl;
-                       this.bl = bl;
                }
 
                public WLoginResult(String cookie, String who, String key,
@@ -73,6 +68,10 @@ public class WebLibraryServer extends WebLibraryServerHtml {
        private List<String> whitelist;
        private List<String> blacklist;
 
+       private Map<String, Progress> imprts = new HashMap<String, Progress>();
+
+       private boolean exiting;
+
        public WebLibraryServer(boolean secure) throws IOException {
                super(secure);
 
@@ -100,6 +99,56 @@ public class WebLibraryServer extends WebLibraryServerHtml {
                new Thread(this).start();
        }
 
+       @Override
+       protected Response stop(WLoginResult login) {
+               if (!login.isRw()) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Exit not allowed");
+               }
+
+               if (exiting) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Server is already exiting...");
+               }
+
+               exiting = true;
+               Instance.getInstance().getTraceHandler().trace("Exiting");
+
+               boolean ok;
+               do {
+                       synchronized (imprts) {
+                               ok = imprts.isEmpty();
+                       }
+                       if (!ok) {
+                               try {
+                                       Thread.sleep(2000);
+                               } catch (InterruptedException e) {
+                                       Instance.getInstance().getTraceHandler()
+                                                       .trace("Waiting to exit...");
+                               }
+                       }
+               } while (!ok);
+
+               doStop();
+
+               new Thread(new Runnable() {
+                       @Override
+                       public void run() {
+                               try {
+                                       Thread.sleep(1500);
+                               } catch (InterruptedException e) {
+                               }
+
+                               Instance.getInstance().getTraceHandler()
+                                               .trace("Exit timeout: force-quit");
+                               System.exit(0);
+                       }
+               }, "Exit program after timeout of 1500 ms").start();
+
+               return NanoHTTPD.newFixedLengthResponse(Status.OK,
+                               NanoHTTPD.MIME_PLAINTEXT, "Exited");
+       }
+
        @Override
        protected WLoginResult login(boolean badLogin, boolean badCookie) {
                return new WLoginResult(false, false);
@@ -302,6 +351,16 @@ public class WebLibraryServer extends WebLibraryServerHtml {
                                        NanoHTTPD.MIME_PLAINTEXT, "Invalid story part request");
                }
 
+               if (!login.isRw()) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+                                       NanoHTTPD.MIME_PLAINTEXT, "SET story part not allowed");
+               }
+
+               if (exiting) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Server is exiting...");
+               }
+
                String luid = uriParts[off + 0];
                String type = uriParts[off + 1];
 
@@ -377,6 +436,16 @@ public class WebLibraryServer extends WebLibraryServerHtml {
                                        NanoHTTPD.MIME_PLAINTEXT, "Invalid cover request");
                }
 
+               if (!login.isRw()) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Cover request not allowed");
+               }
+
+               if (exiting) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Server is exiting...");
+               }
+
                String type = uriParts[off + 0];
                String id = uriParts[off + 1];
 
@@ -393,6 +462,101 @@ public class WebLibraryServer extends WebLibraryServerHtml {
                return newInputStreamResponse(NanoHTTPD.MIME_PLAINTEXT, null);
        }
 
+       @Override
+       protected Response imprt(String uri, String urlStr, WLoginResult login)
+                       throws IOException {
+               final BasicLibrary lib = Instance.getInstance().getLibrary();
+
+               if (!login.isRw()) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Import not allowed");
+               }
+
+               if (exiting) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Server is exiting...");
+               }
+
+               final URL url = new URL(urlStr);
+               final Progress pg = new Progress();
+               final String luid = lib.getNextId();
+
+               synchronized (imprts) {
+                       imprts.put(luid, pg);
+               }
+
+               new Thread(new Runnable() {
+                       @Override
+                       public void run() {
+                               try {
+                                       lib.imprt(url, luid, pg);
+                               } catch (IOException e) {
+                                       Instance.getInstance().getTraceHandler().error(e);
+                               } finally {
+                                       synchronized (imprts) {
+                                               imprts.remove(luid);
+                                       }
+                               }
+                       }
+               }, "Import story: " + urlStr).start();
+
+               return NanoHTTPD.newFixedLengthResponse(Status.OK,
+                               NanoHTTPD.MIME_PLAINTEXT, luid);
+       }
+
+       @Override
+       protected Response imprtProgress(String uri, WLoginResult login) {
+               String[] uriParts = uri.split("/");
+               int off = 2; // "" and "import"
+
+               if (uriParts.length < off + 1) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Invalid cover request");
+               }
+
+               String luid = uriParts[off + 0];
+
+               Progress pg = null;
+               synchronized (imprts) {
+                       pg = imprts.get(luid);
+               }
+               if (pg != null) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.OK,
+                                       "application/json", JsonIO.toJson(pg).toString());
+               }
+
+               return newInputStreamResponse(NanoHTTPD.MIME_PLAINTEXT, null);
+       }
+
+       @Override
+       protected Response delete(String uri, WLoginResult login)
+                       throws IOException {
+               String[] uriParts = uri.split("/");
+               int off = 2; // "" and "delete"
+
+               if (uriParts.length < off + 1) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Invalid delete request");
+               }
+
+               if (!login.isRw()) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Delete not allowed");
+               }
+
+               if (exiting) {
+                       return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE,
+                                       NanoHTTPD.MIME_PLAINTEXT, "Server is exiting...");
+               }
+
+               String luid = uriParts[off + 0];
+
+               BasicLibrary lib = Instance.getInstance().getLibrary();
+               lib.delete(luid);
+
+               return newInputStreamResponse(NanoHTTPD.MIME_PLAINTEXT, null);
+       }
+
        @Override
        protected List<MetaData> metas(WLoginResult login) throws IOException {
                BasicLibrary lib = Instance.getInstance().getLibrary();