mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化
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
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:
@@ -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)
|
||||
|
||||
@@ -244,6 +244,7 @@ fun Book.sync(oldBook: Book) {
|
||||
}
|
||||
}
|
||||
canUpdate = curBook.canUpdate
|
||||
readConfig = curBook.readConfig
|
||||
}
|
||||
|
||||
fun Book.update() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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()
|
||||
) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user