+ // /story/luid/source
+ // /story/luid/title
+ // /story/luid/author
+ @Override
+ protected Response setStoryPart(String uri, String value,
+ WLoginResult login) throws IOException {
+ String[] uriParts = uri.split("/");
+ int off = 2; // "" and "story"
+
+ if (uriParts.length < off + 2) {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT, "Invalid story part request");
+ }
+
+ if (!login.isRw()) {
+ return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+ NanoHTTPD.MIME_PLAINTEXT, "SET story part not allowed");
+ }
+
+ String luid = uriParts[off + 0];
+ String type = uriParts[off + 1];
+
+ if (!Arrays.asList("source", "title", "author").contains(type)) {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT,
+ "Invalid SET story part: " + type);
+ }
+
+ if (meta(luid, login) != null) {
+ BasicLibrary lib = Instance.getInstance().getLibrary();
+ if ("source".equals(type)) {
+ lib.changeSource(luid, value, null);
+ } else if ("title".equals(type)) {
+ lib.changeTitle(luid, value, null);
+ } else if ("author".equals(type)) {
+ lib.changeAuthor(luid, value, null);
+ }
+ }
+
+ return newInputStreamResponse(NanoHTTPD.MIME_PLAINTEXT, null);
+ }
+
+ @Override
+ protected Response getCover(String uri, WLoginResult login)
+ throws IOException {
+ String[] uriParts = uri.split("/");
+ int off = 2; // "" and "cover"
+
+ if (uriParts.length < off + 2) {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT, "Invalid cover request");
+ }
+
+ String type = uriParts[off + 0];
+ String id = uriParts[off + 1];
+
+ InputStream in = null;
+
+ if ("story".equals(type)) {
+ Image img = storyCover(id, login);
+ if (img != null) {
+ in = img.newInputStream();
+ }
+ } else if ("source".equals(type)) {
+ Image img = sourceCover(id, login);
+ if (img != null) {
+ in = img.newInputStream();
+ }
+ } else if ("author".equals(type)) {
+ Image img = authorCover(id, login);
+ if (img != null) {
+ in = img.newInputStream();
+ }
+ } else {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT,
+ "Invalid GET cover type: " + type);
+ }
+
+ // TODO: get correct image type
+ return newInputStreamResponse("image/png", in);
+ }
+
+ @Override
+ protected Response setCover(String uri, String luid, WLoginResult login)
+ throws IOException {
+ String[] uriParts = uri.split("/");
+ int off = 2; // "" and "cover"
+
+ if (uriParts.length < off + 2) {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT, "Invalid cover request");
+ }
+
+ if (!login.isRw()) {
+ return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN,
+ NanoHTTPD.MIME_PLAINTEXT, "Cover request not allowed");
+ }
+
+ String type = uriParts[off + 0];
+ String id = uriParts[off + 1];
+
+ if ("source".equals(type)) {
+ sourceCover(id, login, luid);
+ } else if ("author".equals(type)) {
+ authorCover(id, login, luid);
+ } else {
+ return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
+ NanoHTTPD.MIME_PLAINTEXT,
+ "Invalid SET cover type: " + type);
+ }
+
+ 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");
+ }
+
+ final URL url = new URL(urlStr);
+ final Progress pg = new Progress();
+ final String luid = lib.getNextId();
+
+ // Keep the latest name
+ pg.addProgressListener(new ProgressListener() {
+ @Override
+ public void progress(Progress progress, String name) {
+ pg.setName(name);
+ }
+ });
+
+ 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");
+ }
+
+ String luid = uriParts[off + 0];
+
+ BasicLibrary lib = Instance.getInstance().getLibrary();
+ lib.delete(luid);
+
+ return newInputStreamResponse(NanoHTTPD.MIME_PLAINTEXT, null);
+ }
+