mirror of
https://github.com/gedoor/legado.git
synced 2025-01-07 03:06:58 +08:00
优化
This commit is contained in:
parent
67d0462581
commit
20ab778ec0
@ -109,14 +109,11 @@ object LocalBook {
|
||||
throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty))
|
||||
}
|
||||
val list = ArrayList(LinkedHashSet(chapters))
|
||||
var wordCount = 0
|
||||
list.forEachIndexed { index, bookChapter ->
|
||||
bookChapter.index = index
|
||||
wordCount += bookChapter.tag?.toInt() ?: 0
|
||||
}
|
||||
book.latestChapterTitle = list.last().title
|
||||
book.totalChapterNum = list.size
|
||||
book.wordCount = wordCount.toString() + "字"
|
||||
book.save()
|
||||
return list
|
||||
}
|
||||
|
@ -90,7 +90,8 @@ class TextFile(private var book: Book) {
|
||||
}
|
||||
}
|
||||
}
|
||||
val toc = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
|
||||
val (toc, wordCount) = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
|
||||
book.wordCount = StringUtils.wordCountFormat(wordCount)
|
||||
toc.forEachIndexed { index, bookChapter ->
|
||||
bookChapter.index = index
|
||||
bookChapter.bookUrl = book.bookUrl
|
||||
@ -140,18 +141,19 @@ class TextFile(private var book: Book) {
|
||||
/**
|
||||
* 按规则解析目录
|
||||
*/
|
||||
private fun analyze(pattern: Pattern?): ArrayList<BookChapter> {
|
||||
private fun analyze(pattern: Pattern?): Pair<ArrayList<BookChapter>, Int> {
|
||||
if (pattern?.pattern().isNullOrEmpty()) {
|
||||
return analyze()
|
||||
}
|
||||
pattern ?: return analyze()
|
||||
val toc = arrayListOf<BookChapter>()
|
||||
var bookWordCount = 0
|
||||
LocalBook.getBookInputStream(book).use { bis ->
|
||||
var blockContent: String
|
||||
//加载章节
|
||||
var curOffset: Long = 0
|
||||
//读取的长度
|
||||
var length: Int
|
||||
var lastChapterWordCount = 0
|
||||
val buffer = ByteArray(bufferSize)
|
||||
var bufferStart = 3
|
||||
bis.read(buffer, 0, 3)
|
||||
@ -192,11 +194,12 @@ class TextFile(private var book: Book) {
|
||||
if (book.getSplitLongChapter() && curOffset + chapterLength - lastStart > maxLengthWithToc) {
|
||||
toc.lastOrNull()?.let {
|
||||
it.end = it.start
|
||||
it.tag = null
|
||||
}
|
||||
//章节字数太多进行拆分
|
||||
val lastTitle = toc.lastOrNull()?.title
|
||||
val lastTitleLength = lastTitle?.toByteArray(charset)?.size ?: 0
|
||||
val chapters = analyze(
|
||||
val (chapters, wordCount) = analyze(
|
||||
lastStart + lastTitleLength, curOffset + chapterLength
|
||||
)
|
||||
lastTitle?.let {
|
||||
@ -205,6 +208,7 @@ class TextFile(private var book: Book) {
|
||||
}
|
||||
}
|
||||
toc.addAll(chapters)
|
||||
bookWordCount += wordCount
|
||||
//创建当前章节
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
@ -222,7 +226,7 @@ class TextFile(private var book: Book) {
|
||||
qyChapter.title = "前言"
|
||||
qyChapter.start = curOffset
|
||||
qyChapter.end = curOffset + chapterLength
|
||||
qyChapter.tag = chapterContent.length.toString()
|
||||
qyChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
|
||||
toc.add(qyChapter)
|
||||
book.intro = if (chapterContent.length <= 500) {
|
||||
chapterContent
|
||||
@ -242,13 +246,16 @@ class TextFile(private var book: Book) {
|
||||
chapterContent.substringAfter(lastChapter.title).isBlank()
|
||||
//将当前段落添加上一章去
|
||||
lastChapter.end = lastChapter.end!! + chapterLength
|
||||
lastChapter.tag = ((lastChapter.tag?.toInt() ?: 0) + chapterContent.length).toString()
|
||||
lastChapterWordCount += chapterContent.length
|
||||
lastChapter.tag = StringUtils.wordCountFormat(lastChapterWordCount)
|
||||
//创建当前章节
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = lastChapter.end
|
||||
toc.add(curChapter)
|
||||
}
|
||||
bookWordCount += chapterContent.length
|
||||
lastChapterWordCount = 0
|
||||
} else {
|
||||
if (toc.isNotEmpty()) { //获取章节内容
|
||||
//获取上一章节
|
||||
@ -257,7 +264,7 @@ class TextFile(private var book: Book) {
|
||||
chapterContent.substringAfter(lastChapter.title).isBlank()
|
||||
lastChapter.end =
|
||||
lastChapter.start!! + chapterLength
|
||||
lastChapter.tag = chapterContent.length.toString()
|
||||
lastChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
|
||||
//创建当前章节
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
@ -268,19 +275,24 @@ class TextFile(private var book: Book) {
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = curOffset
|
||||
curChapter.end = curOffset
|
||||
curChapter.tag = chapterContent.length.toString()
|
||||
curChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
|
||||
toc.add(curChapter)
|
||||
}
|
||||
bookWordCount += chapterContent.length
|
||||
lastChapterWordCount = 0
|
||||
}
|
||||
//设置指针偏移
|
||||
seekPos += chapterContent.length
|
||||
}
|
||||
val wordCount = blockContent.length - seekPos
|
||||
bookWordCount += wordCount
|
||||
lastChapterWordCount += wordCount
|
||||
//block的偏移点
|
||||
curOffset += length.toLong()
|
||||
//设置上一章的结尾
|
||||
toc.lastOrNull()?.let {
|
||||
it.end = curOffset
|
||||
it.tag = blockContent.substring(seekPos).length.toString()
|
||||
it.tag = StringUtils.wordCountFormat(lastChapterWordCount)
|
||||
}
|
||||
}
|
||||
toc.lastOrNull()?.let { chapter ->
|
||||
@ -288,9 +300,10 @@ class TextFile(private var book: Book) {
|
||||
if (book.getSplitLongChapter() && chapter.end!! - chapter.start!! > maxLengthWithToc) {
|
||||
val end = chapter.end!!
|
||||
chapter.end = chapter.start
|
||||
chapter.tag = null
|
||||
val lastTitle = chapter.title
|
||||
val lastTitleLength = lastTitle.toByteArray(charset).size
|
||||
val chapters = analyze(
|
||||
val (chapters, _) = analyze(
|
||||
chapter.start!! + lastTitleLength, end
|
||||
)
|
||||
chapters.forEachIndexed { index, bookChapter ->
|
||||
@ -302,7 +315,7 @@ class TextFile(private var book: Book) {
|
||||
}
|
||||
System.gc()
|
||||
System.runFinalization()
|
||||
return toc
|
||||
return toc to bookWordCount
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,8 +323,9 @@ class TextFile(private var book: Book) {
|
||||
*/
|
||||
private fun analyze(
|
||||
fileStart: Long = 0L, fileEnd: Long = Long.MAX_VALUE
|
||||
): ArrayList<BookChapter> {
|
||||
): Pair<ArrayList<BookChapter>, Int> {
|
||||
val toc = arrayListOf<BookChapter>()
|
||||
var bookWordCount = 0
|
||||
LocalBook.getBookInputStream(book).use { bis ->
|
||||
//block的个数
|
||||
var blockPos = 0
|
||||
@ -320,6 +334,7 @@ class TextFile(private var book: Book) {
|
||||
var chapterPos = 0
|
||||
//读取的长度
|
||||
var length = 0
|
||||
var lastChapterWordCount = 0
|
||||
val buffer = ByteArray(bufferSize)
|
||||
var bufferStart = 3
|
||||
if (fileStart == 0L) {
|
||||
@ -360,10 +375,14 @@ class TextFile(private var book: Book) {
|
||||
break
|
||||
}
|
||||
}
|
||||
val content = String(buffer, chapterOffset, end - chapterOffset, charset)
|
||||
bookWordCount += content.length
|
||||
lastChapterWordCount = content.length
|
||||
val chapter = BookChapter()
|
||||
chapter.title = "第${blockPos}章($chapterPos)"
|
||||
chapter.start = toc.lastOrNull()?.end ?: curOffset
|
||||
chapter.end = chapter.start!! + end - chapterOffset
|
||||
chapter.tag = StringUtils.wordCountFormat(content.length)
|
||||
toc.add(chapter)
|
||||
//减去已经被分配的长度
|
||||
strLength -= (end - chapterOffset)
|
||||
@ -380,19 +399,24 @@ class TextFile(private var book: Book) {
|
||||
curOffset += length.toLong()
|
||||
}
|
||||
//设置结尾章节
|
||||
val content = String(buffer, 0, bufferStart, charset)
|
||||
bookWordCount += content.length
|
||||
if (bufferStart > 100 || toc.isEmpty()) {
|
||||
val chapter = BookChapter()
|
||||
chapter.title = "第${blockPos}章(${chapterPos})"
|
||||
chapter.start = toc.lastOrNull()?.end ?: curOffset
|
||||
chapter.end = chapter.start!! + bufferStart
|
||||
chapter.tag = StringUtils.wordCountFormat(content.length)
|
||||
toc.add(chapter)
|
||||
} else {
|
||||
val wordCount = lastChapterWordCount + content.length
|
||||
toc.lastOrNull()?.let {
|
||||
it.end = it.end!! + bufferStart
|
||||
it.tag = StringUtils.wordCountFormat(wordCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
return toc
|
||||
return toc to bookWordCount
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,8 @@ import java.io.ByteArrayOutputStream
|
||||
import java.io.IOException
|
||||
import java.text.DecimalFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
import java.util.zip.GZIPInputStream
|
||||
@ -22,6 +23,9 @@ object StringUtils {
|
||||
private const val DAY_OF_YESTERDAY = 2
|
||||
private const val TIME_UNIT = 60
|
||||
private val ChnMap = chnMap
|
||||
private val wordCountFormatter by lazy {
|
||||
DecimalFormat("#.#")
|
||||
}
|
||||
|
||||
private val chnMap: HashMap<Char, Int>
|
||||
get() {
|
||||
@ -232,16 +236,30 @@ object StringUtils {
|
||||
return isNum.matches()
|
||||
}
|
||||
|
||||
fun wordCountFormat(words: Int): String {
|
||||
var wordsS = ""
|
||||
if (words > 0) {
|
||||
if (words > 10000) {
|
||||
val df = wordCountFormatter
|
||||
wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
|
||||
} else {
|
||||
wordsS = words.toString() + "字"
|
||||
}
|
||||
}
|
||||
return wordsS
|
||||
}
|
||||
|
||||
fun wordCountFormat(wc: String?): String {
|
||||
if (wc == null) return ""
|
||||
var wordsS = ""
|
||||
if (isNumeric(wc)) {
|
||||
val words: Int = wc.toInt()
|
||||
if (words > 0) {
|
||||
wordsS = words.toString() + "字"
|
||||
if (words > 10000) {
|
||||
val df = DecimalFormat("#.#")
|
||||
val df = wordCountFormatter
|
||||
wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
|
||||
} else {
|
||||
wordsS = words.toString() + "字"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user