Compare commits

...

3 Commits

Author SHA1 Message Date
严尚君
0b5d575405
Merge 9d52d3402d into aebdd9f946 2024-01-11 00:27:06 -08:00
Horis
aebdd9f946 优化 2024-01-11 10:22:35 +08:00
okou19900722
9d52d3402d
书源管理界面添加筛选方式--是否开启发现。 resolved #3454 2023-10-31 11:32:32 +08:00
21 changed files with 122 additions and 20 deletions

View File

@ -111,6 +111,20 @@ interface BookSourceDao {
)
fun flowNoGroup(): Flow<List<BookSourcePart>>
@Query(
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
trim(loginUrl) <> '' hasLoginUrl, lastUpdateTime, respondTime, weight, trim(exploreUrl) <> '' hasExploreUrl
from book_sources where enabledExplore = 1 order by customOrder asc"""
)
fun flowEnabledExplore(): Flow<List<BookSourcePart>>
@Query(
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
trim(loginUrl) <> '' hasLoginUrl, lastUpdateTime, respondTime, weight, trim(exploreUrl) <> '' hasExploreUrl
from book_sources where enabledExplore = 0 order by customOrder asc"""
)
fun flowDisabledExplore(): Flow<List<BookSourcePart>>
@Query(
"""select * from book_sources
where enabledExplore = 1
@ -193,6 +207,12 @@ interface BookSourceDao {
@get:Query("select * from book_sources where bookSourceGroup is null or bookSourceGroup = '' or bookSourceGroup like '%未分组%'")
val allNoGroup: List<BookSource>
@get:Query("select * from book_sources where enabledExplore = 1 order by customOrder")
val allEnabledExplore: List<BookSource>
@get:Query("select * from book_sources where enabledExplore = 0 order by customOrder")
val allDisabledExplore: List<BookSource>
@get:Query("select * from book_sources where loginUrl is not null and loginUrl != ''")
val allLogin: List<BookSource>

View File

@ -133,7 +133,10 @@ object ExoPlayerHelper {
* Okhttp DataSource.Factory
*/
private val okhttpDataFactory by lazy {
OkHttpDataSource.Factory(okHttpClient)
val client = okHttpClient.newBuilder()
.callTimeout(0, TimeUnit.SECONDS)
.build()
OkHttpDataSource.Factory(client)
.setCacheControl(CacheControl.Builder().maxAge(1, TimeUnit.DAYS).build())
}

View File

@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicBoolean
abstract class AbsCallBack(
var originalRequest: Request,
val mCall: Call,
var readTimeoutMillis: Int,
private val eventListener: EventListener? = null,
private val responseCallback: Callback? = null
) : UrlRequest.Callback() {
@ -52,6 +53,9 @@ abstract class AbsCallBack(
private var redirectRequest: Request? = null
init {
if (readTimeoutMillis == 0) {
readTimeoutMillis = Int.MAX_VALUE
}
if (originalRequest.header(cookieJarHeader) != null) {
enableCookieJar = true
originalRequest = originalRequest.newBuilder()
@ -411,7 +415,7 @@ abstract class AbsCallBack(
private var buffer = ByteBuffer.allocateDirect(32 * 1024)
private var closed = false
private val timeout = mCall.timeout().timeoutNanos()
private val timeout = readTimeoutMillis.toLong()
override fun close() {
cancelJob?.cancel()
@ -443,7 +447,7 @@ abstract class AbsCallBack(
request?.read(buffer)
val result = callbackResults.poll(timeout, TimeUnit.NANOSECONDS)
val result = callbackResults.poll(timeout, TimeUnit.MILLISECONDS)
if (result == null) {
request?.cancel()
throw IOException("Body Read Timeout")

View File

@ -5,7 +5,12 @@ import io.legado.app.utils.printOnDebug
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
import okhttp3.*
import okhttp3.Call
import okhttp3.CookieJar
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import okhttp3.internal.http.receiveHeaders
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
@ -43,12 +48,12 @@ class CronetCoroutineInterceptor(private val cookieJar: CookieJar) : Interceptor
runBlocking() {
if (timeout > 0) {
withTimeout(timeout) {
proceedWithCronet(newReq, chain.call()).also { response ->
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis()).also { response ->
cookieJar.receiveHeaders(newReq.url, response.headers)
}
}
} else {
proceedWithCronet(newReq, chain.call()).also { response ->
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis()).also { response ->
cookieJar.receiveHeaders(newReq.url, response.headers)
}
}
@ -68,10 +73,14 @@ class CronetCoroutineInterceptor(private val cookieJar: CookieJar) : Interceptor
}
private suspend fun proceedWithCronet(request: Request, call: Call): Response =
private suspend fun proceedWithCronet(
request: Request,
call: Call,
readTimeoutMillis: Int
): Response =
suspendCancellableCoroutine<Response> { coroutine ->
val callBack = object : AbsCallBack(originalRequest = request, mCall = call) {
val callBack = object : AbsCallBack(request, call, readTimeoutMillis) {
override fun waitForDone(urlRequest: UrlRequest): Response {
TODO("Not yet implemented")
}

View File

@ -27,7 +27,7 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
builder.removeHeader("Accept-Encoding")
val newReq = builder.build()
proceedWithCronet(newReq, chain.call())/*?.let { response ->
proceedWithCronet(newReq, chain.call(), chain.readTimeoutMillis())/*?.let { response ->
//从Response 中保存Cookie到CookieJar
//cookieJar.receiveHeaders(newReq.url, response.headers)
response
@ -45,11 +45,11 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
}
@SuppressLint("ObsoleteSdkInt")
private fun proceedWithCronet(request: Request, call: Call): Response? {
private fun proceedWithCronet(request: Request, call: Call, readTimeoutMillis: Int): Response? {
val callBack = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
NewCallBack(request, call)
NewCallBack(request, call, readTimeoutMillis)
} else {
OldCallback(request, call)
OldCallback(request, call, readTimeoutMillis)
}
buildRequest(request, callBack)?.runCatching {
return callBack.waitForDone(this)

View File

@ -15,7 +15,8 @@ import java.util.concurrent.TimeUnit
@SuppressLint("ObsoleteSdkInt")
@Keep
@RequiresApi(api = Build.VERSION_CODES.N)
class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
class NewCallBack(originalRequest: Request, mCall: Call, readTimeoutMillis: Int) :
AbsCallBack(originalRequest, mCall, readTimeoutMillis) {
private val responseFuture = CompletableFuture<Response>()

View File

@ -9,7 +9,8 @@ import org.chromium.net.UrlRequest
import java.io.IOException
@Keep
class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
class OldCallback(originalRequest: Request, mCall: Call, readTimeoutMillis: Int) :
AbsCallBack(originalRequest, mCall, readTimeoutMillis) {
private val mResponseCondition = ConditionVariable()
private var mException: IOException? = null

View File

@ -30,6 +30,7 @@ import java.net.URLEncoder
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.concurrent.TimeUnit
@Suppress("unused", "MemberVisibilityCanBePrivate")
open class WebDav(
@ -97,6 +98,7 @@ open class WebDav(
chain.proceed(request)
}
okHttpClient.newBuilder().run {
callTimeout(0, TimeUnit.SECONDS)
interceptors().add(0, authInterceptor)
addNetworkInterceptor(authInterceptor)
build()

View File

@ -27,12 +27,15 @@ import io.legado.app.utils.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.net.URLEncoder
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import kotlin.math.max
/**
* Created by GKF on 2018/1/24.
@ -51,6 +54,7 @@ class AnalyzeUrl(
private val source: BaseSource? = null,
private val ruleData: RuleDataInterface? = null,
private val chapter: BookChapter? = null,
private val readTimeout: Long? = null,
headerMapF: Map<String, String>? = null,
) : JsExtensions {
companion object {
@ -404,7 +408,7 @@ class AnalyzeUrl(
if (this.useWebView && useWebView) {
strResponse = when (method) {
RequestMethod.POST -> {
val res = getProxyClient(proxy).newCallStrResponse(retry) {
val res = getClient().newCallStrResponse(retry) {
addHeaders(headerMap)
url(urlNoQuery)
if (fieldMap.isNotEmpty() || body.isNullOrBlank()) {
@ -432,7 +436,7 @@ class AnalyzeUrl(
).getStrResponse()
}
} else {
strResponse = getProxyClient(proxy).newCallStrResponse(retry) {
strResponse = getClient().newCallStrResponse(retry) {
addHeaders(headerMap)
when (method) {
RequestMethod.POST -> {
@ -484,7 +488,7 @@ class AnalyzeUrl(
val concurrentRecord = getConcurrentRecord()
try {
setCookie()
val response = getProxyClient(proxy).newCallResponse(retry) {
val response = getClient().newCallResponse(retry) {
addHeaders(headerMap)
when (method) {
RequestMethod.POST -> {
@ -511,15 +515,24 @@ class AnalyzeUrl(
}
}
private fun getClient(): OkHttpClient {
val client = getProxyClient(proxy)
if (readTimeout == null) {
return client
}
return client.newBuilder()
.readTimeout(readTimeout, TimeUnit.MILLISECONDS)
.callTimeout(max(60 * 1000L, readTimeout * 2), TimeUnit.MILLISECONDS)
.build()
}
fun getResponse(): Response {
return runBlocking {
getResponseAwait()
}
}
@Suppress("UnnecessaryVariable")
private fun getByteArrayIfDataUri(): ByteArray? {
@Suppress("RegExpRedundantEscape")
val dataUriFindResult = dataUriRegex.find(urlNoQuery)
if (dataUriFindResult != null) {
val dataUriBase64 = dataUriFindResult.groupValues[1]

View File

@ -167,7 +167,8 @@ class HttpReadAloudService : BaseReadAloudService(),
speakText = speakText,
speakSpeed = speechRate,
source = httpTts,
headerMapF = httpTts.getHeaderMap(true)
headerMapF = httpTts.getHeaderMap(true),
readTimeout = 300 * 1000L
)
var response = analyzeUrl.getResponseAwait()
coroutineContext.ensureActive()

View File

@ -217,6 +217,14 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
searchView.setQuery(getString(R.string.no_group), true)
}
R.id.menu_enabled_explore_group -> {
searchView.setQuery(getString(R.string.enabled_explore), true)
}
R.id.menu_disabled_explore_group -> {
searchView.setQuery(getString(R.string.disabled_explore), true)
}
R.id.menu_help -> showHelp()
}
if (item.groupId == R.id.source_group) {
@ -272,6 +280,14 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
appDb.bookSourceDao.flowNoGroup()
}
searchKey == getString(R.string.enabled_explore) -> {
appDb.bookSourceDao.flowEnabledExplore()
}
searchKey == getString(R.string.disabled_explore) -> {
appDb.bookSourceDao.flowDisabledExplore()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.flowGroupSearch(key)

View File

@ -191,6 +191,14 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
appDb.bookSourceDao.allNoGroup
}
searchKey == appCtx.getString(R.string.enabled_explore) -> {
appDb.bookSourceDao.allEnabledExplore
}
searchKey == appCtx.getString(R.string.disabled_explore) -> {
appDb.bookSourceDao.allDisabledExplore
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.groupSearch(key)

View File

@ -92,6 +92,14 @@
android:id="@+id/menu_group_null"
android:title="@string/no_group" />
<item
android:id="@+id/menu_enabled_explore_group"
android:title="@string/enabled_explore" />
<item
android:id="@+id/menu_disabled_explore_group"
android:title="@string/disabled_explore" />
<group android:id="@+id/source_group">
</group>

View File

@ -729,6 +729,8 @@
<string name="import_old_summary">Seleccione una carpeta de respaldo heredada</string>
<string name="enabled">Activado</string>
<string name="disabled">Desactivado</string>
<string name="enabled_explore">Discovery Enabled</string>
<string name="disabled_explore">Discovery Disabled</string>
<string name="starting_download">Iniciando descarga</string>
<string name="already_in_download">Este libro ya está en la lista de descargas</string>
<string name="click_to_open">Haga clic para abrir</string>

View File

@ -732,6 +732,8 @@
<string name="import_old_summary">Select a legacy backup folder</string>
<string name="enabled">Enabled</string>
<string name="disabled">Disabled</string>
<string name="enabled_explore">Discovery Enabled</string>
<string name="disabled_explore">Discovery Disabled</string>
<string name="starting_download">Starting download</string>
<string name="already_in_download">This book is already in Download list</string>
<string name="click_to_open">Click to open</string>

View File

@ -730,6 +730,8 @@
<string name="import_old_summary">Selecione uma pasta Legado de Backup</string>
<string name="enabled">Ativado</string>
<string name="disabled">Desativado</string>
<string name="enabled_explore">Discovery Enabled</string>
<string name="disabled_explore">Discovery Disabled</string>
<string name="starting_download">Iniciando o download</string>
<string name="already_in_download">Este livro já está na lista de download</string>
<string name="click_to_open">Clique para abrir</string>

View File

@ -730,6 +730,8 @@ Còn </string>
<string name="import_old_summary">Chọn thư mục sao lưu kế thừa</string>
<string name="enabled">Đã bật</string>
<string name="disabled">Đã tắt</string>
<string name="enabled_explore">Discovery Enabled</string>
<string name="disabled_explore">Discovery Disabled</string>
<string name="starting_download">Bắt đầu tải xuống</string>
<string name="already_in_download">Cuốn sách này đã có trong danh sách Download</string>
<string name="click_to_open">Nhấp để mở</string>

View File

@ -723,6 +723,8 @@
<string name="import_old_summary">選擇舊版備份文件夾</string>
<string name="enabled">已啓用</string>
<string name="disabled">已禁用</string>
<string name="enabled_explore">已啟用發現</string>
<string name="disabled_explore">已禁用發現</string>
<string name="text_bottom_justify">文字底部對齊</string>
<string name="starting_download">正在啟動下載</string>
<string name="already_in_download">該書已在下載列表</string>

View File

@ -731,6 +731,8 @@
<string name="import_old_summary">選擇舊版備份資料夾</string>
<string name="enabled">已啟用</string>
<string name="disabled">已禁用</string>
<string name="enabled_explore">已啟用發現</string>
<string name="disabled_explore">已禁用發現</string>
<string name="starting_download">正在啟動下載</string>
<string name="already_in_download">該書已在下載列表</string>
<string name="click_to_open">點擊打開</string>

View File

@ -732,6 +732,8 @@
<string name="import_old_summary">选择旧版备份文件夹</string>
<string name="enabled">已启用</string>
<string name="disabled">已禁用</string>
<string name="enabled_explore">已启用发现</string>
<string name="disabled_explore">已禁用发现</string>
<string name="starting_download">正在启动下载</string>
<string name="already_in_download">该书已在下载列表</string>
<string name="click_to_open">点击打开</string>

View File

@ -734,6 +734,8 @@
<string name="import_old_summary">Select a legacy backup folder</string>
<string name="enabled">Enabled</string>
<string name="disabled">Disabled</string>
<string name="enabled_explore">Discovery Enabled</string>
<string name="disabled_explore">Discovery Disabled</string>
<string name="starting_download">Starting download</string>
<string name="already_in_download">This book is already in Download list</string>
<string name="click_to_open">Click to open</string>