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 eb3855e49..ef87db307 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -11,7 +11,7 @@ import io.legado.app.data.entities.* @Database( - entities = [Book::class, BookGroup::class, BookSource::class, Chapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class], + entities = [Book::class, BookGroup::class, BookSource::class, Chapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, SourceCookie::class], version = 1, exportSchema = true ) @@ -53,4 +53,5 @@ abstract class AppDatabase : RoomDatabase() { abstract fun replaceRuleDao(): ReplaceRuleDao abstract fun searchBookDao(): SearchBookDao abstract fun searchKeywordDao(): SearchKeywordDao + abstract fun sourceCookieDao(): SourceCookieDao } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/dao/SourceCookieDao.kt b/app/src/main/java/io/legado/app/data/dao/SourceCookieDao.kt new file mode 100644 index 000000000..fcf4abf70 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/dao/SourceCookieDao.kt @@ -0,0 +1,12 @@ +package io.legado.app.data.dao + +import androidx.room.Dao +import androidx.room.Query + +@Dao +interface SourceCookieDao { + + @Query("SELECT cookie FROM cookies Where url = :url") + fun getCookieByUrl(url: String): String? + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/SourceCookie.kt b/app/src/main/java/io/legado/app/data/entities/SourceCookie.kt new file mode 100644 index 000000000..62581a2f8 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/SourceCookie.kt @@ -0,0 +1,12 @@ +package io.legado.app.data.entities + +import androidx.room.Entity +import androidx.room.Index +import androidx.room.PrimaryKey + +@Entity(tableName = "cookies", indices = [(Index(value = ["url"], unique = true))]) +data class SourceCookie( + @PrimaryKey + var url: String = "", + var cookie: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt new file mode 100644 index 000000000..79c6fa28e --- /dev/null +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt @@ -0,0 +1,215 @@ +package io.legado.app.model.analyzeRule + +import android.text.TextUtils +import com.jayway.jsonpath.JsonPath +import com.jayway.jsonpath.ReadContext +import java.util.* +import java.util.regex.Pattern + +class AnalyzeByJSonPath { + private var ctx: ReadContext? = null + + fun parse(json: Any): AnalyzeByJSonPath { + ctx = if (json is String) { + JsonPath.parse(json) + } else { + JsonPath.parse(json) + } + return this + } + + fun getString(rule: String): String? { + if (TextUtils.isEmpty(rule)) return null + var result = "" + val rules: Array + val elementsType: String + if (rule.contains("&&")) { + rules = rule.split("&&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "&" + } else { + rules = rule.split("\\|\\|".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "|" + } + if (rules.size == 1) { + if (!rule.contains("{$.")) { + ctx?.let { + try { + val ob = it.read(rule) + result = if (ob is List<*>) { + val builder = StringBuilder() + for (o in ob) { + builder.append(o).append("\n") + } + builder.toString().replace("\\n$".toRegex(), "") + } else { + ob.toString() + } + } catch (ignored: Exception) { + } + + } + return result + } else { + result = rule + val matcher = jsonRulePattern.matcher(rule) + while (matcher.find()) { + result = result.replace( + String.format("{%s}", matcher.group()), + getString(matcher.group())!! + ) + } + return result + } + } else { + val sb = StringBuilder() + for (rl in rules) { + val temp = getString(rl) + if (!TextUtils.isEmpty(temp)) { + sb.append(temp) + if (elementsType == "|") { + break + } + } + } + return sb.toString() + } + } + + internal fun getStringList(rule: String): List { + val result = ArrayList() + if (TextUtils.isEmpty(rule)) return result + val rules: Array + val elementsType: String + when { + rule.contains("&&") -> { + rules = rule.split("&&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "&" + } + rule.contains("%%") -> { + rules = rule.split("%%".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "%" + } + else -> { + rules = rule.split("\\|\\|".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "|" + } + } + if (rules.size == 1) { + if (!rule.contains("{$.")) { + try { + val `object` = ctx!!.read(rule) ?: return result + if (`object` is List<*>) { + for (o in `object`) + result.add(o.toString()) + } else { + result.add(`object`.toString()) + } + } catch (ignored: Exception) { + } + + return result + } else { + val matcher = jsonRulePattern.matcher(rule) + while (matcher.find()) { + val stringList = getStringList(matcher.group()) + for (s in stringList) { + result.add(rule.replace(String.format("{%s}", matcher.group()), s)) + } + } + return result + } + } else { + val results = ArrayList>() + for (rl in rules) { + val temp = getStringList(rl) + if (temp.isNotEmpty()) { + results.add(temp) + if (temp.isNotEmpty() && elementsType == "|") { + break + } + } + } + if (results.size > 0) { + if ("%" == elementsType) { + for (i in 0 until results[0].size) { + for (temp in results) { + if (i < temp.size) { + result.add(temp[i]) + } + } + } + } else { + for (temp in results) { + result.addAll(temp) + } + } + } + return result + } + } + + internal fun getObject(rule: String): Any { + return ctx!!.read(rule) + } + + internal fun getList(rule: String): ArrayList? { + val result = ArrayList() + if (TextUtils.isEmpty(rule)) return result + val elementsType: String + val rules: Array + when { + rule.contains("&&") -> { + rules = rule.split("&&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "&" + } + rule.contains("%%") -> { + rules = rule.split("%%".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "%" + } + else -> { + rules = rule.split("\\|\\|".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + elementsType = "|" + } + } + if (rules.size == 1) { + ctx?.let { + try { + return it.read>(rules[0]) + } catch (e: Exception) { + } + } + return null + } else { + val results = ArrayList>() + for (rl in rules) { + val temp = getList(rl) + if (temp != null && temp.isNotEmpty()) { + results.add(temp) + if (temp.isNotEmpty() && elementsType == "|") { + break + } + } + } + if (results.size > 0) { + if ("%" == elementsType) { + for (i in 0 until results[0].size) { + for (temp in results) { + if (i < temp.size) { + temp[i]?.let { result.add(it) } + } + } + } + } else { + for (temp in results) { + result.addAll(temp) + } + } + } + } + return result + } + + companion object { + private val jsonRulePattern = Pattern.compile("(?<=\\{)\\$\\..+?(?=\\})") + } +} diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeHeaders.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeHeaders.kt new file mode 100644 index 000000000..381987183 --- /dev/null +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeHeaders.kt @@ -0,0 +1,37 @@ +package io.legado.app.model.analyzeRule + +import android.text.TextUtils.isEmpty +import io.legado.app.App +import io.legado.app.R +import io.legado.app.data.entities.BookSource +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJson +import io.legado.app.utils.getPrefString +import java.util.* + +/** + * Created by GKF on 2018/3/2. + * 解析Headers + */ + +object AnalyzeHeaders { + + private val defaultUserAgent: String + get() = App.INSTANCE.getPrefString("user_agent") + ?: App.INSTANCE.getString(R.string.pv_user_agent) + + fun getMap(bookSource: BookSource?): Map { + val headerMap = HashMap() + if (bookSource != null && !isEmpty(bookSource.header)) { + bookSource.header?.let { + val map: HashMap? = GSON.fromJson>(it) + map?.let { headerMap.putAll(map) } + } + } + if (bookSource != null) { + val cookie = App.db.sourceCookieDao().getCookieByUrl(bookSource.origin) + cookie?.let { headerMap["Cookie"] = cookie } + } + return headerMap + } +} diff --git a/app/src/main/res/values/pref_key_value.xml b/app/src/main/res/values/pref_key_value.xml new file mode 100644 index 000000000..dd706603a --- /dev/null +++ b/app/src/main/res/values/pref_key_value.xml @@ -0,0 +1,27 @@ + + + auto_refresh + list_screen_direction + full_screen + threads_num + user_agent + bookshelf_px + read_type + expandGroupFind + defaultToRead + autoDownload + downloadPath + checkUpdate + + ic_launcher_round + book_launcher_round + + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.2357.134 Safari/537.36 + + https://gedoor.github.io/MyBookshelf/sourcerule.html + https://github.com/gedoor/MyBookshelf + https://gedoor.github.io/MyBookshelf/disclaimer.html + https://gedoor.github.io/MyBookshelf/ + https://github.com/gedoor/MyBookshelf/releases/latest + https://api.github.com/repos/gedoor/MyBookshelf/releases/latest +