From a0ccd950a62f4c186144e9c858258574757c51ad Mon Sep 17 00:00:00 2001 From: ag2s20150909 Date: Fri, 2 Apr 2021 21:14:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E5=9C=A8io.legado.app.ui.boo?= =?UTF-8?q?k.cache.CacheViewModel=E4=B8=AD=E5=8A=A0=E5=85=A5=E5=AF=BC?= =?UTF-8?q?=E5=87=BAepub=E7=9A=84=E6=96=B9=E6=B3=95=EF=BC=88=E5=B0=81?= =?UTF-8?q?=E9=9D=A2=E6=9C=AA=E5=AE=9E=E7=8E=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/cache/CacheViewModel.kt | 110 ++++++++++++++++++ .../java/me/ag2s/epublib/domain/Date.java | 8 +- .../me/ag2s/epublib/util/ResourceUtil.java | 24 +++- 3 files changed, 138 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt index d420372c6..927b570ed 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt @@ -13,7 +13,11 @@ import io.legado.app.help.BookHelp import io.legado.app.help.ContentProcessor import io.legado.app.help.storage.BookWebDav import io.legado.app.utils.* +import me.ag2s.epublib.domain.* +import me.ag2s.epublib.epub.EpubWriter +import me.ag2s.epublib.util.ResourceUtil import java.io.File +import java.io.FileOutputStream import java.nio.charset.Charset @@ -127,4 +131,110 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { } return srcList } + //////////////////Start EPUB + /** + * 导出Epub + */ + fun exportEPUB(path: String, book: Book, finally: (msg: String) -> Unit) { + execute { + if (path.isContentScheme()) { + val uri = Uri.parse(path) + DocumentFile.fromTreeUri(context, uri)?.let { + exportEpub(it, book) + } + } else { + exportEpub(FileUtils.createFolderIfNotExist(path), book) + } + }.onError { + finally(it.localizedMessage ?: "ERROR") + }.onSuccess { + finally(context.getString(R.string.success)) + } + } + + @Suppress("BlockingMethodInNonBlockingContext") + private suspend fun exportEpub(doc: DocumentFile, book: Book) { + val filename = "${book.name} by ${book.author}.epub" + DocumentUtils.delete(doc, filename) + val epubBook = EpubBook() + epubBook.version = "2.0" + //set metadata + setEpubMetadata(book,epubBook) + //set cover + //Todo + //epubBook.coverImage= Resource(FileInputStream(BookHelp.getImage(book, book.coverUrl)),"cover.jpg") + + //set css + epubBook.resources.add( + Resource( + "h1 {color: blue;}p {text-indent:2em;}".encodeToByteArray(), + "css/style.css" + ) + ) + //设置正文 + setEpubContent(book, epubBook) + + DocumentUtils.createFileIfNotExist(doc, filename)?.let { bookDoc -> + context.contentResolver.openOutputStream(bookDoc.uri, "wa")?.use { bookOs -> + EpubWriter().write(epubBook, bookOs) + } + + } + } + + private suspend fun exportEpub(file: File, book: Book) { + val filename = "${book.name} by ${book.author}.epub" + val epubBook = EpubBook() + epubBook.version = "2.0" + //set metadata + setEpubMetadata(book,epubBook) + //set cover + //Todo + //epubBook.coverImage= Resource(FileInputStream(BookHelp.getImage(book, book.coverUrl)),"cover.jpg") + + //set css + epubBook.resources.add( + Resource( + "h1 {color: blue;}p {text-indent:2em;}".encodeToByteArray(), + "css/style.css" + ) + ) + val bookPath = FileUtils.getPath(file, filename) + val bookFile = FileUtils.createFileWithReplace(bookPath) + //设置正文 + setEpubContent(book, epubBook) + EpubWriter().write(epubBook, FileOutputStream(bookFile)) + } + + private fun setEpubContent(book: Book, epubBook: EpubBook) { + val useReplace = AppConfig.exportUseReplace + val contentProcessor = ContentProcessor(book.name, book.origin) + appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter -> + BookHelp.getContent(book, chapter).let { content -> + val content1 = contentProcessor + .getContent(book, chapter.title, content ?: "null", false, useReplace) + .joinToString("\n") + epubBook.addSection( + chapter.title, + ResourceUtil.createHTMLResource(chapter.title, content1) + ) + } + } + } + + private fun setEpubMetadata(book: Book,epubBook: EpubBook) { + val metadata = Metadata() + metadata.titles.add(book.name)//书籍的名称 + metadata.authors.add(Author(book.author))//书籍的作者 + metadata.language = "zh"//数据的语言 + metadata.dates.add(Date())//数据的创建日期 + metadata.publishers.add("Legado APP")//数据的创建者 + metadata.descriptions.add(book.getDisplayIntro())//书籍的简介 + //metadata.subjects.add("")//书籍的主题,在静读天下里面有使用这个分类书籍 + epubBook.metadata=metadata + } + + //////end of EPUB + + } \ No newline at end of file diff --git a/epublib/src/main/java/me/ag2s/epublib/domain/Date.java b/epublib/src/main/java/me/ag2s/epublib/domain/Date.java index b72990bca..8e25aba5d 100644 --- a/epublib/src/main/java/me/ag2s/epublib/domain/Date.java +++ b/epublib/src/main/java/me/ag2s/epublib/domain/Date.java @@ -1,11 +1,11 @@ package me.ag2s.epublib.domain; -import me.ag2s.epublib.epub.PackageDocumentBase; - import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Locale; +import me.ag2s.epublib.epub.PackageDocumentBase; + /** * A Date used by the book's metadata. *

@@ -48,6 +48,10 @@ public class Date implements Serializable { private Event event; private String dateString; + public Date() { + this(new java.util.Date(), Event.CREATION); + } + public Date(java.util.Date date) { this(date, (Event) null); } diff --git a/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java b/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java index ec742c0b0..96212f253 100644 --- a/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java +++ b/epublib/src/main/java/me/ag2s/epublib/util/ResourceUtil.java @@ -27,7 +27,12 @@ import me.ag2s.epublib.epub.EpubProcessorSupport; * @author paul */ public class ResourceUtil { - + /** + * 快速创建HTML类型的Resource + * @param title 章节的标题 + * @param string 章节的正文 + * @return 返回Resource + */ public static Resource createHTMLResource(String title, String string) { String html = createHtml(title, string); MediaType mediaTypeProperty = MediaTypes.XHTML; @@ -35,6 +40,14 @@ public class ResourceUtil { return new Resource(data, mediaTypeProperty); } + /** + * 快速创建HTML类型的Resource + * @param title 章节的标题 + * @param string 章节的正文 + * @param href Resource的href + * @return 返回Resource + */ + @SuppressWarnings("unused") public static Resource createHTMLResource(String title, String string, String href) { String html = createHtml(title, string); @@ -65,6 +78,13 @@ public class ResourceUtil { return html; } + /** + * 快速从File创建Resource + * @param file File + * @return + * @throws IOException + */ + @SuppressWarnings("unused") public static Resource createResource(File file) throws IOException { if (file == null) { @@ -77,7 +97,7 @@ public class ResourceUtil { /** - * Creates a resource with as contents a html page with the given title. + * 创建一个只带标题的HTMl类型的Resource,常用于封面页,大卷页 * * @param title v * @param href v