优化
This commit is contained in:
@@ -7,6 +7,7 @@ import com.bumptech.glide.load.Options
|
|||||||
import com.bumptech.glide.load.data.DataFetcher
|
import com.bumptech.glide.load.data.DataFetcher
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.bumptech.glide.util.ContentLengthInputStream
|
import com.bumptech.glide.util.ContentLengthInputStream
|
||||||
|
import com.script.rhino.runScriptWithContext
|
||||||
import io.legado.app.data.entities.BaseSource
|
import io.legado.app.data.entities.BaseSource
|
||||||
import io.legado.app.exception.NoStackTraceException
|
import io.legado.app.exception.NoStackTraceException
|
||||||
import io.legado.app.help.http.CookieManager.cookieJarHeader
|
import io.legado.app.help.http.CookieManager.cookieJarHeader
|
||||||
@@ -17,7 +18,6 @@ import io.legado.app.help.source.SourceHelp
|
|||||||
import io.legado.app.model.ReadManga
|
import io.legado.app.model.ReadManga
|
||||||
import io.legado.app.utils.ImageUtils
|
import io.legado.app.utils.ImageUtils
|
||||||
import io.legado.app.utils.isWifiConnect
|
import io.legado.app.utils.isWifiConnect
|
||||||
import com.script.rhino.runScriptWithContext
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import okhttp3.Call
|
import okhttp3.Call
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
@@ -89,6 +89,7 @@ class OkHttpStreamFetcher(
|
|||||||
stream?.close()
|
stream?.close()
|
||||||
}
|
}
|
||||||
responseBody?.close()
|
responseBody?.close()
|
||||||
|
coroutineContext.cancel()
|
||||||
callback = null
|
callback = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -812,7 +812,7 @@ class AnalyzeRule(
|
|||||||
if (bookSource == null || book == null) return
|
if (bookSource == null || book == null) return
|
||||||
runBlocking(coroutineContext) {
|
runBlocking(coroutineContext) {
|
||||||
withTimeout(1800000) {
|
withTimeout(1800000) {
|
||||||
WebBook.preciseSearchAwait(this, bookSource, book.name, book.author)
|
WebBook.preciseSearchAwait(bookSource, book.name, book.author)
|
||||||
.getOrThrow().let {
|
.getOrThrow().let {
|
||||||
book.bookUrl = it.bookUrl
|
book.bookUrl = it.bookUrl
|
||||||
it.variableMap.forEach { entry ->
|
it.variableMap.forEach { entry ->
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import io.legado.app.model.analyzeRule.RuleData
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.CoroutineStart
|
import kotlinx.coroutines.CoroutineStart
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.sync.Semaphore
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
import kotlinx.coroutines.sync.withPermit
|
import kotlinx.coroutines.sync.withPermit
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
@@ -363,7 +363,7 @@ object WebBook {
|
|||||||
return Coroutine.async(scope, context) {
|
return Coroutine.async(scope, context) {
|
||||||
for (s in bookSourceParts) {
|
for (s in bookSourceParts) {
|
||||||
val source = s.getBookSource() ?: continue
|
val source = s.getBookSource() ?: continue
|
||||||
val book = preciseSearchAwait(scope, source, name, author).getOrNull()
|
val book = preciseSearchAwait(source, name, author).getOrNull()
|
||||||
if (book != null) {
|
if (book != null) {
|
||||||
return@async Pair(book, source)
|
return@async Pair(book, source)
|
||||||
}
|
}
|
||||||
@@ -373,24 +373,19 @@ object WebBook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun preciseSearchAwait(
|
suspend fun preciseSearchAwait(
|
||||||
scope: CoroutineScope,
|
|
||||||
bookSource: BookSource,
|
bookSource: BookSource,
|
||||||
name: String,
|
name: String,
|
||||||
author: String,
|
author: String,
|
||||||
): Result<Book> {
|
): Result<Book> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
scope.isActive
|
coroutineContext.ensureActive()
|
||||||
searchBookAwait(
|
searchBookAwait(
|
||||||
bookSource, name,
|
bookSource, name,
|
||||||
filter = { fName, fAuthor -> fName == name && fAuthor == author },
|
filter = { fName, fAuthor -> fName == name && fAuthor == author },
|
||||||
shouldBreak = { it > 0 }
|
shouldBreak = { it > 0 }
|
||||||
).firstOrNull()?.let { searchBook ->
|
).firstOrNull()?.let { searchBook ->
|
||||||
scope.isActive
|
coroutineContext.ensureActive()
|
||||||
var book = searchBook.toBook()
|
return@runCatching searchBook.toBook()
|
||||||
if (book.tocUrl.isBlank()) {
|
|
||||||
book = getBookInfoAwait(bookSource, book)
|
|
||||||
}
|
|
||||||
return@runCatching book
|
|
||||||
}
|
}
|
||||||
throw NoStackTraceException("未搜索到 $name($author) 书籍")
|
throw NoStackTraceException("未搜索到 $name($author) 书籍")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -350,10 +350,11 @@ class BookInfoActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showCover(book: Book) {
|
private fun showCover(book: Book) {
|
||||||
binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin)
|
binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) {
|
||||||
if (!AppConfig.isEInkMode) {
|
if (!AppConfig.isEInkMode) {
|
||||||
BookCover.loadBlur(this, book.getDisplayCover())
|
BookCover.loadBlur(this, book.getDisplayCover(), false, book.origin)
|
||||||
.into(binding.bgBook)
|
.into(binding.bgBook)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,10 +87,18 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
|
|||||||
batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}")
|
batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}")
|
||||||
if (book.isLocal) return@forEachIndexed
|
if (book.isLocal) return@forEachIndexed
|
||||||
if (book.origin == source.bookSourceUrl) return@forEachIndexed
|
if (book.origin == source.bookSourceUrl) return@forEachIndexed
|
||||||
val newBook = WebBook.preciseSearchAwait(this, source, book.name, book.author)
|
val newBook = WebBook.preciseSearchAwait(source, book.name, book.author)
|
||||||
.onFailure {
|
.onFailure {
|
||||||
AppLog.put("获取书籍出错\n${it.localizedMessage}", it, true)
|
AppLog.put("搜索书籍出错\n${it.localizedMessage}", it, true)
|
||||||
}.getOrNull() ?: return@forEachIndexed
|
}.getOrNull() ?: return@forEachIndexed
|
||||||
|
kotlin.runCatching {
|
||||||
|
if (book.tocUrl.isEmpty()) {
|
||||||
|
WebBook.getBookInfoAwait(source, book)
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
AppLog.put("获取书籍详情出错\n${it.localizedMessage}", it, true)
|
||||||
|
return@forEachIndexed
|
||||||
|
}
|
||||||
WebBook.getChapterListAwait(source, newBook)
|
WebBook.getChapterListAwait(source, newBook)
|
||||||
.onFailure {
|
.onFailure {
|
||||||
AppLog.put("获取目录出错\n${it.localizedMessage}", it, true)
|
AppLog.put("获取目录出错\n${it.localizedMessage}", it, true)
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
|
|||||||
// 自动换源
|
// 自动换源
|
||||||
|
|
||||||
}.mapParallelSafe(AppConfig.threadCount) { source ->
|
}.mapParallelSafe(AppConfig.threadCount) { source ->
|
||||||
val book = WebBook.preciseSearchAwait(this, source, name, author).getOrThrow()
|
val book = WebBook.preciseSearchAwait(source, name, author).getOrThrow()
|
||||||
if (book.tocUrl.isEmpty()) {
|
if (book.tocUrl.isEmpty()) {
|
||||||
WebBook.getBookInfoAwait(source, book)
|
WebBook.getBookInfoAwait(source, book)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
|
|||||||
}.onStart {
|
}.onStart {
|
||||||
ReadBook.upMsg(context.getString(R.string.source_auto_changing))
|
ReadBook.upMsg(context.getString(R.string.source_auto_changing))
|
||||||
}.mapParallelSafe(AppConfig.threadCount) { source ->
|
}.mapParallelSafe(AppConfig.threadCount) { source ->
|
||||||
val book = WebBook.preciseSearchAwait(this, source, name, author).getOrThrow()
|
val book = WebBook.preciseSearchAwait(source, name, author).getOrThrow()
|
||||||
if (book.tocUrl.isEmpty()) {
|
if (book.tocUrl.isEmpty()) {
|
||||||
WebBook.getBookInfoAwait(source, book)
|
WebBook.getBookInfoAwait(source, book)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,8 @@ class CoverImageView @JvmOverloads constructor(
|
|||||||
loadOnlyWifi: Boolean = false,
|
loadOnlyWifi: Boolean = false,
|
||||||
sourceOrigin: String? = null,
|
sourceOrigin: String? = null,
|
||||||
fragment: Fragment? = null,
|
fragment: Fragment? = null,
|
||||||
lifecycle: Lifecycle? = null
|
lifecycle: Lifecycle? = null,
|
||||||
|
onLoadFinish: (() -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
this.bitmapPath = path
|
this.bitmapPath = path
|
||||||
this.name = name?.replace(AppPattern.bdRegex, "")?.trim()
|
this.name = name?.replace(AppPattern.bdRegex, "")?.trim()
|
||||||
@@ -210,15 +211,39 @@ class CoverImageView @JvmOverloads constructor(
|
|||||||
if (sourceOrigin != null) {
|
if (sourceOrigin != null) {
|
||||||
options = options.set(OkHttpModelLoader.sourceOriginOption, sourceOrigin)
|
options = options.set(OkHttpModelLoader.sourceOriginOption, sourceOrigin)
|
||||||
}
|
}
|
||||||
val builder = if (fragment != null && lifecycle != null) {
|
var builder = if (fragment != null && lifecycle != null) {
|
||||||
ImageLoader.load(fragment, lifecycle, path)
|
ImageLoader.load(fragment, lifecycle, path)
|
||||||
} else {
|
} else {
|
||||||
ImageLoader.load(context, path)//Glide自动识别http://,content://和file://
|
ImageLoader.load(context, path)//Glide自动识别http://,content://和file://
|
||||||
}
|
}
|
||||||
builder.apply(options)
|
builder = builder.apply(options)
|
||||||
.placeholder(BookCover.defaultDrawable)
|
.placeholder(BookCover.defaultDrawable)
|
||||||
.error(BookCover.defaultDrawable)
|
.error(BookCover.defaultDrawable)
|
||||||
.listener(glideListener)
|
.listener(glideListener)
|
||||||
|
if (onLoadFinish != null) {
|
||||||
|
builder = builder.addListener(object : RequestListener<Drawable> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Drawable?>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Drawable,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Drawable?>?,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
onLoadFinish.invoke()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
builder
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.into(this)
|
.into(this)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user