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