X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Foutput%2FEpub.java;h=fc2dc8c982127210c308d6a9dc70a20b667162eb;hp=f27391b4c1e7b6583304bdcb4b05ff45e2ac1850;hb=HEAD;hpb=2206ef66ee00ad42d806f04a7b7ad6f8cb2d8828 diff --git a/src/be/nikiroo/fanfix/output/Epub.java b/src/be/nikiroo/fanfix/output/Epub.java index f27391b..fc2dc8c 100644 --- a/src/be/nikiroo/fanfix/output/Epub.java +++ b/src/be/nikiroo/fanfix/output/Epub.java @@ -1,12 +1,15 @@ package be.nikiroo.fanfix.output; +import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.URL; - -import javax.imageio.ImageIO; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.bundles.Config; @@ -14,25 +17,26 @@ import be.nikiroo.fanfix.bundles.StringId; import be.nikiroo.fanfix.data.Chapter; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Paragraph; -import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.data.Paragraph.ParagraphType; +import be.nikiroo.fanfix.data.Story; import be.nikiroo.utils.IOUtils; import be.nikiroo.utils.StringUtils; class Epub extends BasicOutput { private File tmpDir; - private FileWriter writer; + private BufferedWriter writer; private boolean inDialogue = false; private boolean inNormal = false; private File images; + private boolean nextParaIsCover = true; @Override public File process(Story story, File targetDir, String targetName) throws IOException { String targetNameOrig = targetName; - targetName += getDefaultExtension(); + targetName += getDefaultExtension(false); - tmpDir = File.createTempFile("fanfic-reader-epub_", ".wip"); + tmpDir = Instance.getInstance().getTempFiles().createTempDir("fanfic-reader-epub"); tmpDir.delete(); if (!tmpDir.mkdir()) { @@ -40,25 +44,61 @@ class Epub extends BasicOutput { "Cannot create a temporary directory: no space left on device?"); } - // "Originals" - File data = new File(tmpDir, "DATA"); - data.mkdir(); - new InfoText().process(story, data, targetNameOrig); - IOUtils.writeSmallFile(data, "version", "3.0"); - super.process(story, targetDir, targetNameOrig); - // zip/epub - File epub = new File(targetDir, targetName); - IOUtils.zip(tmpDir, epub, true); - IOUtils.deltree(tmpDir); - tmpDir = null; + File epub = null; + try { + // "Originals" + File data = new File(tmpDir, "DATA"); + data.mkdir(); + BasicOutput.getOutput(OutputType.TEXT, isWriteInfo(), + isWriteCover()).process(story, data, targetNameOrig); + InfoCover.writeInfo(data, targetNameOrig, story.getMeta()); + IOUtils.writeSmallFile(data, "version", "3.0"); + + // zip/epub + epub = new File(targetDir, targetName); + IOUtils.zip(tmpDir, epub, true); + + OutputStream out = new FileOutputStream(epub); + try { + ZipOutputStream zip = new ZipOutputStream(out); + try { + // "mimetype" MUST be the first element and not compressed + zip.setLevel(ZipOutputStream.STORED); + File mimetype = new File(tmpDir, "mimetype"); + IOUtils.writeSmallFile(tmpDir, "mimetype", + "application/epub+zip"); + ZipEntry entry = new ZipEntry("mimetype"); + entry.setExtra(new byte[] {}); + zip.putNextEntry(entry); + FileInputStream in = new FileInputStream(mimetype); + try { + IOUtils.write(in, zip); + } finally { + in.close(); + } + IOUtils.deltree(mimetype); + zip.setLevel(ZipOutputStream.DEFLATED); + // + + IOUtils.zip(zip, "", tmpDir, true); + } finally { + zip.close(); + } + } finally { + out.close(); + } + } finally { + IOUtils.deltree(tmpDir); + tmpDir = null; + } return epub; } @Override - public String getDefaultExtension() { + public String getDefaultExtension(boolean readerTarget) { return ".epub"; } @@ -73,11 +113,8 @@ class Epub extends BasicOutput { File metaInf = new File(tmpDir, "META-INF"); metaInf.mkdirs(); - // "root" - IOUtils.writeSmallFile(tmpDir, "mimetype", "application/epub+zip"); - // META-INF - String containerContent = "\n" + String containerContent = "\n" + "\n" + "\t\n" + "\t\t\n" @@ -98,16 +135,18 @@ class Epub extends BasicOutput { // OPS/images if (story.getMeta() != null && story.getMeta().getCover() != null) { - String format = Instance.getConfig() - .getString(Config.IMAGE_FORMAT_COVER).toLowerCase(); - File file = new File(images, "cover." + format); - ImageIO.write(story.getMeta().getCover(), format, file); + File file = new File(images, "cover"); + try { + Instance.getInstance().getCache().saveAsImage(story.getMeta().getCover(), file, true); + } catch (Exception e) { + Instance.getInstance().getTraceHandler().error(e); + } } // OPS/* except chapters IOUtils.writeSmallFile(ops, "epb.ncx", generateNcx(story)); IOUtils.writeSmallFile(ops, "epb.opf", generateOpf(story)); - IOUtils.writeSmallFile(ops, "title.xml", generateTitleXml(story)); + IOUtils.writeSmallFile(ops, "title.xhtml", generateTitleXml(story)); // Resume if (story.getMeta() != null && story.getMeta().getResume() != null) { @@ -118,8 +157,10 @@ class Epub extends BasicOutput { @Override protected void writeChapterHeader(Chapter chap) throws IOException { String filename = String.format("%s%03d%s", "chapter-", - chap.getNumber(), ".xml"); - writer = new FileWriter(new File(tmpDir + "/OPS", filename)); + chap.getNumber(), ".xhtml"); + writer = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(new File(tmpDir + File.separator + "OPS", + filename)), "UTF-8")); inDialogue = false; inNormal = false; try { @@ -130,9 +171,9 @@ class Epub extends BasicOutput { nameOrNum = chap.getName(); } - writer.write(""); - writer.write("\n"); - writer.write("\n"); + writer.append(""); + writer.append("\n"); + writer.append("\n"); writer.write("\n"); writer.write("\n " + StringUtils.xmlEscape(title) + ""); @@ -194,7 +235,7 @@ class Epub extends BasicOutput { writer.write("
"); break; case BREAK: - writer.write("
"); + writer.write("
"); break; case NORMAL: writer.write(" "); @@ -204,11 +245,13 @@ class Epub extends BasicOutput { break; case IMAGE: File file = new File(images, getCurrentImageBestName(false)); - Instance.getCache().saveAsImage(new URL(para.getContent()), file); - writer.write(" "); break; } + + nextParaIsCover = false; } @Override @@ -262,7 +305,7 @@ class Epub extends BasicOutput { title = meta.getTitle(); } - builder.append(""); + builder.append(""); builder.append("\n"); builder.append("\n"); @@ -290,7 +333,7 @@ class Epub extends BasicOutput { builder.append("\n "); builder.append("\n Title Page"); builder.append("\n "); - builder.append("\n "); + builder.append("\n "); builder.append("\n "); int navPoint = 2; // 1 is above @@ -313,11 +356,10 @@ class Epub extends BasicOutput { private void generateNcx(Chapter chap, StringBuilder builder, int navPoint) { String name; if (chap.getName() != null && !chap.getName().isEmpty()) { - name = Instance.getTrans().getString(StringId.CHAPTER_NAMED, - chap.getNumber(), chap.getName()); + name = Instance.getInstance().getTrans().getString(StringId.CHAPTER_NAMED, chap.getNumber(), + chap.getName()); } else { - name = Instance.getTrans().getString(StringId.CHAPTER_UNNAMED, - chap.getNumber()); + name = Instance.getInstance().getTrans().getString(StringId.CHAPTER_UNNAMED, chap.getNumber()); } String nnn = String.format("%03d", (navPoint - 2)); @@ -327,7 +369,7 @@ class Epub extends BasicOutput { builder.append("\n "); builder.append("\n " + name + ""); builder.append("\n "); - builder.append("\n "); + builder.append("\n "); builder.append("\n \n"); } @@ -354,9 +396,8 @@ class Epub extends BasicOutput { lang = meta.getLang(); } - builder.append(""); - builder.append("\n"); + builder.append(""); + builder.append("\n"); builder.append("\n "); builder.append("\n " + StringUtils.xmlEscape(title) @@ -374,20 +415,20 @@ class Epub extends BasicOutput { builder.append("\n " + StringUtils.xmlEscape(source) + ""); builder.append("\n Not for commercial use."); - builder.append("\n " + builder.append("\n " + StringUtils.xmlEscape(uuid) + ""); builder.append("\n " + StringUtils.xmlEscape(lang) + ""); builder.append("\n "); builder.append("\n "); builder.append("\n "); - builder.append("\n "); + builder.append("\n "); for (int i = 0; i <= story.getChapters().size(); i++) { String name = String.format("%s%03d", "chapter-", i); builder.append("\n "); + + ".xhtml\" media-type=\"application/xhtml+xml\"/>"); } builder.append("\n "); @@ -396,8 +437,9 @@ class Epub extends BasicOutput { builder.append("\n "); if (story.getMeta() != null && story.getMeta().getCover() != null) { - String format = Instance.getConfig() - .getString(Config.IMAGE_FORMAT_COVER).toLowerCase(); + String format = Instance.getInstance().getConfig() + .getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER) + .toLowerCase(); builder.append("\n "); } @@ -442,12 +484,12 @@ class Epub extends BasicOutput { author = meta.getAuthor(); } - String format = Instance.getConfig() - .getString(Config.IMAGE_FORMAT_COVER).toLowerCase(); + String format = Instance.getInstance().getConfig() + .getString(Config.FILE_FORMAT_IMAGE_FORMAT_COVER).toLowerCase(); - builder.append(""); - builder.append("\n"); - builder.append("\n"); + builder.append(""); + builder.append("\n"); + builder.append("\n"); builder.append("\n"); builder.append("\n " + StringUtils.xmlEscape(title) + ""); builder.append("\n "); @@ -458,7 +500,8 @@ class Epub extends BasicOutput { builder.append("\n
" + StringUtils.xmlEscape(tags) + "
"); builder.append("\n
"); - builder.append("\n "); + builder.append("\n \"cover"); builder.append("\n
"); builder.append("\n
" + StringUtils.xmlEscape(author) + "
");