fix ul.direlist
Build Futon with Niadd patch / Build Futon Niadd debug APK (push) Successful in 12m49s

This commit is contained in:
2026-08-09 22:45:36 +03:00
parent e8d027bca3
commit bdb8b68c3e
+192 -2
View File
@@ -17,7 +17,10 @@ parser_file = (
)
if not parser_file.is_file():
print(f"ERROR: parser file not found: {parser_file}", file=sys.stderr)
print(
f"ERROR: parser file not found: {parser_file}",
file=sys.stderr,
)
sys.exit(1)
@@ -44,6 +47,40 @@ def replace_exact(name: str, old: str, new: str) -> None:
print(f"[OK] {name}")
#
# Niadd search pagination:
#
# NineManga:
# ?page=2
#
# Niadd:
# ?page=2.html
#
replace_exact(
"Niadd search pagination",
''' append("/search/")
append("?page=")
append(page.toString())
''',
''' append("/search/")
append("?page=")
append(page.toString())
if (domain.endsWith("niadd.com")) {
append(".html")
}
''',
)
#
# Niadd category pagination:
#
# Page 1:
# /category/
#
# Page 2+:
# /category/index_2.html
#
replace_exact(
"Niadd category pagination",
''' } else {
@@ -67,6 +104,142 @@ replace_exact(
)
#
# NineManga used:
#
# ul.direlist > li
#
# Niadd no longer has ul.direlist.
#
# Instead, discover manga cards through their canonical /manga/ links.
#
# The same manga can have several links:
# - cover
# - title
# - description
#
# Therefore links are grouped by absolute manga URL.
#
replace_exact(
"Niadd manga list parser",
''' val doc = webClient.httpGet(url).parseHtml()
val root = doc.body().selectFirstOrThrow("ul.direlist")
val baseHost = root.baseUri().toHttpUrl().host
return root.select("li").map { node ->
val href = node.selectFirstOrThrow("a").attrAsAbsoluteUrl("href")
val relUrl = href.toRelativeUrl(baseHost)
val dd = node.selectFirst("dd")
Manga(
id = generateUid(relUrl),
url = relUrl,
publicUrl = href,
title = dd?.selectFirst("a.bookname")?.text()?.toCamelCase().orEmpty(),
altTitles = emptySet(),
coverUrl = node.selectFirst("img")?.src(),
rating = RATING_UNKNOWN,
authors = emptySet(),
contentRating = null,
tags = emptySet(),
state = null,
source = source,
description = dd?.selectFirst("p")?.html(),
)
}
''',
''' val doc = webClient.httpGet(url).parseHtml()
if (domain.endsWith("niadd.com")) {
val mangaLinks = doc.select("a[href]").filter { link ->
val href = link.attr("href")
href.startsWith("/manga/") ||
href.startsWith("https://${domain}/manga/")
}
val linksByUrl = mangaLinks.groupBy { link ->
link.attrAsAbsoluteUrl("href")
}
return linksByUrl.mapNotNull { (href, links) ->
val relUrl = href.toRelativeUrl(domain)
val texts = links
.map { it.text().trim() }
.filter { it.isNotEmpty() }
.distinct()
val rawTitle = texts.minByOrNull { it.length }
?: return@mapNotNull null
val description = texts
.asSequence()
.filter { it != rawTitle }
.filter { it.length > rawTitle.length }
.maxByOrNull { it.length }
?.removePrefix(rawTitle)
?.trim()
?.takeIf { it.isNotEmpty() }
val coverUrl = links
.asSequence()
.mapNotNull { link ->
link.selectFirst("img")?.src()
?: link.parent()?.selectFirst("img")?.src()
?: link.parent()?.parent()?.selectFirst("img")?.src()
}
.firstOrNull()
Manga(
id = generateUid(relUrl),
url = relUrl,
publicUrl = href,
title = rawTitle.toCamelCase(),
altTitles = emptySet(),
coverUrl = coverUrl,
rating = RATING_UNKNOWN,
authors = emptySet(),
contentRating = null,
tags = emptySet(),
state = null,
source = source,
description = description,
)
}
}
val root = doc.body().selectFirstOrThrow("ul.direlist")
val baseHost = root.baseUri().toHttpUrl().host
return root.select("li").map { node ->
val href = node.selectFirstOrThrow("a").attrAsAbsoluteUrl("href")
val relUrl = href.toRelativeUrl(baseHost)
val dd = node.selectFirst("dd")
Manga(
id = generateUid(relUrl),
url = relUrl,
publicUrl = href,
title = dd?.selectFirst("a.bookname")?.text()?.toCamelCase().orEmpty(),
altTitles = emptySet(),
coverUrl = node.selectFirst("img")?.src(),
rating = RATING_UNKNOWN,
authors = emptySet(),
contentRating = null,
tags = emptySet(),
state = null,
source = source,
description = dd?.selectFirst("p")?.html(),
)
}
''',
)
#
# Russian statuses on Niadd are not consistently cased:
#
# постоянный
# Завершенный
#
replace_exact(
"Russian status parsing",
''' //ru
@@ -80,6 +253,12 @@ replace_exact(
)
#
# Activate Russian source and migrate it to Niadd.
#
# Keep NINEMANGA_RU intentionally unchanged so existing Futon
# database/source references remain compatible.
#
replace_exact(
"NineManga RU to Niadd RU",
''' @Broken
@@ -100,7 +279,18 @@ replace_exact(
)
parser_file.write_text(text, encoding="utf-8")
parser_file.write_text(
text,
encoding="utf-8",
)
print()
print(f"[OK] Patched: {parser_file}")
print()
print("[OK] Niadd domain")
print("[OK] Niadd category pagination")
print("[OK] Niadd search pagination")
print("[OK] Niadd manga list parser")
print("[OK] Russian statuses")
print("[OK] Russian source enabled")