Merge branch 'gedoor:master' into master

pull/1276/head
ag2s20150909 3 years ago committed by GitHub
commit 5b7687393a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  2. 14
      app/src/main/java/io/legado/app/data/entities/BaseSource.kt
  3. 4
      app/src/main/java/io/legado/app/data/entities/BookSource.kt
  4. 2
      app/src/main/java/io/legado/app/data/entities/RssSource.kt
  5. 62
      app/src/main/java/io/legado/app/model/rss/Rss.kt
  6. 10
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  7. 12
      app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt
  8. 2
      app/src/main/java/io/legado/app/utils/EncoderUtils.kt
  9. 2
      build.gradle

@ -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)

@ -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("<js>") ->
loginJs.substring(4, loginJs.lastIndexOf("<"))
else -> loginJs
}
}
/**
* 解析header规则

@ -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<RowUi>? = 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<ExploreKind> by lazy {
val exploreUrl = exploreUrl ?: return@lazy emptyList()
val kinds = arrayListOf<ExploreKind>()
var ruleStr = exploreUrl

@ -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<RowUi>? = null, //登录UI
var loginCheckJs: String? = null, //登录检测js
var sortUrl: String? = null,

@ -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<RssResult> {
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<String> {
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)
}
}

@ -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("正文内容为空")
}

@ -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")
}
}
}
}

@ -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., <i>DES/CBC/PKCS5Padding</i>.
* @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
*/

@ -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()

Loading…
Cancel
Save