|
|
@ -7,6 +7,7 @@ import io.legado.app.data.entities.SearchBook |
|
|
|
import io.legado.app.help.coroutine.Coroutine |
|
|
|
import io.legado.app.help.coroutine.Coroutine |
|
|
|
import io.legado.app.help.http.StrResponse |
|
|
|
import io.legado.app.help.http.StrResponse |
|
|
|
import io.legado.app.model.Debug |
|
|
|
import io.legado.app.model.Debug |
|
|
|
|
|
|
|
import io.legado.app.model.NoStackTraceException |
|
|
|
import io.legado.app.model.analyzeRule.AnalyzeUrl |
|
|
|
import io.legado.app.model.analyzeRule.AnalyzeUrl |
|
|
|
import kotlinx.coroutines.CoroutineScope |
|
|
|
import kotlinx.coroutines.CoroutineScope |
|
|
|
import kotlinx.coroutines.Dispatchers |
|
|
|
import kotlinx.coroutines.Dispatchers |
|
|
@ -15,32 +16,6 @@ import kotlin.coroutines.CoroutineContext |
|
|
|
|
|
|
|
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate") |
|
|
|
@Suppress("MemberVisibilityCanBePrivate") |
|
|
|
object WebBook { |
|
|
|
object WebBook { |
|
|
|
/** |
|
|
|
|
|
|
|
* 精准搜索 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
suspend fun preciseSearch( |
|
|
|
|
|
|
|
scope: CoroutineScope, |
|
|
|
|
|
|
|
bookSources: List<BookSource>, |
|
|
|
|
|
|
|
name: String, |
|
|
|
|
|
|
|
author: String |
|
|
|
|
|
|
|
): Pair<BookSource, Book>? { |
|
|
|
|
|
|
|
bookSources.forEach { source -> |
|
|
|
|
|
|
|
kotlin.runCatching { |
|
|
|
|
|
|
|
if (!scope.isActive) return null |
|
|
|
|
|
|
|
searchBookAwait(scope, source, name).firstOrNull { |
|
|
|
|
|
|
|
it.name == name && it.author == author |
|
|
|
|
|
|
|
}?.let { searchBook -> |
|
|
|
|
|
|
|
if (!scope.isActive) return null |
|
|
|
|
|
|
|
var book = searchBook.toBook() |
|
|
|
|
|
|
|
if (book.tocUrl.isBlank()) { |
|
|
|
|
|
|
|
book = getBookInfoAwait(scope, source, book) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return Pair(source, book) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 搜索 |
|
|
|
* 搜索 |
|
|
@ -326,4 +301,45 @@ object WebBook { |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 精准搜索 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
fun preciseSearch( |
|
|
|
|
|
|
|
scope: CoroutineScope, |
|
|
|
|
|
|
|
bookSources: List<BookSource>, |
|
|
|
|
|
|
|
name: String, |
|
|
|
|
|
|
|
author: String, |
|
|
|
|
|
|
|
context: CoroutineContext = Dispatchers.IO, |
|
|
|
|
|
|
|
): Coroutine<Pair<BookSource, Book>> { |
|
|
|
|
|
|
|
return Coroutine.async(scope, context) { |
|
|
|
|
|
|
|
preciseSearchAwait(scope, bookSources, name, author) |
|
|
|
|
|
|
|
?: throw NoStackTraceException("没有搜索到<$name>$author") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
suspend fun preciseSearchAwait( |
|
|
|
|
|
|
|
scope: CoroutineScope, |
|
|
|
|
|
|
|
bookSources: List<BookSource>, |
|
|
|
|
|
|
|
name: String, |
|
|
|
|
|
|
|
author: String |
|
|
|
|
|
|
|
): Pair<BookSource, Book>? { |
|
|
|
|
|
|
|
bookSources.forEach { source -> |
|
|
|
|
|
|
|
kotlin.runCatching { |
|
|
|
|
|
|
|
if (!scope.isActive) return null |
|
|
|
|
|
|
|
searchBookAwait(scope, source, name).firstOrNull { |
|
|
|
|
|
|
|
it.name == name && it.author == author |
|
|
|
|
|
|
|
}?.let { searchBook -> |
|
|
|
|
|
|
|
if (!scope.isActive) return null |
|
|
|
|
|
|
|
var book = searchBook.toBook() |
|
|
|
|
|
|
|
if (book.tocUrl.isBlank()) { |
|
|
|
|
|
|
|
book = getBookInfoAwait(scope, source, book) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return Pair(source, book) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |