|
|
|
@ -7,12 +7,10 @@ import android.text.TextUtils |
|
|
|
|
import io.legado.app.data.appDb |
|
|
|
|
import io.legado.app.data.entities.Book |
|
|
|
|
import io.legado.app.data.entities.BookChapter |
|
|
|
|
import io.legado.app.data.entities.EpubChapter |
|
|
|
|
import io.legado.app.utils.* |
|
|
|
|
import me.ag2s.epublib.domain.EpubBook |
|
|
|
|
import me.ag2s.epublib.domain.MediaTypes |
|
|
|
|
import me.ag2s.epublib.domain.Resources |
|
|
|
|
import me.ag2s.epublib.domain.TOCReference |
|
|
|
|
import me.ag2s.epublib.epub.EpubReader |
|
|
|
|
import me.ag2s.epublib.util.ResourceUtil |
|
|
|
|
import org.jsoup.Jsoup |
|
|
|
@ -212,15 +210,7 @@ class EpubFile(var book: Book) { |
|
|
|
|
|
|
|
|
|
private fun getChapterList(): ArrayList<BookChapter> { |
|
|
|
|
val chapterList = ArrayList<BookChapter>() |
|
|
|
|
epubBook?.let { eBook -> |
|
|
|
|
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 |
|
|
|
|
epubBook?.tableOfContents?.allUniqueResources?.forEachIndexed { index, resource -> |
|
|
|
|
var title = resource.title |
|
|
|
|
if (TextUtils.isEmpty(title)) { |
|
|
|
|
try { |
|
|
|
@ -235,133 +225,19 @@ class EpubFile(var book: Book) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
val chapter = BookChapter() |
|
|
|
|
chapter.index = i |
|
|
|
|
chapter.index = index |
|
|
|
|
chapter.bookUrl = book.bookUrl |
|
|
|
|
chapter.url = resource.href |
|
|
|
|
if (i == 0 && title.isEmpty()) { |
|
|
|
|
if (index == 0 && title.isEmpty()) { |
|
|
|
|
chapter.title = "封面" |
|
|
|
|
} else { |
|
|
|
|
chapter.title = title |
|
|
|
|
} |
|
|
|
|
chapterList.add(chapter) |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
parseFirstPage(chapterList, refs) |
|
|
|
|
parseMenu(chapterList, refs, 0) |
|
|
|
|
for (i in chapterList.indices) { |
|
|
|
|
chapterList[i].index = i |
|
|
|
|
} |
|
|
|
|
getChildChapter(chapterList) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
book.latestChapterTitle = chapterList.lastOrNull()?.title |
|
|
|
|
book.totalChapterNum = chapterList.size |
|
|
|
|
return chapterList |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*获取当前章节的子章节。部分书籍一个章节包含多个html文件,(一些精排书籍,每一章节正文前的标题、标题封面、引言等都会有独立html)*/ |
|
|
|
|
/*需在读取常规章节列表后调用,遍历书籍全内容,根据href检索原不包含在章节内的html归属父章节*/ |
|
|
|
|
private fun getChildChapter(chapterList: ArrayList<BookChapter>) { |
|
|
|
|
epubBook?.let { |
|
|
|
|
val contents = it.contents |
|
|
|
|
val chapters = ArrayList<EpubChapter>() |
|
|
|
|
if (contents != null) { |
|
|
|
|
var i = 0 |
|
|
|
|
var j = 0 |
|
|
|
|
var parentHref: String? = null |
|
|
|
|
while (i < contents.size) { |
|
|
|
|
val content = contents[i] |
|
|
|
|
if (j < chapterList.size && content.href == chapterList[j].url) { |
|
|
|
|
parentHref = content.href |
|
|
|
|
j++ |
|
|
|
|
} else if (!parentHref.isNullOrBlank() && content.mediaType.toString() |
|
|
|
|
.contains("htm") |
|
|
|
|
) { |
|
|
|
|
val epubChapter = EpubChapter() |
|
|
|
|
epubChapter.bookUrl = book.bookUrl |
|
|
|
|
epubChapter.href = content.href |
|
|
|
|
epubChapter.parentHref = parentHref |
|
|
|
|
chapters.add(epubChapter) |
|
|
|
|
} |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
appDb.epubChapterDao.deleteByName(book.bookUrl) |
|
|
|
|
if (chapters.size > 0) appDb.epubChapterDao.insert(*chapters.toTypedArray()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*获取书籍起始页内容。部分书籍第一章之前存在封面,引言,扉页等内容*/ |
|
|
|
|
/*tile获取不同书籍风格杂乱,格式化处理待优化*/ |
|
|
|
|
private var durIndex = 0 |
|
|
|
|
private fun parseFirstPage( |
|
|
|
|
chapterList: ArrayList<BookChapter>, |
|
|
|
|
refs: List<TOCReference>? |
|
|
|
|
) { |
|
|
|
|
val contents = epubBook?.contents |
|
|
|
|
if (epubBook == null || contents == null || refs == null) return |
|
|
|
|
var i = 0 |
|
|
|
|
durIndex = 0 |
|
|
|
|
while (i < contents.size) { |
|
|
|
|
val content = contents[i] |
|
|
|
|
if (!content.mediaType.toString().contains("htm")) continue |
|
|
|
|
/*检索到第一章href停止*/ |
|
|
|
|
if (refs[0].completeHref == content.href) break |
|
|
|
|
val chapter = BookChapter() |
|
|
|
|
var title = content.title |
|
|
|
|
if (TextUtils.isEmpty(title)) { |
|
|
|
|
val elements = Jsoup.parse( |
|
|
|
|
String( |
|
|
|
|
epubBook!!.resources.getByHref(content.href).data, |
|
|
|
|
mCharset |
|
|
|
|
) |
|
|
|
|
).getElementsByTag("title") |
|
|
|
|
title = |
|
|
|
|
if (elements != null && elements.size > 0 && elements[0].text() |
|
|
|
|
.isNotBlank() |
|
|
|
|
) elements[0].text() else "--卷首--" |
|
|
|
|
} |
|
|
|
|
chapter.bookUrl = book.bookUrl |
|
|
|
|
chapter.title = title |
|
|
|
|
chapter.url = content.href |
|
|
|
|
chapter.startFragmentId = |
|
|
|
|
if (content.href.substringAfter("#") == content.href) null |
|
|
|
|
else content.href.substringAfter("#") |
|
|
|
|
if (durIndex > 0) { |
|
|
|
|
val preIndex = durIndex - 1 |
|
|
|
|
chapterList[preIndex].endFragmentId = chapter.startFragmentId |
|
|
|
|
} |
|
|
|
|
chapterList.add(chapter) |
|
|
|
|
durIndex++ |
|
|
|
|
i++ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun parseMenu( |
|
|
|
|
chapterList: ArrayList<BookChapter>, |
|
|
|
|
refs: List<TOCReference>?, |
|
|
|
|
level: Int |
|
|
|
|
) { |
|
|
|
|
refs?.forEach { ref -> |
|
|
|
|
if (ref.resource != null) { |
|
|
|
|
val chapter = BookChapter() |
|
|
|
|
chapter.bookUrl = book.bookUrl |
|
|
|
|
chapter.title = ref.title |
|
|
|
|
chapter.url = ref.completeHref |
|
|
|
|
chapter.startFragmentId = ref.fragmentId |
|
|
|
|
if (durIndex > 0) { |
|
|
|
|
val preIndex = durIndex - 1 |
|
|
|
|
chapterList[preIndex].endFragmentId = chapter.startFragmentId |
|
|
|
|
} |
|
|
|
|
chapterList.add(chapter) |
|
|
|
|
durIndex++ |
|
|
|
|
} |
|
|
|
|
if (ref.children != null && ref.children.isNotEmpty()) { |
|
|
|
|
parseMenu(chapterList, ref.children, level + 1) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |