|
|
|
@ -1,8 +1,8 @@ |
|
|
|
|
package io.legado.app.model.localBook |
|
|
|
|
|
|
|
|
|
import android.content.Context |
|
|
|
|
import android.net.Uri |
|
|
|
|
import android.text.TextUtils |
|
|
|
|
import io.legado.app.App |
|
|
|
|
import io.legado.app.data.entities.BookChapter |
|
|
|
|
import io.legado.app.utils.htmlFormat |
|
|
|
|
import io.legado.app.utils.isContentPath |
|
|
|
@ -15,8 +15,30 @@ import java.io.IOException |
|
|
|
|
import java.nio.charset.Charset |
|
|
|
|
import java.util.* |
|
|
|
|
|
|
|
|
|
class EPUBFile(context: Context, val book: io.legado.app.data.entities.Book) { |
|
|
|
|
var epubBook: Book? = null |
|
|
|
|
class EPUBFile(val book: io.legado.app.data.entities.Book) { |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
private var eFile: EPUBFile? = null |
|
|
|
|
|
|
|
|
|
@Synchronized |
|
|
|
|
fun getEFile(book: io.legado.app.data.entities.Book): EPUBFile { |
|
|
|
|
if (eFile == null || eFile?.book?.bookUrl == book.bookUrl) { |
|
|
|
|
eFile = EPUBFile(book) |
|
|
|
|
return eFile!! |
|
|
|
|
} |
|
|
|
|
return eFile!! |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun getChapterList(book: io.legado.app.data.entities.Book): ArrayList<BookChapter> { |
|
|
|
|
return getEFile(book).getChapterList() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun getContent(book: io.legado.app.data.entities.Book, chapter: BookChapter): String? { |
|
|
|
|
return getEFile(book).getContent(chapter) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private var epubBook: Book? = null |
|
|
|
|
private lateinit var mCharset: Charset |
|
|
|
|
|
|
|
|
|
init { |
|
|
|
@ -24,7 +46,7 @@ class EPUBFile(context: Context, val book: io.legado.app.data.entities.Book) { |
|
|
|
|
val epubReader = EpubReader() |
|
|
|
|
val inputStream = if (book.bookUrl.isContentPath()) { |
|
|
|
|
val uri = Uri.parse(book.bookUrl) |
|
|
|
|
context.contentResolver.openInputStream(uri) |
|
|
|
|
App.INSTANCE.contentResolver.openInputStream(uri) |
|
|
|
|
} else { |
|
|
|
|
File(book.bookUrl).inputStream() |
|
|
|
|
} |
|
|
|
@ -33,88 +55,90 @@ class EPUBFile(context: Context, val book: io.legado.app.data.entities.Book) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun getContent(chapter: BookChapter): String { |
|
|
|
|
val resource = epubBook!!.resources.getByHref(chapter.url) |
|
|
|
|
val content = StringBuilder() |
|
|
|
|
val doc = Jsoup.parse(String(resource.data, mCharset)) |
|
|
|
|
val elements = doc.allElements |
|
|
|
|
for (element in elements) { |
|
|
|
|
val contentEs = element.textNodes() |
|
|
|
|
for (i in contentEs.indices) { |
|
|
|
|
val text = contentEs[i].text().trim { it <= ' ' }.htmlFormat() |
|
|
|
|
if (elements.size > 1) { |
|
|
|
|
if (text.isNotEmpty()) { |
|
|
|
|
if (content.isNotEmpty()) { |
|
|
|
|
content.append("\r\n") |
|
|
|
|
fun getContent(chapter: BookChapter): String? { |
|
|
|
|
epubBook?.let { eBook -> |
|
|
|
|
val resource = eBook.resources.getByHref(chapter.url) |
|
|
|
|
val content = StringBuilder() |
|
|
|
|
val doc = Jsoup.parse(String(resource.data, mCharset)) |
|
|
|
|
val elements = doc.allElements |
|
|
|
|
for (element in elements) { |
|
|
|
|
val contentEs = element.textNodes() |
|
|
|
|
for (i in contentEs.indices) { |
|
|
|
|
val text = contentEs[i].text().trim { it <= ' ' }.htmlFormat() |
|
|
|
|
if (elements.size > 1) { |
|
|
|
|
if (text.isNotEmpty()) { |
|
|
|
|
if (content.isNotEmpty()) { |
|
|
|
|
content.append("\r\n") |
|
|
|
|
} |
|
|
|
|
content.append("\u3000\u3000").append(text) |
|
|
|
|
} |
|
|
|
|
content.append("\u3000\u3000").append(text) |
|
|
|
|
} else { |
|
|
|
|
content.append(text) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
content.append(text) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return content.toString() |
|
|
|
|
} |
|
|
|
|
return content.toString() |
|
|
|
|
return null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun getChapterList(epubBook: Book): ArrayList<BookChapter> { |
|
|
|
|
val metadata = epubBook.metadata |
|
|
|
|
book.name = metadata.firstTitle |
|
|
|
|
if (metadata.authors.size > 0) { |
|
|
|
|
val author = |
|
|
|
|
metadata.authors[0].toString().replace("^, |, $".toRegex(), "") |
|
|
|
|
book.author = author |
|
|
|
|
} |
|
|
|
|
if (metadata.descriptions.size > 0) { |
|
|
|
|
book.intro = Jsoup.parse(metadata.descriptions[0]).text() |
|
|
|
|
} |
|
|
|
|
fun getChapterList(): ArrayList<BookChapter> { |
|
|
|
|
val chapterList = ArrayList<BookChapter>() |
|
|
|
|
val refs = |
|
|
|
|
epubBook.tableOfContents.tocReferences |
|
|
|
|
if (refs == null || refs.isEmpty()) { |
|
|
|
|
val spineReferences = |
|
|
|
|
epubBook.spine.spineReferences |
|
|
|
|
var i = 0 |
|
|
|
|
val size = spineReferences.size |
|
|
|
|
while (i < size) { |
|
|
|
|
val resource = |
|
|
|
|
spineReferences[i].resource |
|
|
|
|
var title = resource.title |
|
|
|
|
if (TextUtils.isEmpty(title)) { |
|
|
|
|
try { |
|
|
|
|
val doc = |
|
|
|
|
Jsoup.parse(String(resource.data, mCharset)) |
|
|
|
|
val elements = doc.getElementsByTag("title") |
|
|
|
|
if (elements.size > 0) { |
|
|
|
|
title = elements[0].text() |
|
|
|
|
epubBook?.let { eBook -> |
|
|
|
|
val metadata = eBook.metadata |
|
|
|
|
book.name = metadata.firstTitle |
|
|
|
|
if (metadata.authors.size > 0) { |
|
|
|
|
val author = |
|
|
|
|
metadata.authors[0].toString().replace("^, |, $".toRegex(), "") |
|
|
|
|
book.author = author |
|
|
|
|
} |
|
|
|
|
if (metadata.descriptions.size > 0) { |
|
|
|
|
book.intro = Jsoup.parse(metadata.descriptions[0]).text() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val refs = eBook.tableOfContents.tocReferences |
|
|
|
|
if (refs == null || refs.isEmpty()) { |
|
|
|
|
val spineReferences = eBook.spine.spineReferences |
|
|
|
|
var i = 0 |
|
|
|
|
val size = spineReferences.size |
|
|
|
|
while (i < size) { |
|
|
|
|
val resource = |
|
|
|
|
spineReferences[i].resource |
|
|
|
|
var title = resource.title |
|
|
|
|
if (TextUtils.isEmpty(title)) { |
|
|
|
|
try { |
|
|
|
|
val doc = |
|
|
|
|
Jsoup.parse(String(resource.data, mCharset)) |
|
|
|
|
val elements = doc.getElementsByTag("title") |
|
|
|
|
if (elements.size > 0) { |
|
|
|
|
title = elements[0].text() |
|
|
|
|
} |
|
|
|
|
} catch (e: IOException) { |
|
|
|
|
e.printStackTrace() |
|
|
|
|
} |
|
|
|
|
} catch (e: IOException) { |
|
|
|
|
e.printStackTrace() |
|
|
|
|
} |
|
|
|
|
val chapter = BookChapter() |
|
|
|
|
chapter.index = i |
|
|
|
|
chapter.bookUrl = book.bookUrl |
|
|
|
|
chapter.url = resource.href |
|
|
|
|
if (i == 0 && title.isEmpty()) { |
|
|
|
|
chapter.title = "封面" |
|
|
|
|
} else { |
|
|
|
|
chapter.title = title |
|
|
|
|
} |
|
|
|
|
chapterList.add(chapter) |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
val chapter = BookChapter() |
|
|
|
|
chapter.index = i |
|
|
|
|
chapter.bookUrl = book.bookUrl |
|
|
|
|
chapter.url = resource.href |
|
|
|
|
if (i == 0 && title.isEmpty()) { |
|
|
|
|
chapter.title = "封面" |
|
|
|
|
} else { |
|
|
|
|
chapter.title = title |
|
|
|
|
} else { |
|
|
|
|
parseMenu(chapterList, refs, 0) |
|
|
|
|
for (i in chapterList.indices) { |
|
|
|
|
chapterList[i].index = i |
|
|
|
|
} |
|
|
|
|
chapterList.add(chapter) |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
parseMenu(chapterList, refs, 0) |
|
|
|
|
for (i in chapterList.indices) { |
|
|
|
|
chapterList[i].index = i |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return chapterList |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun parseMenu( |
|
|
|
|
chapterList: ArrayList<BookChapter>, |
|
|
|
|
refs: List<TOCReference>?, |
|
|
|
|