- private Response getViewer(Map<String, String> cookies, String uri,
- List<String> whitelist) {
- String[] cover = uri.split("/");
- int off = 2;
-
- if (cover.length < off + 2) {
- return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
- NanoHTTPD.MIME_PLAINTEXT, null);
- }
-
- String type = cover[off + 0];
- String luid = cover[off + 1];
- String chapterStr = cover.length < off + 3 ? null : cover[off + 2];
- String paragraphStr = cover.length < off + 4 ? null : cover[off + 3];
-
- // 1-based (0 = desc)
- int chapter = -1;
- if (chapterStr != null) {
- try {
- chapter = Integer.parseInt(chapterStr);
- if (chapter < 0) {
- throw new NumberFormatException();
- }
- } catch (NumberFormatException e) {
- return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
- NanoHTTPD.MIME_PLAINTEXT, "Chapter is not valid");
- }
- }
-
- // 1-based
- int paragraph = 0;
- if (paragraphStr != null) {
- try {
- paragraph = Integer.parseInt(paragraphStr);
- if (paragraph <= 0) {
- throw new NumberFormatException();
- }
- } catch (NumberFormatException e) {
- return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST,
- NanoHTTPD.MIME_PLAINTEXT, "Paragraph is not valid");
- }
- }
-
- try {
- Story story = story(luid, whitelist);
- if (story == null) {
- return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND,
- NanoHTTPD.MIME_PLAINTEXT, "Story not found");
- }
-
- StringBuilder builder = new StringBuilder();
- appendPreHtml(builder, false);
-
- // For images documents, always go to the images if not chap 0 desc
- if (story.getMeta().isImageDocument()) {
- if (chapter > 0 && paragraph <= 0)
- paragraph = 1;
- }
-
- Chapter chap = null;
- if (chapter <= 0) {
- chap = story.getMeta().getResume();
- } else {
- try {
- chap = story.getChapters().get(chapter - 1);
- } catch (IndexOutOfBoundsException e) {
- return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND,
- NanoHTTPD.MIME_PLAINTEXT, "Chapter not found");
- }
- }
-
- String first, previous, next, last;
-
- StringBuilder content = new StringBuilder();
-
- String disabledLeft = "";
- String disabledRight = "";
- String disabledZoomReal = "";
- String disabledZoomWidth = "";
- String disabledZoomHeight = "";
-
- if (paragraph <= 0) {
- first = getViewUrl(luid, 0, null);
- previous = getViewUrl(luid, (Math.max(chapter - 1, 0)), null);
- next = getViewUrl(luid,
- (Math.min(chapter + 1, story.getChapters().size())),
- null);
- last = getViewUrl(luid, story.getChapters().size(), null);
-
- StringBuilder desc = new StringBuilder();
-
- if (chapter <= 0) {
- desc.append("<h1 class='title'>");
- desc.append(story.getMeta().getTitle());
- desc.append("</h1>\n");
- desc.append("<div class='desc'>\n");
- desc.append("\t<div class='cover'>\n");
- desc.append("\t\t<img src='/story/" + luid + "/cover'/>\n");
- desc.append("\t</div>\n");
- desc.append("\t<table class='details'>\n");
- Map<String, String> details = BasicLibrary
- .getMetaDesc(story.getMeta());
- for (String key : details.keySet()) {
- appendTableRow(desc, 2, key, details.get(key));
- }
- desc.append("\t</table>\n");
- desc.append("</div>\n");
- desc.append("<h1 class='title'>Description</h1>\n");
- }
-
- content.append("<div class='viewer text'>\n");
- content.append(desc);
- String description = new TextOutput(false).convert(chap,
- chapter > 0);
- content.append(chap.getParagraphs().size() <= 0
- ? "No content provided."
- : description);
- content.append("</div>\n");
-
- if (chapter <= 0)
- disabledLeft = " disabled='disbaled'";
- if (chapter >= story.getChapters().size())
- disabledRight = " disabled='disbaled'";
- } else {
- first = getViewUrl(luid, chapter, 1);
- previous = getViewUrl(luid, chapter,
- (Math.max(paragraph - 1, 1)));
- next = getViewUrl(luid, chapter,
- (Math.min(paragraph + 1, chap.getParagraphs().size())));
- last = getViewUrl(luid, chapter, chap.getParagraphs().size());
-
- if (paragraph <= 1)
- disabledLeft = " disabled='disbaled'";
- if (paragraph >= chap.getParagraphs().size())
- disabledRight = " disabled='disbaled'";
-
- // First -> previous *chapter*
- if (chapter > 0)
- disabledLeft = "";
- first = getViewUrl(luid, (Math.max(chapter - 1, 0)), null);
- if (paragraph <= 1) {
- previous = first;
- }
-
- Paragraph para = null;
- try {
- para = chap.getParagraphs().get(paragraph - 1);
- } catch (IndexOutOfBoundsException e) {
- return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND,
- NanoHTTPD.MIME_PLAINTEXT,
- "Paragraph " + paragraph + " not found");
- }
-
- if (para.getType() == ParagraphType.IMAGE) {
- String zoomStyle = "max-width: 100%;";
- disabledZoomWidth = " disabled='disabled'";
- String zoomOption = cookies.get("zoom");
- if (zoomOption != null && !zoomOption.isEmpty()) {
- if (zoomOption.equals("real")) {
- zoomStyle = "";
- disabledZoomWidth = "";
- disabledZoomReal = " disabled='disabled'";
- } else if (zoomOption.equals("width")) {
- zoomStyle = "max-width: 100%;";
- } else if (zoomOption.equals("height")) {
- // see height of navbar + optionbar
- zoomStyle = "max-height: calc(100% - 128px);";
- disabledZoomWidth = "";
- disabledZoomHeight = " disabled='disabled'";
- }
- }
-
- content.append(String.format("" //
- + "<a class='viewer link' href='%s'>"
- + "<img class='viewer img' style='%s' src='%s'/>"
- + "</a>", //
- next, //
- zoomStyle, //
- getStoryUrl(luid, chapter, paragraph)));
- } else {
- content.append(String.format("" //
- + "<div class='viewer text'>%s</div>", //
- para.getContent()));
- }
- }
-
- builder.append(String.format("" //
- + "<div class='bar navbar'>\n" //
- + "\t<a%s class='button first' href='%s'><<</a>\n"//
- + "\t<a%s class='button previous' href='%s'><</a>\n" //
- + "\t<div class='gotobox itemsbox'>\n" //
- + "\t\t<div class='button goto'>%d</div>\n" //
- + "\t\t<div class='items goto'>\n", //
- disabledLeft, first, //
- disabledLeft, previous, //
- paragraph > 0 ? paragraph : chapter //
- ));
-
- // List of chap/para links
-
- String blink = "/view/story/" + luid + "/";
- appendItemA(builder, 3, blink + "0", "Description",
- paragraph == 0 && chapter == 0);
-
- if (paragraph > 0) {
- blink = blink + chapter + "/";
- for (int i = 1; i <= chap.getParagraphs().size(); i++) {
- appendItemA(builder, 3, blink + i, "Image " + i,
- paragraph == i);
- }
- } else {
- int i = 1;
- for (Chapter c : story.getChapters()) {
- String chapName = "Chapter " + c.getNumber();
- if (c.getName() != null && !c.getName().isEmpty()) {
- chapName += ": " + c.getName();
- }
-
- appendItemA(builder, 3, blink + i, chapName, chapter == i);
-
- i++;
- }
- }
-
- builder.append(String.format("" //
- + "\t\t</div>\n" //
- + "\t</div>\n" //
- + "\t<a%s class='button next' href='%s'>></a>\n" //
- + "\t<a%s class='button last' href='%s'>>></a>\n"//
- + "</div>\n", //
- disabledRight, next, //
- disabledRight, last //
- ));
-
- builder.append(content);
-
- builder.append("<div class='bar optionbar ");
- if (paragraph > 0) {
- builder.append("s4");
- } else {
- builder.append("s1");
- }
- builder.append("'>\n");
- builder.append(" <a class='button back' href='/'>BACK</a>\n");
-
- if (paragraph > 0) {
- builder.append(String.format("" //
- + "\t<a%s class='button zoomreal' href='%s'>REAL</a>\n"//
- + "\t<a%s class='button zoomwidth' href='%s'>WIDTH</a>\n"//
- + "\t<a%s class='button zoomheight' href='%s'>HEIGHT</a>\n"//
- + "</div>\n", //
- disabledZoomReal,
- uri + "?optionName=zoom&optionValue=real", //
- disabledZoomWidth,
- uri + "?optionName=zoom&optionValue=width", //
- disabledZoomHeight,
- uri + "?optionName=zoom&optionValue=height" //
- ));
- }
-
- appendPostHtml(builder);
- return NanoHTTPD.newFixedLengthResponse(Status.OK,
- NanoHTTPD.MIME_HTML, builder.toString());
- } catch (IOException e) {
- Instance.getInstance().getTraceHandler()
- .error(new IOException("Cannot get image: " + uri, e));
- return NanoHTTPD.newFixedLengthResponse(Status.INTERNAL_ERROR,
- NanoHTTPD.MIME_PLAINTEXT, "Error when processing request");
- }
- }
-
- private Response newInputStreamResponse(String mimeType, InputStream in) {
- if (in == null) {
- return NanoHTTPD.newFixedLengthResponse(Status.NO_CONTENT, "",
- null);
- }
- return NanoHTTPD.newChunkedResponse(Status.OK, mimeType, in);
- }
-
- private String getContentOf(String file) {
- InputStream in = IOUtils.openResource(WebLibraryServerIndex.class,
- file);
- if (in != null) {
- try {
- return IOUtils.readSmallStream(in);
- } catch (IOException e) {
- Instance.getInstance().getTraceHandler().error(
- new IOException("Cannot get file: index.pre.html", e));
- }
- }
-
- return "";
- }
-
- private String getViewUrl(String luid, int chap, Integer para) {
- return VIEWER_URL //
- .replace("{luid}", luid) //
- .replace("{chap}", Integer.toString(chap)) //
- .replace("/{para}",
- para == null ? "" : "/" + Integer.toString(para));
- }
-
- private String getStoryUrl(String luid, int chap, Integer para) {
- return STORY_URL //
- .replace("{luid}", luid) //
- .replace("{chap}", Integer.toString(chap)) //
- .replace("{para}", para == null ? "" : Integer.toString(para));
- }
-
- private String getStoryUrlCover(String luid) {
- return STORY_URL_COVER //
- .replace("{luid}", luid);
- }
-
- private MetaData meta(String luid, List<String> whitelist)
- throws IOException {