Remove named capture groups from most extensions (#7328)

* remove named capture group (simple)

* remove named capture group (spot checks)
This commit is contained in:
Vetle Ledaal 2025-01-26 13:45:37 +01:00 committed by Draff
parent 07c6de7cf6
commit c15852943e
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
38 changed files with 71 additions and 71 deletions

View File

@ -2,7 +2,7 @@ plugins {
id("lib-multisrc")
}
baseVersionCode = 5
baseVersionCode = 6
dependencies {
api(project(":lib:synchrony"))

View File

@ -276,14 +276,14 @@ abstract class ColaManga(
}.also(screen::addPreference)
}
private val keyMappingRegex = Regex("""if\s*\(\s*([a-zA-Z0-9_]+)\s*==\s*(?<keyType>\d+)\s*\)\s*\{\s*return\s*'(?<key>[a-zA-Z0-9_]+)'\s*;""")
private val keyMappingRegex = Regex("""if\s*\(\s*([a-zA-Z0-9_]+)\s*==\s*(\d+)\s*\)\s*\{\s*return\s*'([a-zA-Z0-9_]+)'\s*;""")
private val keyMapping by lazy {
val obfuscatedReadJs = client.newCall(GET("$baseUrl/js/manga.read.js")).execute().body.string()
val readJs = Deobfuscator.deobfuscateScript(obfuscatedReadJs)
?: throw Exception(intl.couldNotDeobufscateScript)
keyMappingRegex.findAll(readJs).associate { it.groups["keyType"]!!.value to it.groups["key"]!!.value }
keyMappingRegex.findAll(readJs).associate { it.groups[1]!!.value to it.groups[2]!!.value }
}
private fun randomString() = buildString(15) {

View File

@ -2,7 +2,7 @@ plugins {
id("lib-multisrc")
}
baseVersionCode = 12
baseVersionCode = 13
dependencies {
api(project(":lib:i18n"))

View File

@ -290,7 +290,7 @@ abstract class Keyoapp(
.firstOrNull { CDN_HOST_REGEX.containsMatchIn(it.html()) }
?.let {
val cdnHost = CDN_HOST_REGEX.find(it.html())
?.groups?.get("host")?.value
?.groups?.get(1)?.value
?.replace(CDN_CLEAN_REGEX, "")
"https://$cdnHost/uploads"
}
@ -314,7 +314,7 @@ abstract class Keyoapp(
protected open fun Element.getImageUrl(selector: String): String? {
return this.selectFirst(selector)?.let { element ->
IMG_REGEX.find(element.attr("style"))?.groups?.get("url")?.value
IMG_REGEX.find(element.attr("style"))?.groups?.get(1)?.value
?.toHttpUrlOrNull()?.let {
it.newBuilder()
.setQueryParameter("w", "480") // Keyoapp returns the dynamic size of the thumbnail to any size
@ -376,8 +376,8 @@ abstract class Keyoapp(
companion object {
private const val SHOW_PAID_CHAPTERS_PREF = "pref_show_paid_chap"
private const val SHOW_PAID_CHAPTERS_DEFAULT = false
val CDN_HOST_REGEX = """realUrl\s*=\s*`[^`]+//(?<host>[^/]+)""".toRegex()
val CDN_HOST_REGEX = """realUrl\s*=\s*`[^`]+//([^/]+)""".toRegex()
val CDN_CLEAN_REGEX = """\$\{[^}]*\}""".toRegex()
val IMG_REGEX = """url\(['"]?(?<url>[^(['"\)])]+)""".toRegex()
val IMG_REGEX = """url\(['"]?([^(['"\)])]+)""".toRegex()
}
}

View File

@ -2,4 +2,4 @@ plugins {
id("lib-multisrc")
}
baseVersionCode = 3
baseVersionCode = 4

View File

@ -267,7 +267,7 @@ abstract class SlimeReadTheme(
companion object {
const val PREFIX_SEARCH = "id:"
val FUNCTION_REGEX = """(?<script>\[""\.concat\("[^,]+,"\."\)\.concat\((?<infix>[^,]+),":\d+"\)\])""".toRegex(RegexOption.DOT_MATCHES_ALL)
val FUNCTION_REGEX = """(\[""\.concat\("[^,]+,"\."\)\.concat\(([^,]+),":\d+"\)\])""".toRegex(RegexOption.DOT_MATCHES_ALL)
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ROOT)
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Little Garden'
extClass = '.LittleGarden'
extVersionCode = 2
extVersionCode = 3
}
apply from: "$rootDir/common.gradle"

View File

@ -31,7 +31,7 @@ class LittleGarden : ParsedHttpSource() {
private const val cdnUrl = "https://littlexgarden.com/static/images/webp/"
private val JSON_MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
private val slugRegex = Regex("\\\\\"slug\\\\\":\\\\\"(.*?(?=\\\\\"))")
private val oricolPageRegex = Regex("\\{colored:(?<colored>.*?(?=,)),original:(?<original>.*?(?=,))")
private val oricolPageRegex = Regex("\\{colored:(.*?(?=,)),original:(.*?(?=,))")
private val oriPageRegex = Regex("""original:"(.*?(?="))""")
}
@ -176,10 +176,10 @@ class LittleGarden : ParsedHttpSource() {
val engChaps: IntArray = intArrayOf(970, 987, 992)
if (document.selectFirst("div.manga-name")!!.text().trim() == "One Piece" && (engChaps.contains(chapNb) || chapNb > 1004)) { // Permits to get French pages rather than English pages for some chapters
oricolPageRegex.findAll(document.select("script:containsData(pages)").toString()).asIterable().mapIndexed { i, it ->
if (it.groups["colored"]?.value?.contains("\"") == true) { // Their JS dict has " " around the link only when available. Also uses colored pages rather than B&W as it's the main strength of this site
pages.add(Page(i, "", cdnUrl + it.groups["colored"]?.value?.replace("\"", "") + ".webp"))
if (it.groups[1]?.value?.contains("\"") == true) { // Their JS dict has " " around the link only when available. Also uses colored pages rather than B&W as it's the main strength of this site
pages.add(Page(i, "", cdnUrl + it.groups[1]?.value?.replace("\"", "") + ".webp"))
} else {
pages.add(Page(i, "", cdnUrl + it.groups["original"]?.value?.replace("\"", "") + ".webp"))
pages.add(Page(i, "", cdnUrl + it.groups[2]?.value?.replace("\"", "") + ".webp"))
}
}
} else {

View File

@ -3,7 +3,7 @@ ext {
extClass = '.SnowmtlFactory'
themePkg = 'machinetranslations'
baseUrl = 'https://snowmtl.ru'
overrideVersionCode = 6
overrideVersionCode = 7
isNsfw = true
}

View File

@ -97,9 +97,9 @@ class BingTranslator(private val client: OkHttpClient, private val headers: Head
val matchTwo = IG_PARAM_REGEX.find(scriptTwo)?.groups
return TokenGroup(
token = matchOne?.get("token")?.value ?: "",
key = matchOne?.get("key")?.value ?: "",
ig = matchTwo?.get("ig")?.value ?: "",
token = matchOne?.get(2)?.value ?: "",
key = matchOne?.get(1)?.value ?: "",
ig = matchTwo?.get(1)?.value ?: "",
iid = document.selectFirst("div[data-iid]:not([class])")?.attr("data-iid") ?: "",
)
}
@ -109,8 +109,8 @@ class BingTranslator(private val client: OkHttpClient, private val headers: Head
}
companion object {
val TOKENS_REGEX = """params_AbusePreventionHelper(\s+)?=(\s+)?[^\[]\[(?<key>\d+),"(?<token>[^"]+)""".toRegex()
val IG_PARAM_REGEX = """IG:"(?<ig>[^"]+)""".toRegex()
val TOKENS_REGEX = """params_AbusePreventionHelper(\s+)?=(\s+)?[^\[]\[(\d+),"([^"]+)""".toRegex()
val IG_PARAM_REGEX = """IG:"([^"]+)""".toRegex()
const val MAX_CHARS_ALLOW = 1000
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Hachi'
extClass = '.Hachi'
extVersionCode = 1
extVersionCode = 2
isNsfw = true
}

View File

@ -170,7 +170,7 @@ class Hachi : HttpSource() {
// Details
override fun mangaDetailsRequest(manga: SManga): Request {
val slug = patternMangaUrl.find(manga.url)?.groups?.get("slug")?.value
val slug = patternMangaUrl.find(manga.url)?.groups?.get(1)?.value
?: throw Exception("Failed to find manga from URL")
val url = "$baseUrl/_next/data/$buildId/article/$slug.json".toHttpUrl().newBuilder()
@ -226,8 +226,8 @@ class Hachi : HttpSource() {
// Pages
override fun pageListRequest(chapter: SChapter): Request {
val matchGroups = patternMangaUrl.find(chapter.url)!!.groups
val slug = matchGroups["slug"]!!.value
val number = matchGroups["number"]!!.value
val slug = matchGroups[1]!!.value
val number = matchGroups[2]!!.value
val url = "$baseUrl/_next/data/$buildId/article/$slug/chapter/$number.json".toHttpUrl()
.newBuilder()
@ -289,7 +289,7 @@ class Hachi : HttpSource() {
}
private val patternMangaUrl =
"""/article/(?<slug>[^/]+)(?:/chapter/(?<number>[^/?&#]+))?""".toRegex()
"""/article/([^/]+)(?:/chapter/([^/?&#]+))?""".toRegex()
const val SEARCH_PREFIX = "slug:"
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'I Roved Out'
extClass = '.IRovedOut'
extVersionCode = 4
extVersionCode = 5
isNsfw = true
}

View File

@ -30,7 +30,7 @@ class IRovedOut : HttpSource() {
It updates in chunks anywhere between 3 and 30 pages long at least once a month.
""".trimIndent()
private val dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US)
private val titleRegex = Regex("Book (?<bookNumber>\\d+): (?<chapterTitle>.+)")
private val titleRegex = Regex("Book (\\d+): (?.+)")
override fun chapterListRequest(manga: SManga): Request = throw UnsupportedOperationException()
@ -79,8 +79,8 @@ class IRovedOut : HttpSource() {
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
val match = titleRegex.matchEntire(chapter.name) ?: return Observable.just(listOf())
val bookNumber = match.groups["bookNumber"]!!.value.toInt()
val title = match.groups["chapterTitle"]!!.value
val bookNumber = match.groups[1]!!.value.toInt()
val title = match.groups[2]!!.value
val bookPage = client.newCall(GET(archiveUrl + if (bookNumber != 1) "-book-$bookNumber" else "", headers)).execute().asJsoup()
val chapterWrap = bookPage.select(".comic-archive-chapter-wrap").find { it.selectFirst(".comic-archive-chapter")!!.text() == title }
val pageUrls = chapterWrap?.select(".comic-archive-list-wrap .comic-archive-title > a")?.map { it.attr("href") } ?: return Observable.just(listOf())

View File

@ -1,7 +1,7 @@
ext {
extName = 'Rolia Scan'
extClass = '.RoliaScan'
extVersionCode = 1
extVersionCode = 2
}
apply from: "$rootDir/common.gradle"

View File

@ -282,7 +282,7 @@ class RoliaScan : ParsedHttpSource() {
}
private fun getOptionList(pattern: Regex, content: String, cssQuery: String = "option"): List<Option> {
val query = pattern.find(content)?.groups?.get("query")?.value ?: return emptyList()
val query = pattern.find(content)?.groups?.get(1)?.value ?: return emptyList()
return content.getDocumentFragmentFilter(pattern)
?.select(cssQuery)
?.map { element ->
@ -295,13 +295,13 @@ class RoliaScan : ParsedHttpSource() {
}
private fun String.getDocumentFragmentFilter(pattern: Regex): Document? {
return pattern.find(this)?.groups?.get("value")?.value?.let {
return pattern.find(this)?.groups?.get(2)?.value?.let {
val fragment = json.decodeFromString<String>(it)
Jsoup.parseBodyFragment(fragment)
}
}
private fun buildRegex(field: String) = """"(?<query>$field)":(?<value>"<[^,]+)""".toRegex()
private fun buildRegex(field: String) = """"($field)":("<[^,]+)""".toRegex()
private data class Option(val name: String = "", val value: String = "", val query: String = "")

View File

@ -1,7 +1,7 @@
ext {
extName = 'Webcomics'
extClass = '.Webcomics'
extVersionCode = 4
extVersionCode = 5
}
apply from: "$rootDir/common.gradle"

View File

@ -164,7 +164,7 @@ class Webcomics : ParsedHttpSource(), ConfigurableSource {
?: throw Exception("You may need to log in")
return PAGE_REGEX.findAll(script.data()).mapIndexed { index, match ->
Page(index, imageUrl = match.groups["img"]!!.value.unicode())
Page(index, imageUrl = match.groups[1]!!.value.unicode())
}.toList()
}
@ -227,7 +227,7 @@ class Webcomics : ParsedHttpSource(), ConfigurableSource {
}
companion object {
val PAGE_REGEX = """src:(\s+)?"(?<img>[^"]+)""".toRegex()
val PAGE_REGEX = """src:(\s+)?"([^"]+)""".toRegex()
val WHITE_SPACE_REGEX = """[\s]+""".toRegex()
val PUNCTUATION_REGEX = "[\\p{Punct}]".toRegex()
val UNICODE_REGEX = "\\\\u([0-9A-Fa-f]{4})|\\\\U([0-9A-Fa-f]{8})".toRegex()

View File

@ -1,7 +1,7 @@
ext {
extName = 'Plot Twist No Fansub'
extClass = '.PlotTwistNoFansub'
extVersionCode = 7
extVersionCode = 8
isNsfw = true
}

View File

@ -191,7 +191,7 @@ class PlotTwistNoFansub : ParsedHttpSource(), ConfigurableSource {
val script = document.select("script")
.map(Element::data)
.firstNotNullOf(CHAPTER_PAGES_REGEX::find)
val result = json.decodeFromString<PagesPayloadDto>(script.groups["json"]!!.value)
val result = json.decodeFromString<PagesPayloadDto>(script.groups[1]!!.value)
val mangaSlug = "${result.cdnUrl}/${result.mangaSlug}"
val chapterNumber = result.chapterNumber
return result.images.mapIndexed { i, img ->
@ -260,7 +260,7 @@ class PlotTwistNoFansub : ParsedHttpSource(), ConfigurableSource {
companion object {
private val MANGAID1_REGEX = ""","manid":"(\d+)",""".toRegex()
private val UNESCAPE_REGEX = """\\(.)""".toRegex()
private val CHAPTER_PAGES_REGEX = """obj\s*=\s*(?<json>.*)\s*;""".toRegex()
private val CHAPTER_PAGES_REGEX = """obj\s*=\s*(.*)\s*;""".toRegex()
private val ACTION_REGEX = """action:\s*?(['"])([^\r\n]+?)\1""".toRegex()
private const val MAX_MANGA_RESULTS = 1000
}

View File

@ -3,7 +3,7 @@ ext {
extClass = '.FRScan'
themePkg = 'madara'
baseUrl = 'https://fr-scan.com'
overrideVersionCode = 6
overrideVersionCode = 7
}
apply from: "$rootDir/common.gradle"

View File

@ -24,7 +24,7 @@ class FRScan : Madara("FR-Scan", "https://fr-scan.com", "fr", dateFormat = Simpl
val chapterPreloaded = document.selectFirst("#chapter_preloaded_images")
?: return super.pageListParse(document)
val content = CHAPTER_PAGES_REGEX.find(chapterPreloaded.data())?.groups?.get("pages")!!.value
val content = CHAPTER_PAGES_REGEX.find(chapterPreloaded.data())?.groups?.get(1)!!.value
val pages = json.decodeFromString<List<String>>(content)
return pages.mapIndexed { index, imageUrl ->
@ -33,6 +33,6 @@ class FRScan : Madara("FR-Scan", "https://fr-scan.com", "fr", dateFormat = Simpl
}
companion object {
val CHAPTER_PAGES_REGEX = """=\s+(?<pages>\[.+\])""".toRegex()
val CHAPTER_PAGES_REGEX = """=\s+(\[.+\])""".toRegex()
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Read Mangas'
extClass = '.ReadMangas'
extVersionCode = 36
extVersionCode = 37
}
apply from: "$rootDir/common.gradle"

View File

@ -253,7 +253,7 @@ class ReadMangas() : HttpSource() {
val document = response.asJsoup()
val scripts = document.select("script").joinToString("\n") { it.data() }
val pages = IMAGE_URL_REGEX.findAll(scripts).mapIndexed { index, match ->
Page(index, imageUrl = match.groups["imageUrl"]!!.value)
Page(index, imageUrl = match.groups[1]!!.value)
}.toList()
return pages
@ -294,7 +294,7 @@ class ReadMangas() : HttpSource() {
@SuppressLint("SimpleDateFormat")
companion object {
val IMAGE_URL_REGEX = """url\\":\\"(?<imageUrl>[^(\\")]+)""".toRegex()
val IMAGE_URL_REGEX = """url\\":\\"([^(\\")]+)""".toRegex()
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")

View File

@ -1,7 +1,7 @@
ext {
extName = 'Taiyō'
extClass = '.Taiyo'
extVersionCode = 4
extVersionCode = 5
isNsfw = true
}

View File

@ -214,7 +214,7 @@ class Taiyo : ParsedHttpSource() {
.build()
val chapters = client.newCall(GET(pageUrl, headers)).execute().let {
CHAPTER_REGEX.find(it.body.string())?.groups?.get("chapters")?.value
CHAPTER_REGEX.find(it.body.string())?.groups?.get(1)?.value
}
val parsed = json.decodeFromString<ChapterListDto>(chapters!!)
@ -320,7 +320,7 @@ class Taiyo : ParsedHttpSource() {
val script = getScriptContainingToken(scripts)
?: throw Exception("Não foi possivel localizar o token")
return TOKEN_REGEX.find(script)?.groups?.get("token")?.value
return TOKEN_REGEX.find(script)?.groups?.get(1)?.value
?: throw Exception("Não foi possivel extrair o token")
}
@ -339,8 +339,8 @@ class Taiyo : ParsedHttpSource() {
companion object {
const val PREFIX_SEARCH = "id:"
val CHAPTER_REGEX = """(?<chapters>\{"chapters".+"totalPages":\d+\})""".toRegex()
val TOKEN_REGEX = """NEXT_PUBLIC_MEILISEARCH_PUBLIC_KEY:(\s+)?"(?<token>[^"]+)""".toRegex()
val CHAPTER_REGEX = """(\{"chapters".+"totalPages":\d+\})""".toRegex()
val TOKEN_REGEX = """NEXT_PUBLIC_MEILISEARCH_PUBLIC_KEY:(\s+)?"([^"]+)""".toRegex()
const val BEARER_TOKEN_PREF = "TAIYO_BEARER_TOKEN"
private const val IMG_CDN = "https://cdn.taiyo.moe/medias"

View File

@ -3,7 +3,7 @@ ext {
extClass = '.TraducoesDoLipe'
themePkg = 'zeistmanga'
baseUrl = 'https://traducoesdolipe.blogspot.com'
overrideVersionCode = 0
overrideVersionCode = 1
}
apply from: "$rootDir/common.gradle"

View File

@ -40,7 +40,7 @@ class TraducoesDoLipe : ZeistManga(
override fun getChapterFeedUrl(doc: Document): String {
val feed = doc.select("script").map(Element::html)
.firstOrNull { script -> script.contains("catNameProject") }
?.let { script -> PROJECT_NAME_REGEX.find(script)?.groups?.get("project")?.value }
?.let { script -> PROJECT_NAME_REGEX.find(script)?.groups?.get(1)?.value }
?: throw Exception("Não foi possivel encontrar o nome do projeto")
return apiUrl(chapterCategory)
@ -52,7 +52,7 @@ class TraducoesDoLipe : ZeistManga(
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
val pages = document.selectFirst(".chapter script")!!.html().let {
val list = PAGES_REGEX.find(it)?.groups?.get("pages")?.value
val list = PAGES_REGEX.find(it)?.groups?.get(1)?.value
json.decodeFromString<List<String>>(list!!)
}
@ -62,7 +62,7 @@ class TraducoesDoLipe : ZeistManga(
}
companion object {
val PROJECT_NAME_REGEX = """=\s+?\('(?<project>[^']+)""".toRegex()
val PAGES_REGEX = """=(?<pages>\[[^]]+])""".toRegex()
val PROJECT_NAME_REGEX = """=\s+?\('([^']+)""".toRegex()
val PAGES_REGEX = """=(\[[^]]+])""".toRegex()
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Tsuki Mangás'
extClass = '.TsukiMangas'
extVersionCode = 6
extVersionCode = 7
isNsfw = true
}

View File

@ -316,7 +316,7 @@ class TsukiMangas : HttpSource() {
}
}
private val apiHeadersRegex = Regex("""headers\.common(?:\.(?<key>[0-9A-Za-z_]+)|\[['"](?<key2>[0-9A-Za-z-_]+)['"]])\s*=\s*['"](?<value>[a-zA-Z0-9_ :;.,\\/?!(){}\[\]@<>=\-+*#$&`|~^%]+)['"]""")
private val apiHeadersRegex = Regex("""headers\.common(?:\.([0-9A-Za-z_]+)|\[['"]([0-9A-Za-z-_]+)['"]])\s*=\s*['"]([a-zA-Z0-9_ :;.,\\/?!(){}\[\]@<>=\-+*#$&`|~^%]+)['"]""")
private val apiHeaders by lazy {
val document = client.newCall(GET(baseUrl, headers)).execute().asJsoup()
@ -325,7 +325,7 @@ class TsukiMangas : HttpSource() {
val matches = apiHeadersRegex.findAll(script)
matches.associate {
(it.groups["key"] ?: it.groups["key2"]!!).value to it.groups["value"]!!.value
(it.groups[1] ?: it.groups[2]!!).value to it.groups[3]!!.value
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Hattori Manga'
extClass = '.HattoriManga'
extVersionCode = 39
extVersionCode = 40
isNsfw = true
}

View File

@ -254,7 +254,7 @@ class HattoriManga : HttpSource() {
thumbnail_url = element.selectFirst(".img-con")?.absUrl("data-setbg")
genre = element.select(".product-card-con ul li").joinToString { it.text() }
val script = element.attr("onclick")
setUrlWithoutDomain(REGEX_MANGA_URL.find(script)!!.groups["url"]!!.value)
setUrlWithoutDomain(REGEX_MANGA_URL.find(script)!!.groups[1]!!.value)
}
private fun parseGenres(document: Document): List<Genre> {
@ -279,7 +279,7 @@ class HattoriManga : HttpSource() {
companion object {
const val SEARCH_PREFIX = "slug:"
val REGEX_MANGA_URL = """='(?<url>[^']+)""".toRegex()
val REGEX_MANGA_URL = """='([^']+)""".toRegex()
val dateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.US)
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'Uzay Manga'
extClass = '.UzayManga'
extVersionCode = 37
extVersionCode = 38
}
apply from: "$rootDir/common.gradle"

View File

@ -138,7 +138,7 @@ class UzayManga : ParsedHttpSource() {
?: return emptyList()
return pageRegex.findAll(script).mapIndexed { index, result ->
val url = result.groups.get("path")!!.value
val url = result.groups.get(1)!!.value
Page(index, document.location(), "$CDN_URL/upload/series/$url")
}.toList()
}
@ -158,7 +158,7 @@ class UzayManga : ParsedHttpSource() {
const val CDN_URL = "https://cdn1.uzaymanga.com"
const val URL_SEARCH_PREFIX = "slug:"
val dateFormat = SimpleDateFormat("MMM d ,yyyy", Locale("tr"))
val pageRegex = """\\"path\\":\\"(?<path>[^"]+)\\""".trimIndent().toRegex()
val pageRegex = """\\"path\\":\\"([^"]+)\\""".trimIndent().toRegex()
}
}

View File

@ -1,7 +1,7 @@
ext {
extName = 'LXHentai'
extClass = '.LxHentai'
extVersionCode = 13
extVersionCode = 14
isNsfw = true
}

View File

@ -137,7 +137,7 @@ class LxHentai : ParsedHttpSource(), ConfigurableSource {
}.trim()
thumbnail_url = document.selectFirst(".cover")?.attr("style")?.let {
IMAGE_REGEX.find(it)?.groups?.get("img")?.value
IMAGE_REGEX.find(it)?.groups?.get(1)?.value
}
val statusString = document.select("div.grow div.mt-2:contains(Tình trạng) a").first()!!.text()
@ -323,7 +323,7 @@ class LxHentai : ParsedHttpSource(), ConfigurableSource {
const val PREFIX_ID_SEARCH = "id:"
val CHAPTER_NUMBER_REGEX = Regex("""[+\-]?([0-9]*[.])?[0-9]+""", RegexOption.IGNORE_CASE)
val IMAGE_REGEX = """url\('(?<img>[^']+)""".toRegex()
val IMAGE_REGEX = """url\('([^']+)""".toRegex()
private const val DEFAULT_BASE_URL_PREF = "defaultBaseUrl"
private const val RESTART_APP = "Khởi chạy lại ứng dụng để áp dụng thay đổi."

View File

@ -1,7 +1,7 @@
ext {
extName = 'Roumanwu'
extClass = '.Roumanwu'
extVersionCode = 14
extVersionCode = 15
isNsfw = true
}

View File

@ -34,7 +34,7 @@ class Roumanwu : ParsedHttpSource(), ConfigurableSource {
override val client = network.cloudflareClient.newBuilder().addInterceptor(ScrambledImageInterceptor).build()
private val imageUrlRegex = """\\"imageUrl\\":\\"(?<imageUrl>[^\\]+)""".toRegex()
private val imageUrlRegex = """\\"imageUrl\\":\\"([^\\]+)""".toRegex()
override fun popularMangaRequest(page: Int) = GET("$baseUrl/home", headers)
override fun popularMangaNextPageSelector(): String? = null
@ -110,7 +110,7 @@ class Roumanwu : ParsedHttpSource(), ConfigurableSource {
val images = document.selectFirst("script:containsData(imageUrl)")?.data()
?.let { content ->
imageUrlRegex
.findAll(content).map { it.groups["imageUrl"]?.value }
.findAll(content).map { it.groups[1]?.value }
.toList()
} ?: return emptyList()