- 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);
-
- // TODO: no desc page for images?
- if (story.getMeta().isImageDocument()) {
- if (chapter <= 0)
- chapter = 1;
- if (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, 1, null);
- previous = getViewUrl(luid, (Math.max(chapter - 1, 1)), null);
- next = getViewUrl(luid,
- (Math.min(chapter + 1, story.getChapters().size())),
- null);
- last = getViewUrl(luid, story.getChapters().size(), null);
-
- // TODO
- StringBuilder desc = new StringBuilder();
-
- if (chapter <= 0) {
- 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>\n");
- desc.append("\t\t<tr><th>HEAD 1</th><th>HEAD 2</th></tr>\n");
- desc.append("\t\t<tr><td>KEY 1</td><td>VAL 1</td></tr>\n");
- desc.append("\t\t<tr><td>KEY 2</td><td>VAL 2</td></tr>\n");
- 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);
- content.append(new TextOutput(false).convert(chap, chapter > 0));
- content.append("</div>\n");
-
- if (chapter <= 1)
- 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'";
-
- 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(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<a%s class='button next' href='%s'>></a>\n"//
- + "\t<a%s class='button last' href='%s'>>></a>\n"//
- + "</div>\n", //
- disabledLeft, first, //
- disabledLeft, previous, //
- 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 {