Просмотр исходного кода

添加校验设置;fix:直链规则错误提示不显示

Xwite 4 лет назад
Родитель
Сommit
5b9eeef696

+ 2 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -91,6 +91,8 @@ object PreferKey {
     const val doublePageHorizontal = "doublePageHorizontal"
     const val readUrlOpenInBrowser = "readUrlInBrowser"
     const val defaultBookTreeUri = "defaultBookTreeUri"
+    const val checkSource = "checkSource"
+    const val uploadRule = "uploadRule"
 
     const val cPrimary = "colorPrimary"
     const val cAccent = "colorAccent"

+ 17 - 0
app/src/main/java/io/legado/app/model/CheckSource.kt

@@ -7,9 +7,17 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.service.CheckSourceService
 import io.legado.app.utils.startService
 import io.legado.app.utils.toastOnUi
+import io.legado.app.help.CacheManager
 
 object CheckSource {
     var keyword = "我的"
+    //校验设置
+    var timeout = CacheManager.getLong("checkSourceTimeout") ?: 180000L
+    var checkSearch = CacheManager.get("checkSearch")?.toBoolean() ?: true
+    var checkDiscovery = CacheManager.get("checkDiscovery")?.toBoolean() ?: true
+    var checkInfo = CacheManager.get("checkInfo")?.toBoolean() ?: true
+    var checkCategory = CacheManager.get("checkCategory")?.toBoolean() ?: true
+    var checkContent = CacheManager.get("checkContent")?.toBoolean() ?: true
 
     fun start(context: Context, sources: List<BookSource>) {
         if (sources.isEmpty()) {
@@ -31,4 +39,13 @@ object CheckSource {
             action = IntentAction.stop
         }
     }
+
+    fun putConfig() {
+        CacheManager.put("checkSourceTimeout", timeout * 1000)
+        CacheManager.put("checkSearch", checkSearch)
+        CacheManager.put("checkDiscovery", checkDiscovery)
+        CacheManager.put("checkInfo", checkInfo)
+        CacheManager.put("checkCategory", checkCategory)
+        CacheManager.put("checkContent", checkContent)
+    }
 }

+ 50 - 34
app/src/main/java/io/legado/app/service/CheckSourceService.kt

@@ -9,6 +9,7 @@ import io.legado.app.constant.EventBus
 import io.legado.app.constant.IntentAction
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.BookSource
+import io.legado.app.data.entities.SearchBook
 import io.legado.app.help.AppConfig
 import io.legado.app.help.coroutine.CompositeCoroutine
 import io.legado.app.model.CheckSource
@@ -33,6 +34,8 @@ class CheckSourceService : BaseService() {
     private val checkedIds = ArrayList<String>()
     private var processIndex = 0
     private var notificationMsg = ""
+    private var books = ArrayList<SearchBook>()
+
     private val notificationBuilder by lazy {
         NotificationCompat.Builder(this, AppConst.channelIdReadAloud)
             .setSmallIcon(R.drawable.ic_network_check)
@@ -118,45 +121,58 @@ class CheckSourceService : BaseService() {
                     searchWord = it
                 }
             }
-            var books = WebBook.searchBookAwait(this, source, searchWord)
-            if (books.isEmpty()) {
-                source.addGroup("搜索失效")
-                val exs = source.exploreKinds
-                var url: String? = null
-                for (ex in exs) {
-                    url = ex.url
-                    if (!url.isNullOrBlank()) {
-                        break
+            //校验搜索
+            if (CheckSource.checkSearch) {
+                books = WebBook.searchBookAwait(this, source, searchWord)
+                if (books.isEmpty()) source.addGroup("搜索失效") else source.removeGroup("搜索失效")
+            }
+            //校验发现
+            if (CheckSource.checkDiscovery) {
+                if (books.isEmpty()) {
+                    val exs = source.exploreKinds
+                    var url: String? = null
+                    for (ex in exs) {
+                        url = ex.url
+                        if (!url.isNullOrBlank()) {
+                            break
+                        }
+                    }
+                    if (url.isNullOrBlank()) {
+                        throw NoStackTraceException("搜索内容为空并且没有发现")
+                    }
+                    books = WebBook.exploreBookAwait(this, source, url)
+                    if (books.isEmpty()) {
+                        throw NoStackTraceException("发现书籍为空")
                     }
                 }
-                if (url.isNullOrBlank()) {
-                    throw NoStackTraceException("搜索内容为空并且没有发现")
+            }
+            //校验详情
+            if (CheckSource.checkInfo) {
+                var book = books.first().toBook()
+                if (book.tocUrl.isBlank()) {
+                    book = WebBook.getBookInfoAwait(this, source, book)
                 }
-                books = WebBook.exploreBookAwait(this, source, url)
-                if (books.isEmpty()) {
-                    throw NoStackTraceException("发现书籍为空")
+                //校验目录
+                if (CheckSource.checkCategory) {
+                    val toc = WebBook.getChapterListAwait(this, source, book)
+                    val nextChapterUrl = toc.getOrNull(1)?.url ?: toc.first().url
+                    //校验正文
+                    if (CheckSource.checkContent) {
+                        val content = WebBook.getContentAwait(
+                            this,
+                            bookSource = source,
+                            book = book,
+                            bookChapter = toc.first(),
+                            nextChapterUrl = nextChapterUrl,
+                            needSave = false
+                        )
+                        if ( !toc.first().isVolume && content.isBlank()) {
+                            throw NoStackTraceException("正文内容为空")
+                        }
+                    }
                 }
-            } else {
-                source.removeGroup("搜索失效")
-            }
-            var book = books.first().toBook()
-            if (book.tocUrl.isBlank()) {
-                book = WebBook.getBookInfoAwait(this, source, book)
-            }
-            val toc = WebBook.getChapterListAwait(this, source, book)
-            val nextChapterUrl = toc.getOrNull(1)?.url ?: toc.first().url
-            val content = WebBook.getContentAwait(
-                this,
-                bookSource = source,
-                book = book,
-                bookChapter = toc.first(),
-                nextChapterUrl = nextChapterUrl,
-                needSave = false
-            )
-            if ( !toc.first().isVolume && content.isBlank()) {
-                throw NoStackTraceException("正文内容为空")
             }
-        }.timeout(180000L)
+        }.timeout(CheckSource.timeout)
             .onError(searchCoroutine) {
                 source.addGroup("失效")
                 if (source.bookSourceComment?.contains("Error: ") == false) {

+ 71 - 0
app/src/main/java/io/legado/app/ui/config/CheckSourceConfig.kt

@@ -0,0 +1,71 @@
+package io.legado.app.ui.config
+
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import io.legado.app.R
+import io.legado.app.base.BaseDialogFragment
+import io.legado.app.databinding.DialogCheckSourceConfigBinding
+import io.legado.app.model.CheckSource
+import io.legado.app.lib.theme.primaryColor
+import io.legado.app.utils.setLayout
+import io.legado.app.utils.viewbindingdelegate.viewBinding
+import io.legado.app.utils.toastOnUi
+import splitties.views.onClick
+
+class CheckSourceConfig : BaseDialogFragment(R.layout.dialog_check_source_config) {
+
+    private val binding by viewBinding(DialogCheckSourceConfigBinding::bind)
+    //允许的最小超时时间,秒
+    private val minTimeout = 60L
+
+    override fun onStart() {
+        super.onStart()
+        setLayout(
+            0.9f,
+            ViewGroup.LayoutParams.WRAP_CONTENT
+        )
+    }
+
+    override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
+        binding.toolBar.setBackgroundColor(primaryColor)
+        CheckSource.run {
+            binding.checkSourceTimeout.setText((timeout / 1000).toString())
+            binding.checkSearch?.isChecked = checkSearch
+            binding.checkDiscovery?.isChecked = checkDiscovery
+            binding.checkInfo?.isChecked = checkInfo
+            binding.checkCategory?.isChecked = checkCategory
+            binding.checkContent?.isChecked = checkContent
+            binding.tvCancel.onClick {
+                dismiss()
+            }
+            binding.tvOk.onClick {
+                val text = binding.checkSourceTimeout.text.toString()
+                when {
+                    text.isBlank() -> {
+                        toastOnUi("${getString(R.string.timeout)}${getString(R.string.cannot_empty)}")
+                        return@onClick
+                    }
+                    text.toLong() < minTimeout -> {
+                        toastOnUi("${getString(R.string.timeout)}${getString(R.string.less_than)}${minTimeout}${getString(R.string.seconds)}")
+                        return@onClick
+                    }
+                    else -> timeout = text.toLong() * 1000
+                }
+                val _checkSearch = binding.checkSearch?.isChecked
+                val _checkDiscovery = binding.checkDiscovery?.isChecked
+                if (!_checkSearch && !_checkDiscovery) {
+                        toastOnUi(getString(R.string.error_check_source_config))
+                        return@onClick
+                }
+                checkSearch = _checkSearch
+                checkDiscovery = _checkDiscovery
+                checkInfo = binding.checkInfo?.isChecked
+                checkCategory = binding.checkCategory?.isChecked
+                checkContent = binding.checkContent?.isChecked
+                putConfig()
+                dismiss()
+            }
+        }
+    }
+}

+ 2 - 2
app/src/main/java/io/legado/app/ui/config/DirectLinkUploadConfig.kt

@@ -41,11 +41,11 @@ class DirectLinkUploadConfig : BaseDialogFragment(R.layout.dialog_direct_link_up
             val uploadUrl = binding.editUploadUrl.text?.toString()
             val downloadUrlRule = binding.editDownloadUrlRule.text?.toString()
             val summary = binding.editSummary.text?.toString()
-            uploadUrl ?: let {
+            if (uploadUrl.isNullOrBlank()) {
                 toastOnUi("上传Url不能为空")
                 return@onClick
             }
-            downloadUrlRule ?: let {
+            if (downloadUrlRule.isNullOrBlank()) {
                 toastOnUi("下载Url规则不能为空")
                 return@onClick
             }

+ 5 - 4
app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt

@@ -70,7 +70,7 @@ class OtherConfigFragment : BasePreferenceFragment(),
         when (preference?.key) {
             PreferKey.userAgent -> showUserAgentDialog()
             PreferKey.defaultBookTreeUri -> localBookTreeSelect.launch {
-                title = "选择保存书籍的文件夹"
+                title = getString(R.string.select_book_folder)
                 mode = HandleFileContract.DIR_SYS
             }
             PreferKey.preDownloadNum -> NumberPickerDialog(requireContext())
@@ -98,7 +98,8 @@ class OtherConfigFragment : BasePreferenceFragment(),
                     AppConfig.webPort = it
                 }
             PreferKey.cleanCache -> clearCache()
-            "uploadRule" -> DirectLinkUploadConfig().show(childFragmentManager, "uploadRuleConfig")
+            PreferKey.uploadRule -> showDialogFragment<DirectLinkUploadConfig>()
+            PreferKey.checkSource -> showDialogFragment<CheckSourceConfig>()
         }
         return super.onPreferenceTreeClick(preference)
     }
@@ -155,9 +156,9 @@ class OtherConfigFragment : BasePreferenceFragment(),
 
     @SuppressLint("InflateParams")
     private fun showUserAgentDialog() {
-        alert("UserAgent") {
+        alert(getString(R.string.user_agent)) {
             val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
-                editView.hint = "UserAgent"
+                editView.hint = getString(R.string.user_agent)
                 editView.setText(AppConfig.userAgent)
             }
             customView { alertBinding.root }

+ 94 - 0
app/src/main/res/layout/dialog_check_source_config.xml

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/tool_bar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="?attr/actionBarStyle"
+        app:title="@string/check_source_config"
+        app:popupTheme="@style/AppTheme.PopupOverlay"
+        app:titleTextAppearance="@style/ToolbarTitle" />
+
+    <io.legado.app.ui.widget.text.TextInputLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="3dp">
+
+        <io.legado.app.lib.theme.view.ThemeEditText
+            android:id="@+id/check_source_timeout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/check_source_timeout"
+            tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
+
+    </io.legado.app.ui.widget.text.TextInputLayout>
+
+    <com.google.android.flexbox.FlexboxLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="12dp"
+        android:paddingRight="12dp"
+        app:flexWrap="wrap"
+        app:justifyContent="space_between">
+
+        <io.legado.app.lib.theme.view.ThemeCheckBox
+            android:id="@+id/check_search"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/check_search" />
+        <io.legado.app.lib.theme.view.ThemeCheckBox
+            android:id="@+id/check_discovery"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/check_discovery" />
+        <io.legado.app.lib.theme.view.ThemeCheckBox
+            android:id="@+id/check_info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_wrapBefore="true"
+            android:text="@string/check_info" />
+        <io.legado.app.lib.theme.view.ThemeCheckBox
+            android:id="@+id/check_category"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/check_category" />
+        <io.legado.app.lib.theme.view.ThemeCheckBox
+            android:id="@+id/check_content"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/check_content" />
+
+    </com.google.android.flexbox.FlexboxLayout>
+
+    <com.google.android.flexbox.FlexboxLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="12dp"
+        android:paddingRight="12dp"
+        app:flexWrap="wrap"
+        app:justifyContent="flex_end">
+
+        <io.legado.app.ui.widget.text.AccentTextView
+            android:id="@+id/tv_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="12dp"
+            android:text="@string/cancel"
+            tools:ignore="RtlHardcoded" />
+
+        <io.legado.app.ui.widget.text.AccentTextView
+            android:id="@+id/tv_ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="12dp"
+            android:text="@string/ok"
+            tools:ignore="RtlHardcoded" />
+
+    </com.google.android.flexbox.FlexboxLayout>
+</LinearLayout>

+ 1 - 1
app/src/main/res/layout/dialog_direct_link_upload_config.xml

@@ -11,7 +11,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:theme="?attr/actionBarStyle"
-        app:title="直链上传配置"
+        app:title="@string/direct_link_upload_config"
         app:popupTheme="@style/AppTheme.PopupOverlay"
         app:titleTextAppearance="@style/ToolbarTitle" />
 

+ 16 - 0
app/src/main/res/values/strings.xml

@@ -877,6 +877,7 @@
     <string name="path">path</string>
     <string name="direct_link_upload_rule">直链上传规则</string>
     <string name="direct_link_upload_rule_summary">用于导出书源书单时生成直链url</string>
+    <string name="direct_link_upload_config">直链上传配置</string>
     <string name="copy_play_url">拷贝播放Url</string>
     <string name="set_source_variable">设置源变量</string>
     <string name="set_book_variable">设置书籍变量</string>
@@ -916,5 +917,20 @@
     <string name="expand_text_menu">展开文本选择菜单</string>
     <string name="book_tree_uri_t">书籍保存位置</string>
     <string name="book_tree_uri_s">从其它应用打开的书籍保存位置</string>
+    <string name="select_book_folder">选择保存书籍的文件夹</string>
+    <string name="user_agent">用户代理</string>
 
+    <!-- check source config string -->
+    <string name="check_source_config">校验设置</string>
+    <string name="check_source_timeout">单个书源校验超时(秒)</string>
+    <string name="timeout">超时</string>
+    <string name="seconds">秒</string>
+    <string name="less_than">小于</string>
+    <string name="check_search">校验搜索</string>
+    <string name="check_discovery">校验发现</string>
+    <string name="check_info">校验详情</string>
+    <string name="check_category">校验目录</string>
+    <string name="check_content">校验正文</string>
+    <string name="error_check_source_config">搜索发现至少校验一个</string>
+    <!-- string end -->
 </resources>

+ 5 - 1
app/src/main/res/xml/pref_config_other.xml

@@ -54,13 +54,17 @@
 
         <io.legado.app.ui.widget.prefs.Preference
             android:key="userAgent"
-            android:title="UserAgent" />
+            android:title="@string/user_agent" />
 
         <io.legado.app.ui.widget.prefs.Preference
             android:key="defaultBookTreeUri"
             android:title="@string/book_tree_uri_t"
             android:summary="@string/book_tree_uri_s" />
 
+        <io.legado.app.ui.widget.prefs.Preference
+            android:key="checkSource"
+            android:title="@string/check_source_config" />
+
         <io.legado.app.ui.widget.prefs.Preference
             android:key="uploadRule"
             android:title="@string/direct_link_upload_rule"