parent
ef475af436
commit
42ccafde13
@ -0,0 +1,19 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:49 |
||||||
|
*/ |
||||||
|
data class BookInfoRule3( |
||||||
|
var init: String? = null, |
||||||
|
var name: String? = null, |
||||||
|
var author: String? = null, |
||||||
|
var intro: String? = null, |
||||||
|
var kind: String? = null, |
||||||
|
var lastChapter: String? = null, |
||||||
|
var updateTime: String? = null, |
||||||
|
var coverUrl: String? = null, |
||||||
|
var tocUrl: String? = null, |
||||||
|
var wordCount: String? = null, |
||||||
|
var canReName: String? = null |
||||||
|
) |
@ -0,0 +1,15 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:50 |
||||||
|
*/ |
||||||
|
data class ContentRule3( |
||||||
|
var content: String? = null, |
||||||
|
var nextContentUrl: String? = null, |
||||||
|
var webJs: String? = null, |
||||||
|
var sourceRegex: String? = null, |
||||||
|
var replaceRegex: String? = null, //替换规则 |
||||||
|
var imageStyle: String? = null, //默认大小居中,FULL最大宽度 |
||||||
|
var payAction: String? = null, //购买操作,url/js |
||||||
|
) |
@ -0,0 +1,18 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:50 |
||||||
|
*/ |
||||||
|
data class ExploreRule3( |
||||||
|
var bookList: String? = null, |
||||||
|
var name: String? = null, |
||||||
|
var author: String? = null, |
||||||
|
var intro: String? = null, |
||||||
|
var kind: String? = null, |
||||||
|
var lastChapter: String? = null, |
||||||
|
var updateTime: String? = null, |
||||||
|
var bookUrl: String? = null, |
||||||
|
var coverUrl: String? = null, |
||||||
|
var wordCount: String? = null |
||||||
|
) |
@ -0,0 +1,19 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:48 |
||||||
|
*/ |
||||||
|
data class SearchRule3( |
||||||
|
var checkKeyWord: String? = null, // 校验关键字 |
||||||
|
var bookList: String? = null, |
||||||
|
var name: String? = null, |
||||||
|
var author: String? = null, |
||||||
|
var intro: String? = null, |
||||||
|
var kind: String? = null, |
||||||
|
var lastChapter: String? = null, |
||||||
|
var updateTime: String? = null, |
||||||
|
var bookUrl: String? = null, |
||||||
|
var coverUrl: String? = null, |
||||||
|
var wordCount: String? = null |
||||||
|
) |
@ -0,0 +1,36 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:47 |
||||||
|
*/ |
||||||
|
data class Source3( |
||||||
|
var bookSourceUrl: String = "", // 地址,包括 http/https |
||||||
|
var bookSourceName: String = "", // 名称 |
||||||
|
var bookSourceGroup: String? = null, // 分组 |
||||||
|
//未加 |
||||||
|
var bookSourceType: Int = 0, // 类型,0 文本,1 音频, 3 图片 |
||||||
|
var bookUrlPattern: String? = null, // 详情页url正则 |
||||||
|
var customOrder: Int = 0, // 手动排序编号 |
||||||
|
var enabled: Boolean = true, // 是否启用 |
||||||
|
//未加 |
||||||
|
var enabledExplore: Boolean = true, // 启用发现 |
||||||
|
var concurrentRate: String? = null, // 并发率 |
||||||
|
var header: String? = null, // 请求头 |
||||||
|
var loginUrl: String? = null, // 登录地址 |
||||||
|
//未加 |
||||||
|
var loginUi: String? = null, // 登录UI |
||||||
|
var loginCheckJs: String? = null, // 登录检测js |
||||||
|
var bookSourceComment: String? = null, // 注释 |
||||||
|
var lastUpdateTime: Long = 0, // 最后更新时间,用于排序 |
||||||
|
//未加 |
||||||
|
var respondTime: Long = 180000L, // 响应时间,用于排序 |
||||||
|
var weight: Int = 0, // 智能排序的权重 |
||||||
|
var exploreUrl: String? = null, // 发现url |
||||||
|
var ruleExplore: ExploreRule3? = null, // 发现规则 |
||||||
|
var searchUrl: String? = null, // 搜索url |
||||||
|
var ruleSearch: SearchRule3? = null, // 搜索规则 |
||||||
|
var ruleBookInfo: BookInfoRule3? = null, // 书籍信息页规则 |
||||||
|
var ruleToc: TocRule3? = null, // 目录页规则 |
||||||
|
var ruleContent: ContentRule3? = null // 正文页规则 |
||||||
|
) |
@ -0,0 +1,101 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
import xyz.fycz.myreader.common.APPCONST |
||||||
|
import xyz.fycz.myreader.greendao.entity.rule.* |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:51 |
||||||
|
*/ |
||||||
|
object Third3SourceUtil { |
||||||
|
fun source3ToSource(bean: Source3): BookSource { |
||||||
|
val bookSource = BookSource() |
||||||
|
bookSource.sourceUrl = bean.bookSourceUrl |
||||||
|
bookSource.sourceName = bean.bookSourceName |
||||||
|
bookSource.sourceGroup = bean.bookSourceGroup |
||||||
|
bookSource.sourceType = APPCONST.THIRD_3_SOURCE |
||||||
|
bookSource.orderNum = bean.customOrder |
||||||
|
bookSource.enable = bean.enabled |
||||||
|
bookSource.concurrentRate = bean.concurrentRate |
||||||
|
bookSource.sourceHeaders = bean.header |
||||||
|
bookSource.loginUrl = bean.loginUrl |
||||||
|
bookSource.loginCheckJs = bean.loginCheckJs |
||||||
|
bookSource.sourceComment = bean.bookSourceComment |
||||||
|
bookSource.lastUpdateTime = bean.lastUpdateTime |
||||||
|
bookSource.weight = bean.weight |
||||||
|
|
||||||
|
|
||||||
|
val searchRule = SearchRule() |
||||||
|
val ruleSearch = bean.ruleSearch |
||||||
|
searchRule.searchUrl = bean.searchUrl |
||||||
|
searchRule.list = ruleSearch?.bookList |
||||||
|
searchRule.name = ruleSearch?.name |
||||||
|
searchRule.author = ruleSearch?.author |
||||||
|
searchRule.desc = ruleSearch?.intro |
||||||
|
searchRule.type = ruleSearch?.kind |
||||||
|
searchRule.lastChapter = ruleSearch?.lastChapter |
||||||
|
searchRule.updateTime = ruleSearch?.updateTime |
||||||
|
searchRule.infoUrl = ruleSearch?.bookUrl |
||||||
|
searchRule.imgUrl = ruleSearch?.coverUrl |
||||||
|
searchRule.wordCount = ruleSearch?.wordCount |
||||||
|
searchRule.isRelatedWithInfo = true |
||||||
|
bookSource.searchRule = searchRule |
||||||
|
|
||||||
|
val infoRule = InfoRule() |
||||||
|
val ruleInfo = bean.ruleBookInfo |
||||||
|
infoRule.urlPattern = bean.bookUrlPattern |
||||||
|
infoRule.init = ruleInfo?.init |
||||||
|
infoRule.name = ruleInfo?.name |
||||||
|
infoRule.author = ruleInfo?.author |
||||||
|
infoRule.desc = ruleInfo?.intro |
||||||
|
infoRule.type = ruleInfo?.kind |
||||||
|
infoRule.lastChapter = ruleInfo?.lastChapter |
||||||
|
infoRule.updateTime = ruleInfo?.updateTime |
||||||
|
infoRule.imgUrl = ruleInfo?.coverUrl |
||||||
|
infoRule.tocUrl = ruleInfo?.tocUrl |
||||||
|
infoRule.wordCount = ruleInfo?.wordCount |
||||||
|
bookSource.infoRule = infoRule |
||||||
|
|
||||||
|
val tocRule = TocRule() |
||||||
|
val ruleToc = bean.ruleToc |
||||||
|
tocRule.chapterList = ruleToc?.chapterList |
||||||
|
tocRule.chapterName = ruleToc?.chapterName |
||||||
|
tocRule.chapterUrl = ruleToc?.chapterUrl |
||||||
|
tocRule.isVip = ruleToc?.isVip |
||||||
|
tocRule.isPay = ruleToc?.isPay |
||||||
|
tocRule.updateTime = ruleToc?.updateTime |
||||||
|
tocRule.tocUrlNext = ruleToc?.nextTocUrl |
||||||
|
bookSource.tocRule = tocRule |
||||||
|
|
||||||
|
val contentRule = ContentRule() |
||||||
|
val ruleContent = bean.ruleContent |
||||||
|
contentRule.content = ruleContent?.content |
||||||
|
contentRule.contentUrlNext = ruleContent?.nextContentUrl |
||||||
|
contentRule.replaceRegex = ruleContent?.replaceRegex |
||||||
|
bookSource.contentRule = contentRule |
||||||
|
|
||||||
|
val findRule = FindRule() |
||||||
|
val ruleFind = bean.ruleExplore |
||||||
|
findRule.url = bean.exploreUrl |
||||||
|
findRule.list = ruleFind?.bookList |
||||||
|
findRule.name = ruleFind?.name |
||||||
|
findRule.author = ruleFind?.author |
||||||
|
findRule.desc = ruleFind?.intro |
||||||
|
findRule.type = ruleFind?.kind |
||||||
|
findRule.lastChapter = ruleFind?.lastChapter |
||||||
|
findRule.updateTime = ruleFind?.updateTime |
||||||
|
findRule.imgUrl = ruleFind?.coverUrl |
||||||
|
findRule.infoUrl = ruleFind?.bookUrl |
||||||
|
findRule.wordCount = ruleFind?.wordCount |
||||||
|
bookSource.findRule = findRule |
||||||
|
return bookSource |
||||||
|
} |
||||||
|
|
||||||
|
fun source3sToSources(source3s: List<Source3>): List<BookSource> { |
||||||
|
val sources = mutableListOf<BookSource>() |
||||||
|
source3s.forEach { |
||||||
|
sources.add(source3ToSource(it)) |
||||||
|
} |
||||||
|
return sources |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package xyz.fycz.myreader.entity.thirdsource.source3 |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2022/1/20 13:50 |
||||||
|
*/ |
||||||
|
data class TocRule3( |
||||||
|
var chapterList: String? = null, |
||||||
|
var chapterName: String? = null, |
||||||
|
var chapterUrl: String? = null, |
||||||
|
var isVip: String? = null, |
||||||
|
var isPay: String? = null, |
||||||
|
var updateTime: String? = null, |
||||||
|
var nextTocUrl: String? = null |
||||||
|
) |
@ -0,0 +1,8 @@ |
|||||||
|
package xyz.fycz.myreader.model.third3 |
||||||
|
|
||||||
|
object BookType { |
||||||
|
const val default = 0 // 0 文本 |
||||||
|
const val audio = 1 // 1 音频 |
||||||
|
const val image = 3 //图片 |
||||||
|
const val local = "loc_book" |
||||||
|
} |
@ -0,0 +1,318 @@ |
|||||||
|
package xyz.fycz.myreader.model.third3 |
||||||
|
|
||||||
|
import android.util.Log |
||||||
|
import androidx.annotation.Keep |
||||||
|
import com.jayway.jsonpath.JsonPath |
||||||
|
import xyz.fycz.myreader.common.APPCONST |
||||||
|
import xyz.fycz.myreader.entity.thirdsource.source3.* |
||||||
|
import xyz.fycz.myreader.util.utils.* |
||||||
|
import java.util.regex.Pattern |
||||||
|
|
||||||
|
@Suppress("RegExpRedundantEscape") |
||||||
|
object SourceAnalyzer { |
||||||
|
private val headerPattern = Pattern.compile("@Header:\\{.+?\\}", Pattern.CASE_INSENSITIVE) |
||||||
|
private val jsPattern = Pattern.compile("\\{\\{.+?\\}\\}", Pattern.CASE_INSENSITIVE) |
||||||
|
|
||||||
|
fun jsonToBookSources(json: String): List<Source3> { |
||||||
|
val bookSources = mutableListOf<Source3>() |
||||||
|
val items: List<Map<String, Any>> = jsonPath.parse(json).read("$") |
||||||
|
for (item in items) { |
||||||
|
val jsonItem = jsonPath.parse(item) |
||||||
|
jsonToBookSource(jsonItem.jsonString())?.let { |
||||||
|
bookSources.add(it) |
||||||
|
} |
||||||
|
} |
||||||
|
return bookSources |
||||||
|
} |
||||||
|
|
||||||
|
fun jsonToBookSource(json: String): Source3? { |
||||||
|
val source = Source3() |
||||||
|
val sourceAny = try { |
||||||
|
GSON.fromJsonObject<BookSourceAny>(json.trim()) |
||||||
|
} catch (e: Exception) { |
||||||
|
null |
||||||
|
} |
||||||
|
try { |
||||||
|
if (sourceAny?.ruleToc == null) { |
||||||
|
source.apply { |
||||||
|
val jsonItem = jsonPath.parse(json.trim()) |
||||||
|
bookSourceUrl = jsonItem.readString("bookSourceUrl") ?: return null |
||||||
|
bookSourceName = jsonItem.readString("bookSourceName") ?: "" |
||||||
|
bookSourceGroup = jsonItem.readString("bookSourceGroup") |
||||||
|
loginUrl = jsonItem.readString("loginUrl") |
||||||
|
loginUi = jsonItem.readString("loginUi") |
||||||
|
loginCheckJs = jsonItem.readString("loginCheckJs") |
||||||
|
bookSourceComment = jsonItem.readString("bookSourceComment") ?: "" |
||||||
|
bookUrlPattern = jsonItem.readString("ruleBookUrlPattern") |
||||||
|
customOrder = jsonItem.readInt("serialNumber") ?: 0 |
||||||
|
header = uaToHeader(jsonItem.readString("httpUserAgent")) |
||||||
|
searchUrl = toNewUrl(jsonItem.readString("ruleSearchUrl")) |
||||||
|
exploreUrl = toNewUrls(jsonItem.readString("ruleFindUrl")) |
||||||
|
bookSourceType = |
||||||
|
if (jsonItem.readString("bookSourceType") == "AUDIO") BookType.audio else BookType.default |
||||||
|
enabled = jsonItem.readBool("enable") ?: true |
||||||
|
if (exploreUrl.isNullOrBlank()) { |
||||||
|
enabledExplore = false |
||||||
|
} |
||||||
|
ruleSearch = SearchRule3( |
||||||
|
bookList = toNewRule(jsonItem.readString("ruleSearchList")), |
||||||
|
name = toNewRule(jsonItem.readString("ruleSearchName")), |
||||||
|
author = toNewRule(jsonItem.readString("ruleSearchAuthor")), |
||||||
|
intro = toNewRule(jsonItem.readString("ruleSearchIntroduce")), |
||||||
|
kind = toNewRule(jsonItem.readString("ruleSearchKind")), |
||||||
|
bookUrl = toNewRule(jsonItem.readString("ruleSearchNoteUrl")), |
||||||
|
coverUrl = toNewRule(jsonItem.readString("ruleSearchCoverUrl")), |
||||||
|
lastChapter = toNewRule(jsonItem.readString("ruleSearchLastChapter")) |
||||||
|
) |
||||||
|
ruleExplore = ExploreRule3( |
||||||
|
bookList = toNewRule(jsonItem.readString("ruleFindList")), |
||||||
|
name = toNewRule(jsonItem.readString("ruleFindName")), |
||||||
|
author = toNewRule(jsonItem.readString("ruleFindAuthor")), |
||||||
|
intro = toNewRule(jsonItem.readString("ruleFindIntroduce")), |
||||||
|
kind = toNewRule(jsonItem.readString("ruleFindKind")), |
||||||
|
bookUrl = toNewRule(jsonItem.readString("ruleFindNoteUrl")), |
||||||
|
coverUrl = toNewRule(jsonItem.readString("ruleFindCoverUrl")), |
||||||
|
lastChapter = toNewRule(jsonItem.readString("ruleFindLastChapter")) |
||||||
|
) |
||||||
|
ruleBookInfo = BookInfoRule3( |
||||||
|
init = toNewRule(jsonItem.readString("ruleBookInfoInit")), |
||||||
|
name = toNewRule(jsonItem.readString("ruleBookName")), |
||||||
|
author = toNewRule(jsonItem.readString("ruleBookAuthor")), |
||||||
|
intro = toNewRule(jsonItem.readString("ruleIntroduce")), |
||||||
|
kind = toNewRule(jsonItem.readString("ruleBookKind")), |
||||||
|
coverUrl = toNewRule(jsonItem.readString("ruleCoverUrl")), |
||||||
|
lastChapter = toNewRule(jsonItem.readString("ruleBookLastChapter")), |
||||||
|
tocUrl = toNewRule(jsonItem.readString("ruleChapterUrl")) |
||||||
|
) |
||||||
|
ruleToc = TocRule3( |
||||||
|
chapterList = toNewRule(jsonItem.readString("ruleChapterList")), |
||||||
|
chapterName = toNewRule(jsonItem.readString("ruleChapterName")), |
||||||
|
chapterUrl = toNewRule(jsonItem.readString("ruleContentUrl")), |
||||||
|
nextTocUrl = toNewRule(jsonItem.readString("ruleChapterUrlNext")) |
||||||
|
) |
||||||
|
var content = toNewRule(jsonItem.readString("ruleBookContent")) ?: "" |
||||||
|
if (content.startsWith("$") && !content.startsWith("$.")) { |
||||||
|
content = content.substring(1) |
||||||
|
} |
||||||
|
ruleContent = ContentRule3( |
||||||
|
content = content, |
||||||
|
replaceRegex = toNewRule(jsonItem.readString("ruleBookContentReplace")), |
||||||
|
nextContentUrl = toNewRule(jsonItem.readString("ruleContentUrlNext")) |
||||||
|
) |
||||||
|
} |
||||||
|
} else { |
||||||
|
source.bookSourceUrl = sourceAny.bookSourceUrl |
||||||
|
source.bookSourceName = sourceAny.bookSourceName |
||||||
|
source.bookSourceGroup = sourceAny.bookSourceGroup |
||||||
|
source.bookSourceType = sourceAny.bookSourceType |
||||||
|
source.bookUrlPattern = sourceAny.bookUrlPattern |
||||||
|
source.customOrder = sourceAny.customOrder |
||||||
|
source.enabled = sourceAny.enabled |
||||||
|
source.enabledExplore = sourceAny.enabledExplore |
||||||
|
source.concurrentRate = sourceAny.concurrentRate |
||||||
|
source.header = sourceAny.header |
||||||
|
source.loginUrl = when (sourceAny.loginUrl) { |
||||||
|
null -> null |
||||||
|
is String -> sourceAny.loginUrl.toString() |
||||||
|
else -> JsonPath.parse(sourceAny.loginUrl).readString("url") |
||||||
|
} |
||||||
|
source.loginUi = if (sourceAny.loginUi is List<*>) { |
||||||
|
GSON.toJson(sourceAny.loginUi) |
||||||
|
} else { |
||||||
|
sourceAny.loginUi?.toString() |
||||||
|
} |
||||||
|
source.loginCheckJs = sourceAny.loginCheckJs |
||||||
|
source.bookSourceComment = sourceAny.bookSourceComment |
||||||
|
source.lastUpdateTime = sourceAny.lastUpdateTime |
||||||
|
source.respondTime = sourceAny.respondTime |
||||||
|
source.weight = sourceAny.weight |
||||||
|
source.exploreUrl = sourceAny.exploreUrl |
||||||
|
source.ruleExplore = if (sourceAny.ruleExplore is String) { |
||||||
|
GSON.fromJsonObject(sourceAny.ruleExplore.toString()) |
||||||
|
} else { |
||||||
|
GSON.fromJsonObject(GSON.toJson(sourceAny.ruleExplore)) |
||||||
|
} |
||||||
|
source.searchUrl = sourceAny.searchUrl |
||||||
|
source.ruleSearch = if (sourceAny.ruleSearch is String) { |
||||||
|
GSON.fromJsonObject(sourceAny.ruleSearch.toString()) |
||||||
|
} else { |
||||||
|
GSON.fromJsonObject(GSON.toJson(sourceAny.ruleSearch)) |
||||||
|
} |
||||||
|
source.ruleBookInfo = if (sourceAny.ruleBookInfo is String) { |
||||||
|
GSON.fromJsonObject(sourceAny.ruleBookInfo.toString()) |
||||||
|
} else { |
||||||
|
GSON.fromJsonObject(GSON.toJson(sourceAny.ruleBookInfo)) |
||||||
|
} |
||||||
|
source.ruleToc = if (sourceAny.ruleToc is String) { |
||||||
|
GSON.fromJsonObject(sourceAny.ruleToc.toString()) |
||||||
|
} else { |
||||||
|
GSON.fromJsonObject(GSON.toJson(sourceAny.ruleToc)) |
||||||
|
} |
||||||
|
source.ruleContent = if (sourceAny.ruleContent is String) { |
||||||
|
GSON.fromJsonObject(sourceAny.ruleContent.toString()) |
||||||
|
} else { |
||||||
|
GSON.fromJsonObject(GSON.toJson(sourceAny.ruleContent)) |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (e: Exception) { |
||||||
|
Log.e("SourceAnalyzer", "" + e.localizedMessage) |
||||||
|
} |
||||||
|
return source |
||||||
|
} |
||||||
|
|
||||||
|
@Keep |
||||||
|
data class BookSourceAny( |
||||||
|
var bookSourceName: String = "", // 名称 |
||||||
|
var bookSourceGroup: String? = null, // 分组 |
||||||
|
var bookSourceUrl: String = "", // 地址,包括 http/https |
||||||
|
var bookSourceType: Int = BookType.default, // 类型,0 文本,1 音频 |
||||||
|
var bookUrlPattern: String? = null, // 详情页url正则 |
||||||
|
var customOrder: Int = 0, // 手动排序编号 |
||||||
|
var enabled: Boolean = true, // 是否启用 |
||||||
|
var enabledExplore: Boolean = true, // 启用发现 |
||||||
|
var concurrentRate: String? = null, // 并发率 |
||||||
|
var header: String? = null, // 请求头 |
||||||
|
var loginUrl: Any? = null, // 登录规则 |
||||||
|
var loginUi: Any? = null, // 登录UI |
||||||
|
var loginCheckJs: String? = null, //登录检测js |
||||||
|
var bookSourceComment: String? = "", //书源注释 |
||||||
|
var lastUpdateTime: Long = 0, // 最后更新时间,用于排序 |
||||||
|
var respondTime: Long = 180000L, // 响应时间,用于排序 |
||||||
|
var weight: Int = 0, // 智能排序的权重 |
||||||
|
var exploreUrl: String? = null, // 发现url |
||||||
|
var ruleExplore: Any? = null, // 发现规则 |
||||||
|
var searchUrl: String? = null, // 搜索url |
||||||
|
var ruleSearch: Any? = null, // 搜索规则 |
||||||
|
var ruleBookInfo: Any? = null, // 书籍信息页规则 |
||||||
|
var ruleToc: Any? = null, // 目录页规则 |
||||||
|
var ruleContent: Any? = null // 正文页规则 |
||||||
|
) |
||||||
|
|
||||||
|
// default规则适配 |
||||||
|
// #正则#替换内容 替换成 ##正则##替换内容 |
||||||
|
// | 替换成 || |
||||||
|
// & 替换成 && |
||||||
|
private fun toNewRule(oldRule: String?): String? { |
||||||
|
if (oldRule.isNullOrBlank()) return null |
||||||
|
var newRule = oldRule |
||||||
|
var reverse = false |
||||||
|
var allinone = false |
||||||
|
if (oldRule.startsWith("-")) { |
||||||
|
reverse = true |
||||||
|
newRule = oldRule.substring(1) |
||||||
|
} |
||||||
|
if (newRule.startsWith("+")) { |
||||||
|
allinone = true |
||||||
|
newRule = newRule.substring(1) |
||||||
|
} |
||||||
|
if (!newRule.startsWith("@CSS:", true) && |
||||||
|
!newRule.startsWith("@XPath:", true) && |
||||||
|
!newRule.startsWith("//") && |
||||||
|
!newRule.startsWith("##") && |
||||||
|
!newRule.startsWith(":") && |
||||||
|
!newRule.contains("@js:", true) && |
||||||
|
!newRule.contains("<js>", true) |
||||||
|
) { |
||||||
|
if (newRule.contains("#") && !newRule.contains("##")) { |
||||||
|
newRule = oldRule.replace("#", "##") |
||||||
|
} |
||||||
|
if (newRule.contains("|") && !newRule.contains("||")) { |
||||||
|
if (newRule.contains("##")) { |
||||||
|
val list = newRule.split("##") |
||||||
|
if (list[0].contains("|")) { |
||||||
|
newRule = list[0].replace("|", "||") |
||||||
|
for (i in 1 until list.size) { |
||||||
|
newRule += "##" + list[i] |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
newRule = newRule.replace("|", "||") |
||||||
|
} |
||||||
|
} |
||||||
|
if (newRule.contains("&") |
||||||
|
&& !newRule.contains("&&") |
||||||
|
&& !newRule.contains("http") |
||||||
|
&& !newRule.startsWith("/") |
||||||
|
) { |
||||||
|
newRule = newRule.replace("&", "&&") |
||||||
|
} |
||||||
|
} |
||||||
|
if (allinone) { |
||||||
|
newRule = "+$newRule" |
||||||
|
} |
||||||
|
if (reverse) { |
||||||
|
newRule = "-$newRule" |
||||||
|
} |
||||||
|
return newRule |
||||||
|
} |
||||||
|
|
||||||
|
private fun toNewUrls(oldUrls: String?): String? { |
||||||
|
if (oldUrls.isNullOrBlank()) return null |
||||||
|
if (oldUrls.startsWith("@js:") || oldUrls.startsWith("<js>")) { |
||||||
|
return oldUrls |
||||||
|
} |
||||||
|
if (!oldUrls.contains("\n") && !oldUrls.contains("&&")) { |
||||||
|
return toNewUrl(oldUrls) |
||||||
|
} |
||||||
|
val urls = oldUrls.split("(&&|\r?\n)+".toRegex()) |
||||||
|
return urls.map { |
||||||
|
toNewUrl(it)?.replace("\n\\s*".toRegex(), "") |
||||||
|
}.joinToString("\n") |
||||||
|
} |
||||||
|
|
||||||
|
private fun toNewUrl(oldUrl: String?): String? { |
||||||
|
if (oldUrl.isNullOrBlank()) return null |
||||||
|
var url: String = oldUrl |
||||||
|
if (oldUrl.startsWith("<js>", true)) { |
||||||
|
url = url.replace("=searchKey", "={{key}}") |
||||||
|
.replace("=searchPage", "={{page}}") |
||||||
|
return url |
||||||
|
} |
||||||
|
val map = HashMap<String, String>() |
||||||
|
var mather = headerPattern.matcher(url) |
||||||
|
if (mather.find()) { |
||||||
|
val header = mather.group() |
||||||
|
url = url.replace(header, "") |
||||||
|
map["headers"] = header.substring(8) |
||||||
|
} |
||||||
|
var urlList = url.split("|") |
||||||
|
url = urlList[0] |
||||||
|
if (urlList.size > 1) { |
||||||
|
map["charset"] = urlList[1].split("=")[1] |
||||||
|
} |
||||||
|
mather = jsPattern.matcher(url) |
||||||
|
val jsList = arrayListOf<String>() |
||||||
|
while (mather.find()) { |
||||||
|
jsList.add(mather.group()) |
||||||
|
url = url.replace(jsList.last(), "$${jsList.size - 1}") |
||||||
|
} |
||||||
|
url = url.replace("{", "<").replace("}", ">") |
||||||
|
url = url.replace("searchKey", "{{key}}") |
||||||
|
url = url.replace("<searchPage([-+]1)>".toRegex(), "{{page$1}}") |
||||||
|
.replace("searchPage([-+]1)".toRegex(), "{{page$1}}") |
||||||
|
.replace("searchPage", "{{page}}") |
||||||
|
for ((index, item) in jsList.withIndex()) { |
||||||
|
url = url.replace( |
||||||
|
"$$index", |
||||||
|
item.replace("searchKey", "key").replace("searchPage", "page") |
||||||
|
) |
||||||
|
} |
||||||
|
urlList = url.split("@") |
||||||
|
url = urlList[0] |
||||||
|
if (urlList.size > 1) { |
||||||
|
map["method"] = "POST" |
||||||
|
map["body"] = urlList[1] |
||||||
|
} |
||||||
|
if (map.size > 0) { |
||||||
|
url += "," + GSON.toJson(map) |
||||||
|
} |
||||||
|
return url |
||||||
|
} |
||||||
|
|
||||||
|
private fun uaToHeader(ua: String?): String? { |
||||||
|
if (ua.isNullOrEmpty()) return null |
||||||
|
val map = mapOf(Pair(APPCONST.UA_NAME, ua)) |
||||||
|
return GSON.toJson(map) |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package xyz.fycz.myreader.util.utils |
||||||
|
|
||||||
|
import com.jayway.jsonpath.* |
||||||
|
|
||||||
|
val jsonPath: ParseContext by lazy { |
||||||
|
JsonPath.using( |
||||||
|
Configuration.builder() |
||||||
|
.options(Option.SUPPRESS_EXCEPTIONS) |
||||||
|
.build() |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
fun ReadContext.readString(path: String): String? = this.read(path, String::class.java) |
||||||
|
|
||||||
|
fun ReadContext.readBool(path: String): Boolean? = this.read(path, Boolean::class.java) |
||||||
|
|
||||||
|
fun ReadContext.readInt(path: String): Int? = this.read(path, Int::class.java) |
||||||
|
|
||||||
|
fun ReadContext.readLong(path: String): Long? = this.read(path, Long::class.java) |
||||||
|
|
Loading…
Reference in new issue