diff --git a/app/src/main/java/io/legado/app/data/AppDatabase.kt b/app/src/main/java/io/legado/app/data/AppDatabase.kt index e22b26eaf..a599f7f73 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -50,7 +50,7 @@ abstract class AppDatabase : RoomDatabase() { fun createDatabase(context: Context) = Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME) - .fallbackToDestructiveMigration() + .fallbackToDestructiveMigrationFrom(1, 2, 3, 4, 5, 6, 7, 8, 9) .addMigrations(*DatabaseMigrations.migrations) .allowMainThreadQueries() .addCallback(dbCallback) diff --git a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt index cab31e55d..01fdec156 100644 --- a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt @@ -17,9 +17,21 @@ import javax.script.SimpleBindings @Suppress("unused") interface BaseSource : JsExtensions { + var loginUrl: String? + var header: String? + fun getStoreUrl(): String - var header: String? + fun getLoginJs(): String? { + val loginJs = loginUrl + return when { + loginJs == null -> null + loginJs.startsWith("@js:") -> loginJs.substring(4) + loginJs.startsWith("") -> + loginJs.substring(4, loginJs.lastIndexOf("<")) + else -> loginJs + } + } /** * 解析header规则 diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index 4fe694709..4339e0875 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -28,7 +28,7 @@ data class BookSource( var enabled: Boolean = true, // 是否启用 var enabledExplore: Boolean = true, // 启用发现 override var header: String? = null, // 请求头 - var loginUrl: String? = null, // 登录地址 + override var loginUrl: String? = null, // 登录地址 var loginUi: List? = null, //登录UI var loginCheckJs: String? = null, //登录检测js var bookSourceComment: String? = null, // 注释 @@ -50,7 +50,7 @@ data class BookSource( @delegate:Transient @delegate:Ignore @IgnoredOnParcel - val exploreKinds by lazy { + val exploreKinds: List by lazy { val exploreUrl = exploreUrl ?: return@lazy emptyList() val kinds = arrayListOf() var ruleStr = exploreUrl diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt index 162e1f1d9..0a933883b 100644 --- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt @@ -21,7 +21,7 @@ data class RssSource( var sourceComment: String? = null, var enabled: Boolean = true, override var header: String? = null, // 请求头 - var loginUrl: String? = null, // 登录地址 + override var loginUrl: String? = null, // 登录地址 var loginUi: List? = null, //登录UI var loginCheckJs: String? = null, //登录检测js var sortUrl: String? = null, diff --git a/app/src/main/java/io/legado/app/model/rss/Rss.kt b/app/src/main/java/io/legado/app/model/rss/Rss.kt index 22f0a6c02..51539ee0a 100644 --- a/app/src/main/java/io/legado/app/model/rss/Rss.kt +++ b/app/src/main/java/io/legado/app/model/rss/Rss.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlin.coroutines.CoroutineContext +@Suppress("MemberVisibilityCanBePrivate") object Rss { fun getArticles( @@ -23,18 +24,27 @@ object Rss { context: CoroutineContext = Dispatchers.IO ): Coroutine { return Coroutine.async(scope, context) { - val ruleData = RuleData() - val analyzeUrl = AnalyzeUrl( - sortUrl, - page = page, - ruleData = ruleData, - headerMapF = rssSource.getHeaderMap() - ) - val body = analyzeUrl.getStrResponse(rssSource.sourceUrl).body - RssParserByRule.parseXML(sortName, sortUrl, body, rssSource, ruleData) + getArticlesAwait(sortName, sortUrl, rssSource, page) } } + suspend fun getArticlesAwait( + sortName: String, + sortUrl: String, + rssSource: RssSource, + page: Int, + ): RssResult { + val ruleData = RuleData() + val analyzeUrl = AnalyzeUrl( + sortUrl, + page = page, + ruleData = ruleData, + headerMapF = rssSource.getHeaderMap() + ) + val body = analyzeUrl.getStrResponse(rssSource.sourceUrl).body + return RssParserByRule.parseXML(sortName, sortUrl, body, rssSource, ruleData) + } + fun getContent( scope: CoroutineScope, rssArticle: RssArticle, @@ -43,19 +53,27 @@ object Rss { context: CoroutineContext = Dispatchers.IO ): Coroutine { return Coroutine.async(scope, context) { - val analyzeUrl = AnalyzeUrl( - rssArticle.link, - baseUrl = rssArticle.origin, - ruleData = rssArticle, - headerMapF = rssSource.getHeaderMap() - ) - val body = analyzeUrl.getStrResponse(rssArticle.origin).body - Debug.log(rssSource.sourceUrl, "≡获取成功:${rssSource.sourceUrl}") - Debug.log(rssSource.sourceUrl, body, state = 20) - val analyzeRule = AnalyzeRule(rssArticle, rssSource) - analyzeRule.setContent(body) - .setBaseUrl(NetworkUtils.getAbsoluteURL(rssArticle.origin, rssArticle.link)) - analyzeRule.getString(ruleContent) + getContentAwait(rssArticle, ruleContent, rssSource) } } + + suspend fun getContentAwait( + rssArticle: RssArticle, + ruleContent: String, + rssSource: RssSource, + ): String { + val analyzeUrl = AnalyzeUrl( + rssArticle.link, + baseUrl = rssArticle.origin, + ruleData = rssArticle, + headerMapF = rssSource.getHeaderMap() + ) + val body = analyzeUrl.getStrResponse(rssArticle.origin).body + Debug.log(rssSource.sourceUrl, "≡获取成功:${rssSource.sourceUrl}") + Debug.log(rssSource.sourceUrl, body, state = 20) + val analyzeRule = AnalyzeRule(rssArticle, rssSource) + analyzeRule.setContent(body) + .setBaseUrl(NetworkUtils.getAbsoluteURL(rssArticle.origin, rssArticle.link)) + return analyzeRule.getString(ruleContent) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/service/CheckSourceService.kt b/app/src/main/java/io/legado/app/service/CheckSourceService.kt index 00aeaf374..c706dbf39 100644 --- a/app/src/main/java/io/legado/app/service/CheckSourceService.kt +++ b/app/src/main/java/io/legado/app/service/CheckSourceService.kt @@ -113,9 +113,6 @@ class CheckSourceService : BaseService() { var books = webBook.searchBookAwait(this, CheckSource.keyword) if (books.isEmpty()) { val exs = source.exploreKinds - if (exs.isEmpty()) { - throw Exception("搜索内容为空并且没有发现") - } var url: String? = null for (ex in exs) { url = ex.url @@ -123,11 +120,14 @@ class CheckSourceService : BaseService() { break } } - books = webBook.exploreBookAwait(this, url!!) + if (url.isNullOrBlank()) { + throw Exception("搜索内容为空并且没有发现") + } + books = webBook.exploreBookAwait(this, url) } val book = webBook.getBookInfoAwait(this, books.first().toBook()) val toc = webBook.getChapterListAwait(this, book) - val content = webBook.getContentAwait(this, book, toc.first()) + val content = webBook.getContentAwait(this, book, toc.first(), toc.getOrNull(2)?.url) if (content.isBlank()) { throw Exception("正文内容为空") } diff --git a/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt b/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt index dd25d1125..81773df3a 100644 --- a/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt +++ b/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt @@ -15,6 +15,7 @@ import io.legado.app.ui.widget.text.EditText import io.legado.app.ui.widget.text.TextInputLayout import io.legado.app.utils.GSON import io.legado.app.utils.applyTint +import io.legado.app.utils.toastOnUi import io.legado.app.utils.viewbindingdelegate.viewBinding class RuleUiLoginDialog : BaseDialogFragment() { @@ -84,9 +85,14 @@ class RuleUiLoginDialog : BaseDialogFragment() { } } bookSource.putLoginInfo(GSON.toJson(loginData)) - bookSource.loginUrl?.let { - - bookSource.evalJS(it) + bookSource.getLoginJs()?.let { + try { + bookSource.evalJS(it) + toastOnUi(R.string.success) + } catch (e: Exception) { + e.printStackTrace() + toastOnUi(e.localizedMessage ?: "ERROR") + } } } } diff --git a/app/src/main/java/io/legado/app/utils/EncoderUtils.kt b/app/src/main/java/io/legado/app/utils/EncoderUtils.kt index 504d4a9c1..0b3300897 100644 --- a/app/src/main/java/io/legado/app/utils/EncoderUtils.kt +++ b/app/src/main/java/io/legado/app/utils/EncoderUtils.kt @@ -125,6 +125,8 @@ object EncoderUtils { * @param key The key. * @param algorithm The name of algorithm. * @param transformation The name of the transformation, e.g., DES/CBC/PKCS5Padding. + * @param iv The buffer with the IV. The contents of the + * buffer are copied to protect against subsequent modification. * @param isEncrypt True to encrypt, false otherwise. * @return the bytes of symmetric encryption or decryption */ diff --git a/build.gradle b/build.gradle index 844e4e6b6..967f30950 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.5.30-M1' + ext.kotlin_version = '1.5.30' repositories { google() mavenCentral()