fix: [Genesis]: Update Source URL and Parsing Logic (#1204)

* New Source dreambigtl (Dream Big Translations)

* Apply suggestions from code review

Co-authored-by: nyagami <hoangquan05112002@gmail.com>

* Update dreambigtl.ts

* gensis fix, they obfuscated their api...dont be suprised chapter names are missing...

* Update galaxy translations new domain

* version increment

* they changed their code again

---------

Co-authored-by: Ridi <ridi.culous.progger@gmail.com>
Co-authored-by: nyagami <hoangquan05112002@gmail.com>
This commit is contained in:
r1di
2024-10-04 13:59:26 +02:00
committed by GitHub
parent 8d75b746b9
commit 2e52945498
2 changed files with 66 additions and 56 deletions
+2 -2
View File
@@ -347,11 +347,11 @@
}, },
{ {
"id": "galaxytranslations", "id": "galaxytranslations",
"sourceSite": "https://galaxytranslations11.com/", "sourceSite": "https://darkstartranslations.com/",
"sourceName": "Galaxy Translations", "sourceName": "Galaxy Translations",
"options": { "options": {
"useNewChapterEndpoint": true, "useNewChapterEndpoint": true,
"versionIncrements": 2, "versionIncrements": 3,
"lang": "English" "lang": "English"
} }
}, },
+64 -54
View File
@@ -18,87 +18,103 @@ class Genesis implements Plugin.PluginBase {
icon = 'src/en/genesis/icon.png'; icon = 'src/en/genesis/icon.png';
customCSS = 'src/en/genesis/customCSS.css'; customCSS = 'src/en/genesis/customCSS.css';
site = 'https://genesistudio.com'; site = 'https://genesistudio.com';
version = '1.0.3'; version = '1.0.4';
imageRequestInit?: Plugin.ImageRequestInit | undefined = { imageRequestInit?: Plugin.ImageRequestInit | undefined = {
headers: { headers: {
'referrer': this.site, 'referrer': this.site,
}, },
}; };
async parseNovels(json: any[]): Promise<Plugin.NovelItem[]> { async parseNovels(json: any[]): Promise<Plugin.SourceNovel[]> {
return json.map((novel: any) => { return json.map((novel: any) => ({
return { name: novel.novel_title,
name: novel.novel_title, path: `/novels/${novel.abbreviation}`,
path: `/novels/${novel.abbreviation}`, cover: novel.cover,
cover: novel.cover, }));
};
});
} }
async popularNovels( async popularNovels(
pageNo: number, pageNo: number,
{ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
showLatestNovels, ): Promise<Plugin.SourceNovel[]> {
filters,
}: Plugin.PopularNovelsOptions<typeof this.filters>,
): Promise<Plugin.NovelItem[]> {
if (pageNo !== 1) return []; if (pageNo !== 1) return [];
let link = `${this.site}/api/search?`;
let link = `https://genesistudio.com/api/search?`;
if (showLatestNovels) { if (showLatestNovels) {
link += 'sort=Recent'; link += 'sort=Recent';
} else { } else {
if (filters!.genres.value.length) { if (filters!.genres.value) {
link += filters!.genres.value.join('&'); link += filters!.genres.value;
} }
link += `&${filters!.storyStatus.value}&${filters!.sort.value}`; link += `&${filters!.storyStatus.value}&${filters!.sort.value}`;
} }
const json = await fetchApi(link).then(r => r.json()); const json = await fetchApi(link).then(r => r.json());
return this.parseNovels(json); return this.parseNovels(json);
} }
async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> { async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> {
const url = `${this.site}${novelPath}/__data.json?x-sveltekit-invalidated=001`; const url = `${this.site}${novelPath}/__data.json?x-sveltekit-invalidated=001`;
const json = await fetchApi(url).then(r => r.json()); const json = await fetchApi(url).then(r => r.json());
const nodes = json.nodes; const nodes = json.nodes;
const data = nodes const data = nodes
.filter((node: { type: string }) => node.type === 'data') .filter((node: { type: string }) => node.type === 'data')
.map((node: { data: any }) => node.data)[0]; .map((node: { data: any }) => node.data)[0];
const novelData = data[data[0].novel];
const novel: Plugin.SourceNovel = { const novel: Plugin.SourceNovel = {
path: novelPath, path: novelPath,
name: data[novelData.novel_title], name: '',
cover: data[novelData.cover], cover: '',
summary: data[novelData.synopsis], summary: '',
author: data[novelData.author], author: '',
status: 'Unknown',
chapters: [],
}; };
novel.genres = data[novelData.genres] for (const key in data) {
.map((index: number) => data[index]) const value = data[key];
.join(','); if (typeof value === 'object' && value !== null) {
if ('novel_title' in value) {
novel.name = data[value.novel_title];
novel.cover = data[value.cover];
novel.summary = data[value.synopsis];
novel.author = data[value.author];
novel.genres = (data[value.genres] as number[])
.map((genreId: number) => data[genreId])
.join(', ');
novel.status = value.release_days ? 'Ongoing' : 'Completed';
} else if ('chapters_list' in value) {
const chaptersFunction = data[value.chapters_list];
const chapterMatches = chaptersFunction.match(
/'id':((?!_)\w+),'chapter_title':(?:'([^'\\]*(?:\\.[^'\\]*)*)'|(\w+\([^\)]+\))),'chapter_number':(\w+),'required_tier':(\w+),'date_created':([^,]*),/g,
);
novel.status = data[novelData.release_days] ? 'Ongoing' : 'Completed'; if (chapterMatches) {
novel.chapters = chapterMatches
.map((match: string) => {
const [, id, title, , number, requiredTier, dateCreated] =
match.match(
/'id':(\w+),'chapter_title':(?:'([^'\\]*(?:\\.[^'\\]*)*)'|(\w+\([^\)]+\))),'chapter_number':(\w+),'required_tier':(\w+),'date_created':([^,]*),/,
)!;
const chapterData = data[data[0].chapters]; if (parseInt(requiredTier, 16) === 0) {
const freeChapterData = chapterData.free_chapters; return {
name: `Chapter ${parseInt(number, 16)}: ${title || 'Unknown Title'}`,
/** Premium chapters not yet implemented */ path: `/viewer/${parseInt(id, 16)}`,
// const premiumChapterData = chapterData.premium_chapters; releaseTime: dateCreated.replace(/^'|'$/g, ''),
chapterNumber: parseInt(number, 16),
novel.chapters = data[freeChapterData] };
.map((index: number) => data[index]) }
.map((chapter: any) => { return null;
return { })
name: `Chapter ${data[chapter.chapter_number]}: ${data[chapter.chapter_title]}`, .filter(
path: `/viewer/${data[chapter.id]}`, (
releaseTime: data[chapter.date_created], chapter: Plugin.ChapterItem | null,
chapterNumber: data[chapter.chapter_number], ): chapter is Plugin.ChapterItem => chapter !== null,
}; );
}); }
}
}
}
return novel; return novel;
} }
@@ -106,28 +122,22 @@ class Genesis implements Plugin.PluginBase {
async parseChapter(chapterPath: string): Promise<string> { async parseChapter(chapterPath: string): Promise<string> {
const url = `${this.site}${chapterPath}/__data.json?x-sveltekit-invalidated=001`; const url = `${this.site}${chapterPath}/__data.json?x-sveltekit-invalidated=001`;
const json = await fetchApi(url).then(r => r.json()); const json = await fetchApi(url).then(r => r.json());
const nodes = json.nodes; const nodes = json.nodes;
const data = nodes const data = nodes
.filter((node: { type: string }) => node.type === 'data') .filter((node: { type: string }) => node.type === 'data')
.map((node: { data: any }) => node.data)[0]; .map((node: { data: any }) => node.data)[0];
/** May change in the future */
const content = data[19]; const content = data[19];
const footnotes = data[data[0].footnotes]; const footnotes = data[data[0].footnotes];
return content + (footnotes ?? '');
return content + footnotes ?? '';
} }
async searchNovels( async searchNovels(
searchTerm: string, searchTerm: string,
pageNo: number, pageNo: number,
): Promise<Plugin.NovelItem[]> { ): Promise<Plugin.SourceNovel[]> {
if (pageNo !== 1) return []; if (pageNo !== 1) return [];
const url = `${this.site}/api/search?serialization=All&sort=Popular&title=${searchTerm}`; const url = `${this.site}/api/search?serialization=All&sort=Popular&title=${searchTerm}`;
const json = await fetchApi(url).then(r => r.json()); const json = await fetchApi(url).then(r => r.json());
return this.parseNovels(json); return this.parseNovels(json);
} }