优化
Some checks are pending
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions

This commit is contained in:
Horis
2025-03-25 12:20:50 +08:00
parent 7f381174cf
commit 64d7d3f300
10 changed files with 66 additions and 56 deletions

View File

@@ -365,7 +365,7 @@ data class Book(
}
fun save() {
if (appDb.bookDao.has(bookUrl) == true) {
if (appDb.bookDao.has(bookUrl)) {
appDb.bookDao.update(this)
} else {
appDb.bookDao.insert(this)

View File

@@ -244,6 +244,7 @@ fun Book.sync(oldBook: Book) {
}
}
canUpdate = curBook.canUpdate
readConfig = curBook.readConfig
}
fun Book.update() {

View File

@@ -815,7 +815,7 @@ class AnalyzeRule(
if (bookSource == null || book == null) return
runBlocking(coroutineContext) {
withTimeout(1800000) {
WebBook.getBookInfoAwait(bookSource, book)
WebBook.getBookInfoAwait(bookSource, book, false)
}
}
}
@@ -829,7 +829,7 @@ class AnalyzeRule(
if (bookSource == null || book == null) return
runBlocking(coroutineContext) {
withTimeout(1800000) {
WebBook.getBookInfoAwait(bookSource, book)
WebBook.getBookInfoAwait(bookSource, book, false)
}
}
}

View File

@@ -32,7 +32,9 @@ object BookList {
baseUrl: String,
body: String?,
isSearch: Boolean = true,
isRedirect: Boolean = false
isRedirect: Boolean = false,
filter: ((name: String, author: String) -> Boolean)? = null,
shouldBreak: ((size: Int) -> Boolean)? = null
): ArrayList<SearchBook> {
body ?: throw NoStackTraceException(
appCtx.getString(
@@ -107,6 +109,7 @@ object BookList {
getSearchItem(
bookSource, analyzeRule, item, baseUrl, ruleData.getVariable(),
index == 0,
filter,
ruleName = ruleName,
ruleBookUrl = ruleBookUrl,
ruleAuthor = ruleAuthor,
@@ -121,6 +124,9 @@ object BookList {
}
bookList.add(searchBook)
}
if (shouldBreak?.invoke(bookList.size) == true) {
break
}
}
val lh = LinkedHashSet(bookList)
bookList.clear()
@@ -177,6 +183,7 @@ object BookList {
baseUrl: String,
variable: String?,
log: Boolean,
filter: ((name: String, author: String) -> Boolean)? = null,
ruleName: List<AnalyzeRule.SourceRule>,
ruleBookUrl: List<AnalyzeRule.SourceRule>,
ruleAuthor: List<AnalyzeRule.SourceRule>,
@@ -202,6 +209,9 @@ object BookList {
Debug.log(bookSource.bookSourceUrl, "┌获取作者", log)
searchBook.author = BookHelp.formatBookAuthor(analyzeRule.getString(ruleAuthor))
Debug.log(bookSource.bookSourceUrl, "${searchBook.author}", log)
if (filter?.invoke(searchBook.name, searchBook.author) == false) {
return null
}
coroutineContext.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取分类", log)
try {

View File

@@ -85,7 +85,12 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
callBack.onSearchStart()
}.mapParallelSafe(threadCount) {
withTimeout(30000L) {
WebBook.searchBookAwait(it, searchKey, searchPage)
WebBook.searchBookAwait(
it, searchKey, searchPage,
filter = { name, author ->
!precision || name.contains(searchKey) ||
author.contains(searchKey)
})
}
}.onEach { items ->
for (book in items) {

View File

@@ -49,6 +49,8 @@ object WebBook {
bookSource: BookSource,
key: String,
page: Int? = 1,
filter: ((name: String, author: String) -> Boolean)? = null,
shouldBreak: ((size: Int) -> Boolean)? = null
): ArrayList<SearchBook> {
val searchUrl = bookSource.searchUrl
if (searchUrl.isNullOrBlank()) {
@@ -80,7 +82,9 @@ object WebBook {
baseUrl = res.url,
body = res.body,
isSearch = true,
isRedirect = res.raw.priorResponse?.isRedirect == true
isRedirect = res.raw.priorResponse?.isRedirect == true,
filter = filter,
shouldBreak = shouldBreak
)
}
@@ -207,21 +211,16 @@ object WebBook {
}
}
suspend fun runPreUpdateJs(bookSource: BookSource, book: Book): Result<Boolean> {
suspend fun runPreUpdateJs(bookSource: BookSource, book: Book): Result<Unit> {
return kotlin.runCatching {
val preUpdateJs = bookSource.ruleToc?.preUpdateJs
if (!preUpdateJs.isNullOrBlank()) {
kotlin.runCatching {
AnalyzeRule(book, bookSource)
.setCoroutineContext(coroutineContext)
.evalJS(preUpdateJs)
}.onFailure {
AppLog.put("执行preUpdateJs规则失败 书源:${bookSource.bookSourceName}", it)
throw it
}
return@runCatching true
AnalyzeRule(book, bookSource)
.setCoroutineContext(coroutineContext)
.evalJS(preUpdateJs)
}
return@runCatching false
}.onFailure {
AppLog.put("执行preUpdateJs规则失败 书源:${bookSource.bookSourceName}", it)
}
}
@@ -386,9 +385,11 @@ object WebBook {
): Result<Book> {
return kotlin.runCatching {
scope.isActive
searchBookAwait(bookSource, name).firstOrNull {
it.name == name && it.author == author
}?.let { searchBook ->
searchBookAwait(
bookSource, name,
filter = { fName, fAuthor -> fName == name && fAuthor == author },
shouldBreak = { it > 0 }
).firstOrNull()?.let { searchBook ->
scope.isActive
var book = searchBook.toBook()
if (book.tocUrl.isBlank()) {

View File

@@ -137,7 +137,9 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
if (source.getSearchRule().coverUrl.isNullOrBlank()) {
return
}
val searchBook = WebBook.searchBookAwait(source, name).firstOrNull() ?: return
val searchBook = WebBook.searchBookAwait(
source, name,
shouldBreak = { it > 0 }).firstOrNull() ?: return
if (searchBook.name == name && searchBook.author == author
&& !searchBook.coverUrl.isNullOrEmpty()
) {

View File

@@ -237,18 +237,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
private suspend fun search(source: BookSource) {
val resultBooks = WebBook.searchBookAwait(source, name)
resultBooks.filter { searchBook ->
if (searchBook.name != name) {
return@filter false
}
if (AppConfig.changeSourceCheckAuthor && !searchBook.author.contains(author)) {
return@filter false
}
true
}.forEach { searchBook ->
val checkAuthor = AppConfig.changeSourceCheckAuthor
val loadInfo = AppConfig.changeSourceLoadInfo
val loadToc = AppConfig.changeSourceLoadToc
val loadWordCount = AppConfig.changeSourceLoadWordCount
val resultBooks = WebBook.searchBookAwait(
source, name,
filter = { fName, fAuthor ->
fName == name && (!checkAuthor || fAuthor.contains(author))
})
resultBooks.forEach { searchBook ->
when {
AppConfig.changeSourceLoadInfo || AppConfig.changeSourceLoadToc || AppConfig.changeSourceLoadWordCount -> {
loadInfo || loadToc || loadWordCount -> {
loadBookInfo(source, searchBook.toBook())
}

View File

@@ -98,7 +98,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
bookSource = if (book.isLocal) null else
appDb.bookSourceDao.getBookSource(book.origin)
if (book.tocUrl.isEmpty() && !book.isLocal) {
loadBookInfo(book)
loadBookInfo(book, runPreUpdateJs = inBookshelf)
} else {
val chapterList = appDb.bookChapterDao.getChapterList(book.bookUrl)
if (chapterList.isNotEmpty()) {
@@ -166,12 +166,13 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
fun loadBookInfo(
book: Book,
canReName: Boolean = true,
runPreUpdateJs: Boolean = true,
scope: CoroutineScope = viewModelScope
) {
if (book.isLocal) {
LocalBook.upBookInfo(book)
bookData.postValue(book)
loadChapter(book, scope)
loadChapter(book)
} else {
val bookSource = bookSource ?: let {
chapterListData.postValue(emptyList())
@@ -192,22 +193,12 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
bookData.postValue(it)
if (inBookshelf) {
if (!appDb.bookDao.has(it.bookUrl)) {
/**
* 来自搜索,同一本书,不同 bookUrl
*/
appDb.bookDao.insert(it)
} else {
appDb.bookDao.update(it)
}
if (dbBook != null && (dbBook.name != book.name || dbBook.bookUrl != book.bookUrl)) {
BookHelp.updateCacheFolder(dbBook, book)
}
it.save()
}
if (it.isWebFile) {
loadWebFile(it, scope)
loadWebFile(it)
} else {
loadChapter(it, scope)
loadChapter(it, runPreUpdateJs)
}
}.onError {
AppLog.put("获取书籍信息失败\n${it.localizedMessage}", it)
@@ -218,6 +209,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
private fun loadChapter(
book: Book,
runPreUpdateJs: Boolean = true,
scope: CoroutineScope = viewModelScope
) {
if (book.isLocal) {
@@ -240,16 +232,14 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
return
}
val oldBook = book.copy()
WebBook.getChapterList(scope, bookSource, book, true)
WebBook.getChapterList(scope, bookSource, book, runPreUpdateJs)
.onSuccess(IO) {
/**
* runPreUpdateJs 有可能会修改 book 的书名作者和 bookUrl
*/
if (inBookshelf) {
if (oldBook.bookUrl == book.bookUrl) {
appDb.bookDao.update(book)
} else {
appDb.bookDao.insert(book)
book.save()
/**
* runPreUpdateJs 有可能会修改 book 的 bookUrl
*/
if (oldBook.bookUrl != book.bookUrl) {
BookHelp.updateCacheFolder(oldBook, book)
}
appDb.bookChapterDao.delByBook(oldBook.bookUrl)

View File

@@ -152,9 +152,10 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
}
kotlin.runCatching {
val oldBook = book.copy()
WebBook.runPreUpdateJs(source, book)
if (book.tocUrl.isBlank()) {
WebBook.getBookInfoAwait(source, book)
} else {
WebBook.runPreUpdateJs(source, book)
}
val toc = WebBook.getChapterListAwait(source, book).getOrThrow()
book.sync(oldBook)