Skip to content

Commit 0ecc7c6

Browse files
committed
+ Adopt to the latest html structure.
1 parent c65b044 commit 0ecc7c6

3 files changed

Lines changed: 88 additions & 91 deletions

File tree

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@rollup/plugin-json": "^6.1.0",
1313
"@rollup/plugin-node-resolve": "^15.3.0",
1414
"@rollup/plugin-typescript": "^12.1.1",
15-
"@rulia/types": "^0.6.0",
15+
"@rulia/types": "^0.6.1",
1616
"@types/jquery": "^3.5.32",
1717
"archiver": "^6.0.1",
1818
"rollup": "^2.79.2",

src/index.ts

Lines changed: 83 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,52 @@
22

33
import $ from 'jquery'
44

5-
const COVER: Record<string, string> = {
6-
ウェスタdeクッキング: 'https://alt.hololive.tv/wp-content/uploads/2024/11/%E3%82%AF%E3%83%83%E3%82%AD%E3%83%B3%E3%82%AF%E3%82%99.jpg',
7-
'Vesta de Cooking': 'https://alt.hololive.tv/wp-content/uploads/2024/11/%E3%82%AF%E3%83%83%E3%82%AD%E3%83%B3%E3%82%AF%E3%82%99.jpg',
8-
9-
'それゆけ!! 魔界学校': 'https://alt.hololive.tv/wp-content/uploads/2023/06/cover_makaigakko.jpg',
10-
'Underworld Academy Overload!!': 'https://alt.hololive.tv/wp-content/uploads/2023/06/cover_makaigakko.jpg',
11-
'Sukaria Sekolah Alam Bawah': 'https://alt.hololive.tv/wp-content/uploads/2023/06/cover_makaigakko.jpg',
12-
13-
'Yamato Phantasia': 'https://alt.hololive.tv/wp-content/uploads/2023/06/holoearth_main-1.png',
14-
ヤマト神想怪異譚: 'https://alt.hololive.tv/wp-content/uploads/2023/06/holoearth_main-1.png',
15-
'Kisah Fantasi Yamato': 'https://alt.hololive.tv/wp-content/uploads/2023/06/holoearth_main-1.png'
16-
}
5+
const MANGA_INFO = [
6+
{
7+
title: {
8+
en: 'Vesta de Cooking',
9+
jp: 'ウェスタdeクッキング',
10+
id: 'Vesta de Cooking'
11+
},
12+
url: {
13+
en: 'https://holoearth.com/en/alt/holonometria/manga/vestadecooking',
14+
jp: 'https://holoearth.com/alt/holonometria/manga/vestadecooking',
15+
id: 'https://holoearth.com/id/alt/holonometria/manga/vestadecooking'
16+
},
17+
cover: 'https://holoearth.com/assets/img/alt/top/comic/thumb_1.jpg',
18+
firstEp: 'ep0'
19+
},
20+
21+
{
22+
title: {
23+
en: 'Underworld Academy Overload!!',
24+
jp: 'それゆけ!! 魔界学校',
25+
id: 'Sukaria Sekolah Alam Bawah'
26+
},
27+
url: {
28+
en: 'https://holoearth.com/en/alt/holonometria/manga/soreyukemakaigakko',
29+
jp: 'https://holoearth.com/alt/holonometria/manga/soreyukemakaigakko',
30+
id: 'https://holoearth.com/id/alt/holonometria/manga/soreyukemakaigakko'
31+
},
32+
cover: 'https://holoearth.com/assets/img/alt/top/comic/thumb_2.jpg',
33+
firstEp: 'ep0'
34+
},
35+
36+
{
37+
title: {
38+
en: 'Yamato Phantasia',
39+
jp: 'ヤマト神想怪異譚',
40+
id: 'Kisah Fantasi Yamato'
41+
},
42+
url: {
43+
en: 'https://holoearth.com/en/alt/holonometria/manga/yamatokasoukaiitan',
44+
jp: 'https://holoearth.com/alt/holonometria/manga/yamatokasoukaiitan',
45+
id: 'https://holoearth.com/id/alt/holonometria/manga/yamatokasoukaiitan'
46+
},
47+
cover: 'https://holoearth.com/assets/img/alt/top/comic/thumb_3.jpg',
48+
firstEp: 'ep0'
49+
}
50+
]
1751

1852
function sleep (ms: number) {
1953
return new Promise(resolve => setTimeout(resolve, ms))
@@ -35,70 +69,34 @@ async function getMangaList (
3569
keyword?: string,
3670
rawFilterOptions?: string
3771
) {
72+
const result: IGetMangaListResult = {
73+
list: []
74+
}
75+
3876
if (page !== '1') {
39-
window.Rulia.endWithResult({
40-
list: []
41-
})
77+
window.Rulia.endWithResult(result)
4278
return
4379
}
4480

4581
try {
4682
const config = window.Rulia.getUserConfig()
4783
const lang = (config?.language ?? 'en').toLowerCase()
48-
49-
const homepages: Record<string, string> = {
50-
en: 'https://alt.hololive.tv/holonometria/en/',
51-
jp: 'https://alt.hololive.tv/holonometria/',
52-
id: 'https://alt.hololive.tv/holonometria/id/'
53-
}
54-
55-
const homepage = homepages[lang] || homepages.en
56-
const response = await window.Rulia.httpRequest({
57-
url: homepage,
58-
method: 'GET'
59-
})
60-
61-
const result: IGetMangaListResult = {
62-
list: []
63-
}
64-
65-
$(response).find('li[data-type="manga"] a').each((i, el) => {
66-
const title = $(el).text()
67-
const url = $(el).attr('href') ?? ''
84+
for (const item of MANGA_INFO) {
85+
const title = item.title[lang as keyof typeof item.title] ?? item.title.en
86+
const url = item.url[lang as keyof typeof item.url] ?? item.url.en
6887
result.list.push({
6988
title,
70-
url,
71-
coverUrl: COVER[title] ?? ''
89+
url: `${url}/${item.firstEp}?title=${encodeURIComponent(title)}`,
90+
coverUrl: item.cover
7291
})
73-
})
92+
}
7493

7594
window.Rulia.endWithResult(result)
7695
} catch (error) {
7796
window.Rulia.endWithException((error as Error).message)
7897
}
7998
}
8099

81-
async function getChapterListFromDetailPage (detailPage: string): Promise<{ title: string, url: string }[]> {
82-
const response = await window.Rulia.httpRequest({
83-
url: detailPage,
84-
method: 'GET'
85-
})
86-
87-
const result: { title: string, url: string }[] = []
88-
$(response).find('article.md-list__archive--lineup--block').each((i, el) => {
89-
const $a = $(el).find('a')
90-
const $h4 = $(el).find('h4')
91-
const title = $h4.text().trim()
92-
const url = $a.attr('href') ?? ''
93-
result.push({
94-
title,
95-
url
96-
})
97-
})
98-
99-
return result
100-
}
101-
102100
/**
103101
* Get data of a single manga.
104102
* This function will be invoked by Rulia when user clicks a certain manga
@@ -115,32 +113,32 @@ async function getMangaData (dataPageUrl: string) {
115113
})
116114

117115
const $html = $(response)
118-
const title = $html.find('h1.md-ttl__pages')?.text()?.trim() ?? ''
119-
const description = $html.find('main.mangainfo--main main')?.text()?.trim() ?? ''
120-
const coverUrl = $html.find('main.mangainfo--main img')?.attr('src') ?? ''
116+
const title = new URL(dataPageUrl).searchParams.get('title') ?? ''
117+
const description = $html.find('.manga-detail__caption')?.text()?.trim() ?? ''
118+
const coverUrl = $html.find('.manga-detail__thumb img')?.attr('src') ?? ''
121119

122120
const result: IGetMangaDataResult = {
123121
title,
124122
description,
125123
coverUrl,
126-
chapterList: []
124+
chapterList: [],
125+
chapterListOptions: {
126+
hasPagination: true,
127+
totalPage: 1
128+
}
127129
}
128130

129-
const allDetailPages = [dataPageUrl]
130-
$html.find('.pagenation-list a').each((i, el) => {
131-
const url = $(el).attr('href')
132-
if (url) {
133-
allDetailPages.push(url)
134-
}
135-
})
131+
$html.find('.manga-detail__list-item').each((i, el) => {
132+
const $el = $(el)
133+
const title = $el.find('.manga-detail__list-title').text().trim()
134+
const url = $el.find('.manga-detail__list-link').attr('href') ?? ''
136135

137-
for (const pageUrl of allDetailPages) {
138-
const list = await getChapterListFromDetailPage(pageUrl)
139-
result.chapterList.push(...list)
140-
await sleep(300)
141-
}
136+
result.chapterList.push({
137+
title,
138+
url
139+
})
140+
})
142141

143-
result.chapterList.reverse()
144142
window.Rulia.endWithResult(result)
145143
} catch (error) {
146144
window.Rulia.endWithException((error as Error).message)
@@ -162,18 +160,17 @@ async function getChapterImageList (chapterUrl: string) {
162160
const result: IRuliaChapterImage[] = []
163161
const $html = $(response)
164162

165-
const $mangaBlocks = $html.find('.manga--viewer__block')
166-
$mangaBlocks.each((i, el) => {
167-
const img = $(el).find('img')[0]
168-
if (img) {
169-
result.push({
170-
url: img.src,
171-
width: 684,
172-
height: 997
173-
})
174-
}
163+
const $images = $html.find('.manga-detail__swiper-slide img')
164+
$images.each((i, el) => {
165+
const src = $(el).attr('src') || ''
166+
result.push({
167+
url: src,
168+
width: 684,
169+
height: 997
170+
})
175171
})
176172

173+
result.reverse() // The image order in the html is reversed, so we need to reverse it back.
177174
window.Rulia.endWithResult(result)
178175
} catch (error) {
179176
window.Rulia.endWithException((error as Error).message)

0 commit comments

Comments
 (0)