为绅士漫画增加获取最新域名和排行榜功能 (#204)

* feat: Implement dynamic domain selection and refresh functionality to improve site accessibility

* feat: enable ranking page with new ranking options and loading functionality, and add translations for ranking periods

* fix: format漫画柜

* Downgrade version from 1.0.5 to 1.0.4
This commit is contained in:
sakana164
2025-12-04 21:17:34 +08:00
committed by GitHub
parent 6a0e667775
commit c8de505945
2 changed files with 232 additions and 37 deletions

View File

@@ -33,7 +33,7 @@
"name": "紳士漫畫",
"fileName": "wnacg.js",
"key": "wnacg",
"version": "1.0.3",
"version": "1.0.4",
"description": "紳士漫畫漫畫源, 不能使用時請嘗試更換URL"
},
{

209
wnacg.js
View File

@@ -7,15 +7,39 @@ class Wnacg extends ComicSource {
// unique id of the source
key = "wnacg"
version = "1.0.3"
version = "1.0.5"
minAppVersion = "1.0.0"
// update url
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/wnacg.js"
static domains = [];
get baseUrl() {
return `https://${this.loadSetting('domain')}`
let selection = this.loadSetting('domainSelection')
if (selection === undefined || selection === null) selection = 0
selection = parseInt(selection)
if (selection === 0) {
// 选择自定义域名
let domain0 = this.loadSetting('domain0')
if (!domain0 || domain0.trim() === '') {
throw 'Custom domain is not set'
}
return `https://${domain0.trim()}`
} else {
// 选择获取的域名 (Domain 1-3)
let index = selection - 1
if (index >= Wnacg.domains.length) {
throw 'Selected domain is unavailable'
}
return `https://${Wnacg.domains[index]}`
}
}
overwriteDomains(domains) {
if (domains.length != 0) Wnacg.domains = domains
}
// [Optional] account related
@@ -55,6 +79,91 @@ class Wnacg extends ComicSource {
registerWebsite: null
}
async init() {
if (this.loadSetting('refreshDomainsOnStart')) await this.refreshDomains(false)
}
/**
* 刷新域名列表
* @param showConfirmDialog {boolean}
*/
async refreshDomains(showConfirmDialog) {
let url = "https://wn01.link/"
let title = ""
let message = ""
let domains = []
try {
let res = await fetch(url)
if (res.status == 200) {
let html = await res.text()
let document = new HtmlDocument(html)
// 提取所有链接
let links = document.querySelectorAll("a[href]")
let seenDomains = new Set()
for (let link of links) {
let href = link.attributes["href"]
if (!href) continue
// 提取域名(支持 http:// 和 https://
let match = href.match(/^https?:\/\/([^\/]+)/)
if (match) {
let domain = match[1]
// 只提取有效的域名,排除 wn01.link 自身和其他无关链接
if (domain &&
domain.includes(".") &&
!domain.includes("wn01.link") &&
!domain.includes("google.cn") &&
!domain.includes("cdn-cgi") &&
!seenDomains.has(domain)) {
domains.push(domain)
seenDomains.add(domain)
}
}
}
document.dispose()
if (domains.length > 0) {
title = "Update Success"
message = "New domains:\n\n"
}
}
} catch (e) {
// 获取失败,使用内置域名
}
if (domains.length == 0) {
title = "Update Failed"
message = `Using built-in domains:\n\n`
domains = Wnacg.domains
}
for (let i = 0; i < domains.length; i++) {
message = message + `Fetched Domain ${i + 1}: ${domains[i]}\n`
}
message = message + `\nTotal: ${domains.length} domain(s)`
if (showConfirmDialog) {
UI.showDialog(
title,
message,
[
{
text: "Cancel",
callback: () => { }
},
{
text: "Apply",
callback: () => this.overwriteDomains(domains)
}
]
)
} else {
this.overwriteDomains(domains)
}
}
parseComic(c) {
let link = c.querySelector("div.pic_box > a").attributes["href"];
let id = RegExp("(?<=-aid-)[0-9]+").exec(link)[0];
@@ -273,7 +382,7 @@ class Wnacg extends ComicSource {
},
],
// enable ranking page
enableRankingPage: false,
enableRankingPage: true,
}
/// category comic loading related
@@ -316,6 +425,43 @@ class Wnacg extends ComicSource {
maxPage: pages,
}
},
ranking: {
options: [
"day-Day",
"week-Week",
"month-Month",
],
load: async (option, page) => {
let url = `${this.baseUrl}/albums-favorite_ranking-type-${option}.html`
if (page !== 0) {
url = `${this.baseUrl}/albums-favorite_ranking-page-${page}-type-${option}.html`
}
let res = await Network.get(url, {})
if (res.status !== 200) {
throw `Invalid Status Code ${res.status}`
}
let document = new HtmlDocument(res.body)
let comicElements = document.querySelectorAll("div.grid div.gallary_wrap > ul.cc > li")
let comics = []
for (let comicElement of comicElements) {
comics.push(this.parseComic(comicElement))
}
let pagesLink = document.querySelectorAll("div.f_left.paginator > a")
let pages = 1
if (pagesLink.length > 0) {
pages = Number(pagesLink[pagesLink.length - 1].text)
}
document.dispose()
return {
comics: comics,
maxPage: pages,
}
}
}
}
/// search related
@@ -578,11 +724,60 @@ class Wnacg extends ComicSource {
}
settings = {
domain: {
title: "Domain",
refreshDomains: {
title: "Refresh Domain List",
type: "callback",
buttonText: "Refresh",
callback: () => this.refreshDomains(true)
},
refreshDomainsOnStart: {
title: "Refresh Domain List on Startup",
type: "switch",
default: true,
},
domainSelection: {
title: "Domain Selection",
type: "select",
options: [
{ value: '0', text: 'Custom Domain' },
{ value: '1', text: 'Domain 1' },
{ value: '2', text: 'Domain 2' },
{ value: '3', text: 'Domain 3' }
],
default: "0",
},
domain0: {
title: "Custom Domain",
type: "input",
validator: '^(?!:\\/\\/)(?=.{1,253})([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$',
default: 'www.wnacg.com',
validator: String.raw`^(?!:\/\/)(?=.{1,253})([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$`,
default: 'wnacg.com',
},
}
translation = {
'zh_CN': {
'Refresh Domain List': '刷新域名列表',
'Refresh': '刷新',
'Refresh Domain List on Startup': '启动时刷新域名列表',
'Domain Selection': '域名选择',
'Custom Domain': '自定义域名',
'Custom domain is not set': '未设置自定义域名',
'Selected domain is unavailable': '所选域名不可用,请先刷新域名列表',
'Day': '日',
'Week': '周',
'Month': '月',
},
'zh_TW': {
'Refresh Domain List': '刷新域名列表',
'Refresh': '刷新',
'Refresh Domain List on Startup': '啟動時刷新域名列表',
'Domain Selection': '域名選擇',
'Custom Domain': '自定義域名',
'Custom domain is not set': '未設置自定義域名',
'Selected domain is unavailable': '所選域名不可用,請先刷新域名列表',
'Day': '日',
'Week': '周',
'Month': '月',
},
}
}