From ec968a3ff989eb4772b5a0b00595cc77f3072067 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:13:05 -0500 Subject: [PATCH 01/11] chore: Source announced termination --- plugins/english/lightnovelpub.ts | 499 ------------------------------- 1 file changed, 499 deletions(-) delete mode 100644 plugins/english/lightnovelpub.ts diff --git a/plugins/english/lightnovelpub.ts b/plugins/english/lightnovelpub.ts deleted file mode 100644 index e2eacc9df..000000000 --- a/plugins/english/lightnovelpub.ts +++ /dev/null @@ -1,499 +0,0 @@ -import { Parser } from 'htmlparser2'; -import { fetchApi } from '@libs/fetch'; -import { Plugin } from '@/types/plugin'; -import { Filters, FilterTypes } from '@libs/filterInputs'; -import dayjs from 'dayjs'; - -class LightNovelPub implements Plugin.PagePlugin { - id = 'lightnovelpub'; - name = 'LightNovelPub'; - version = '2.2.0'; - icon = 'src/en/lightnovelpub/icon.png'; - site = 'https://www.lightnovelpub.com/'; - headers = { - Accept: 'application/json', - 'Content-Type': 'application/json', - }; - - parseNovels(html: string) { - const novels: Plugin.NovelItem[] = []; - let tempNovel: Partial = {}; - let state: ParsingState = ParsingState.Idle; - const parser = new Parser({ - onopentag(name, attribs) { - if (attribs['class'] === 'novel-item') { - state = ParsingState.Novel; - } - if (state !== ParsingState.Novel) return; - - switch (name) { - case 'a': - tempNovel.path = attribs['href'].slice(1); - tempNovel.name = attribs['title']; - break; - case 'img': - tempNovel.cover = attribs['data-src'] || attribs['src']; - break; - } - }, - onclosetag(name) { - if (name === 'li') { - if (tempNovel.path && tempNovel.cover) { - novels.push(tempNovel as Plugin.NovelItem); - tempNovel = {}; - } - state = ParsingState.Idle; - } - }, - }); - - parser.write(html); - parser.end(); - - return novels; - } - - async popularNovels( - page: number, - { filters }: Plugin.PopularNovelsOptions, - ): Promise { - const linkParts = [ - this.site + 'browse', - filters.genres.value, - filters.order.value, - filters.status.value, - page.toString(), - ]; - - const body = await fetchApi(linkParts.join('/')).then(r => r.text()); - - return this.parseNovels(body); - } - - async parseNovel( - novelPath: string, - ): Promise { - const body = await fetchApi(this.site + novelPath).then(r => r.text()); - const novel: Partial & Partial<{ totalPages: number }> = - { - path: novelPath, - chapters: [], - }; - let state: ParsingState = ParsingState.Idle; - const summaryParts: string[] = []; - const genreArray: string[] = []; - const parser = new Parser({ - onopentag(name, attribs) { - switch (name) { - case 'h1': - if (attribs['class']?.includes('novel-title')) { - state = ParsingState.NovelName; - } - break; - case 'figure': - if (attribs['class'] === 'cover') { - state = ParsingState.Cover; - } - break; - case 'img': - if (state === ParsingState.Cover) { - novel.cover = attribs['data-src'] || attribs['src']; - } - break; - case 'strong': - if (state === ParsingState.HeaderStats) { - if (attribs['class']) { - state = ParsingState.Status; - } else { - state = ParsingState.TotalChapters; - } - } - break; - case 'br': - if (state === ParsingState.Summary) { - summaryParts.push(''); - } - break; - case 'a': - if (state === ParsingState.Genres) { - state = ParsingState.Tags; - } - break; - case 'div': - if (attribs['class']) { - if (attribs['class'].includes('content')) { - state = ParsingState.Summary; - } else { - const map: Record = { - 'categories': ParsingState.Genres, - 'header-stats': ParsingState.HeaderStats, - 'expand': ParsingState.Idle, - }; - state = map[attribs['class']] ?? state; - } - } - break; - default: - if (attribs['itemprop'] === 'author') { - state = ParsingState.AuthorName; - } - break; - } - }, - ontext(data) { - switch (state) { - case ParsingState.TotalChapters: - if (!novel.totalPages) { - novel.totalPages = Math.ceil(parseInt(data, 10) / 100); - } - break; - case ParsingState.Status: - novel.status = data.trim(); - break; - case ParsingState.NovelName: - novel.name = (novel.name || '') + data.trim(); - break; - case ParsingState.AuthorName: - novel.author = data; - break; - case ParsingState.Summary: - summaryParts.push(data); - break; - case ParsingState.Tags: - genreArray.push(data); - break; - } - }, - onclosetag(name) { - switch (name) { - case 'strong': - if (state === ParsingState.TotalChapters) { - state = ParsingState.HeaderStats; - } else if (state === ParsingState.Status) { - state = ParsingState.Idle; - } - break; - case 'i': - if (state === ParsingState.Status) { - state = ParsingState.Idle; - } - break; - case 'h1': - if (state === ParsingState.NovelName) { - state = ParsingState.Idle; - } - break; - case 'span': - if (state === ParsingState.AuthorName) { - state = ParsingState.Idle; - } - break; - case 'div': - if ( - state === ParsingState.Summary || - state === ParsingState.Genres - ) { - state = ParsingState.Idle; - } - break; - case 'a': - if (state === ParsingState.Tags) { - state = ParsingState.Genres; - } - break; - case 'figure': - if (state === ParsingState.Cover) { - state = ParsingState.Idle; - } - break; - case 'p': - if (state === ParsingState.Summary) { - summaryParts.push(''); - } - break; - } - }, - onend() { - const text = summaryParts - .join('') - .replace(//g, '\n\n') - .replace(//g, '\n') - .replace(/\r\n/g, '\n') - .replace(/ /g, ' '); - - const paragraphs = text - .split('\n\n') - .map(p => p.trim().replace(/[ \t]+/g, ' ')) - .filter(p => p.length > 0); - - novel.summary = paragraphs.join('\n\n'); - summaryParts.length = 0; - - novel.genres = genreArray.join(', '); - }, - }); - - parser.write(body); - parser.end(); - - return novel as Plugin.SourceNovel & { totalPages: number }; - } - - async parsePage(novelPath: string, page: string): Promise { - const url = this.site + novelPath + '/chapters/page-' + page; - const body = await fetchApi(url).then(res => res.text()); - const chapters: Plugin.ChapterItem[] = []; - let tempChapter: Partial = {}; - let state: ParsingState = ParsingState.Idle; - - const parser = new Parser({ - onopentag(name, attribs) { - if (attribs['class'] === 'chapter-list') { - state = ParsingState.ChapterList; - return; - } - - switch (state) { - case ParsingState.ChapterList: - if (name === 'li') { - state = ParsingState.ChapterItem; - tempChapter = { - chapterNumber: Number(attribs['data-orderno'] || 0), - }; - } - break; - case ParsingState.ChapterItem: - switch (name) { - case 'a': - tempChapter.name = attribs['title']; - tempChapter.path = attribs['href']?.slice(1); - break; - case 'time': - tempChapter.releaseTime = dayjs( - attribs['datetime'], - ).toISOString(); - break; - } - break; - } - }, - onclosetag(name) { - switch (state) { - case ParsingState.ChapterItem: - if (name === 'li') { - if ( - tempChapter.chapterNumber !== undefined && - tempChapter.path && - tempChapter.releaseTime - ) { - chapters.push(tempChapter as Plugin.ChapterItem); - } - state = ParsingState.ChapterList; - } - break; - case ParsingState.ChapterList: - if (name === 'ul') { - state = ParsingState.Idle; - } - break; - } - }, - }); - - parser.write(body); - parser.end(); - - return { chapters }; - } - - async parseChapter(chapterPath: string): Promise { - const html = await fetchApi(this.site + chapterPath).then(r => r.text()); - - let depth = 0; - let state: ParsingState = ParsingState.Idle; - const chapterHtml: string[] = []; - - type EscapeChar = '&' | '<' | '>' | '"' | "'"; - const escapeRegex = /[&<>"']/g; - const escapeMap: Record = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - }; - const escapeHtml = (text: string): string => - text.replace(escapeRegex, char => escapeMap[char as EscapeChar]); - - const parser = new Parser({ - onopentag(name, attribs) { - switch (state) { - case ParsingState.Idle: - if (name === 'div' && attribs['id'] === 'chapter-container') { - state = ParsingState.Chapter; - depth++; - } - break; - case ParsingState.Chapter: - if (name === 'div') depth++; - break; - default: - return; - } - - if (state === ParsingState.Chapter) { - const attr = Object.keys(attribs).map(key => { - const value = attribs[key].replace(/"/g, '"'); - return ` ${key}="${value}"`; - }); - chapterHtml.push(`<${name}${attr.join('')}>`); - } - }, - - ontext(text) { - if (state === ParsingState.Chapter) { - chapterHtml.push(escapeHtml(text)); - } - }, - - onclosetag(name) { - if (state === ParsingState.Chapter) { - if (!parser['isVoidElement'](name)) { - chapterHtml.push(``); - } - if (name === 'div') depth--; - if (depth === 0) { - state = ParsingState.Stopped; - } - } - }, - }); - - parser.write(html); - parser.end(); - - return chapterHtml.join(''); - } - - async searchNovels(searchTerm: string): Promise { - const url = `${this.site}lnsearchlive`; - const link = `${this.site}search`; - const response = await fetchApi(link).then(r => r.text()); - let verifytoken = ''; - const parser = new Parser({ - onopentag(name, attribs) { - if ( - name === 'input' && - attribs['name']?.includes('LNRequestVerifyToken') - ) { - verifytoken = attribs['value']; - } - }, - }); - parser.write(response); - parser.end(); - - const formData = new FormData(); - formData.append('inputContent', searchTerm); - - const body = await fetchApi(url, { - method: 'POST', - headers: { LNRequestVerifyToken: verifytoken! }, - body: formData, - }).then(r => r.json()); - - return this.parseNovels(body.resultview); - } - - filters = { - order: { - value: 'popular', - label: 'Order by', - options: [ - { label: 'New', value: 'new' }, - { label: 'Popular', value: 'popular' }, - { label: 'Updates', value: 'updated' }, - ], - type: FilterTypes.Picker, - }, - status: { - value: 'all', - label: 'Status', - options: [ - { label: 'All', value: 'all' }, - { label: 'Completed', value: 'completed' }, - { label: 'Ongoing', value: 'ongoing' }, - ], - type: FilterTypes.Picker, - }, - genres: { - value: 'all', - label: 'Genre', - options: [ - { label: 'All', value: 'all' }, - { label: 'Action', value: 'action' }, - { label: 'Adventure', value: 'adventure' }, - { label: 'Drama', value: 'drama' }, - { label: 'Fantasy', value: 'fantasy' }, - { label: 'Harem', value: 'harem' }, - { label: 'Martial Arts', value: 'martial-arts' }, - { label: 'Mature', value: 'mature' }, - { label: 'Romance', value: 'romance' }, - { label: 'Tragedy', value: 'tragedy' }, - { label: 'Xuanhuan', value: 'xuanhuan' }, - { label: 'Ecchi', value: 'ecchi' }, - { label: 'Comedy', value: 'comedy' }, - { label: 'Slice of Life', value: 'slice-of-life' }, - { label: 'Mystery', value: 'mystery' }, - { label: 'Supernatural', value: 'supernatural' }, - { label: 'Psychological', value: 'psychological' }, - { label: 'Sci-fi', value: 'sci-fi' }, - { label: 'Xianxia', value: 'xianxia' }, - { label: 'School Life', value: 'school-life' }, - { label: 'Josei', value: 'josei' }, - { label: 'Wuxia', value: 'wuxia' }, - { label: 'Shounen', value: 'shounen' }, - { label: 'Horror', value: 'horror' }, - { label: 'Mecha', value: 'mecha' }, - { label: 'Historical', value: 'historical' }, - { label: 'Shoujo', value: 'shoujo' }, - { label: 'Adult', value: 'adult' }, - { label: 'Seinen', value: 'seinen' }, - { label: 'Sports', value: 'sports' }, - { label: 'Lolicon', value: 'lolicon' }, - { label: 'Gender Bender', value: 'gender-bender' }, - { label: 'Shounen Ai', value: 'shounen-ai' }, - { label: 'Yaoi', value: 'yaoi' }, - { label: 'Video Games', value: 'video-games' }, - { label: 'Smut', value: 'smut' }, - { label: 'Magical Realism', value: 'magical-realism' }, - { label: 'Eastern Fantasy', value: 'eastern-fantasy' }, - { label: 'Contemporary Romance', value: 'contemporary-romance' }, - { label: 'Fantasy Romance', value: 'fantasy-romance' }, - { label: 'Shoujo Ai', value: 'shoujo-ai' }, - { label: 'Yuri', value: 'yuri' }, - ], - type: FilterTypes.Picker, - }, - } satisfies Filters; -} - -export default new LightNovelPub(); - -enum ParsingState { - Idle, - Novel, - HeaderStats, - Status, - Stopped, - Chapter, - ChapterItem, - ChapterList, - TotalChapters, - NovelName, - AuthorName, - Summary, - Genres, - Tags, - Cover, -} From d87359dccfb360d4f621fef655ea46ca6248059e Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:14:27 -0500 Subject: [PATCH 02/11] chore: Obsolete plugin --- plugins/english/novelfire.paged.ts | 382 ----------------------------- 1 file changed, 382 deletions(-) delete mode 100644 plugins/english/novelfire.paged.ts diff --git a/plugins/english/novelfire.paged.ts b/plugins/english/novelfire.paged.ts deleted file mode 100644 index 6e2b449ab..000000000 --- a/plugins/english/novelfire.paged.ts +++ /dev/null @@ -1,382 +0,0 @@ -import { CheerioAPI, load } from 'cheerio'; -import { fetchApi } from '@libs/fetch'; -import { Plugin } from '@/types/plugin'; -import { NovelStatus } from '@libs/novelStatus'; -import { Filters, FilterTypes } from '@libs/filterInputs'; -import { defaultCover } from '@/types/constants'; - -class NovelFirePaged implements Plugin.PagePlugin { - id = 'novelfire.paged'; - name = 'Novel Fire Paged'; - version = '1.1.2'; - icon = 'src/en/novelfire/icon.png'; - site = 'https://novelfire.net/'; - - async getCheerio(url: string, search: boolean): Promise { - const r = await fetchApi(url); - if (!r.ok && search != true) - throw new Error( - 'Could not reach site (' + r.status + ') try to open in webview.', - ); - const $ = load(await r.text()); - - if ($('title').text().includes('Cloudflare')) { - throw new Error('Cloudflare is blocking requests. Try again later.'); - } - - return $; - } - - async popularNovels( - pageNo: number, - { - showLatestNovels, - filters, - }: Plugin.PopularNovelsOptions, - ): Promise { - let url = this.site + 'search-adv'; - if (showLatestNovels) { - url += `?ctgcon=and&totalchapter=0&ratcon=min&rating=0&status=-1&sort=date&tagcon=and&page=${pageNo}`; - } else if (filters) { - const params = new URLSearchParams(); - for (const language of filters.language.value) { - params.append('country_id[]', language); - } - params.append('ctgcon', filters.genre_operator.value); - for (const genre of filters.genres.value) { - params.append('categories[]', genre); - } - params.append('totalchapter', filters.chapters.value); - params.append('ratcon', filters.rating_operator.value); - params.append('rating', filters.rating.value); - params.append('status', filters.status.value); - params.append('sort', filters.sort.value); - params.append('page', pageNo.toString()); - url += `?${params.toString()}`; - } else { - url += `?ctgcon=and&totalchapter=0&ratcon=min&rating=0&status=-1&sort=rank-top&page=${pageNo}`; - } - - const loadedCheerio = await this.getCheerio(url, false); - - return loadedCheerio('.novel-item') - .map((index, ele) => { - const novelName = - loadedCheerio(ele).find('.novel-title > a').text() || - 'No Title Found'; - const novelCover = loadedCheerio(ele) - .find('.novel-cover > img') - .attr('data-src'); - const novelPath = loadedCheerio(ele) - .find('.novel-title > a') - .attr('href'); - - if (!novelPath) return; - - return { - name: novelName, - cover: novelCover, - path: novelPath.replace(this.site, ''), - }; - }) - .get() - .filter(novel => novel !== null); - } - - async parseNovel( - novelPath: string, - ): Promise { - const $ = await this.getCheerio(this.site + novelPath, false); - const baseUrl = this.site; - - const novel: Partial = { - path: novelPath, - }; - - novel.name = - $('.novel-title').text().trim() ?? - $('.cover > img').attr('alt') ?? - 'No Titled Found'; - const coverUrl = - $('.cover > img').attr('data-src') ?? $('.cover > img').attr('src'); - - if (coverUrl) { - novel.cover = new URL(coverUrl, baseUrl).href; - } else { - novel.cover = defaultCover; - } - - novel.genres = $('.categories .property-item') - .map((i, el) => $(el).text()) - .toArray() - .join(','); - - let summary = $('.summary .content').text().trim(); - - if (summary) { - summary = summary.replace('Show More', ''); - novel.summary = summary; - } else { - novel.summary = 'No Summary Found'; - } - - novel.author = $('.author .property-item > span').text(); - - const rawStatus = - $('.header-stats .ongoing').text() || - $('.header-stats .completed').text() || - 'Unknown'; - const map: Record = { - ongoing: NovelStatus.Ongoing, - hiatus: NovelStatus.OnHiatus, - dropped: NovelStatus.Cancelled, - cancelled: NovelStatus.Cancelled, - completed: NovelStatus.Completed, - unknown: NovelStatus.Unknown, - }; - novel.status = map[rawStatus.toLowerCase()] ?? NovelStatus.Unknown; - - novel.rating = parseFloat($('.nub').text().trim()); - - const totalChapters = $('.header-stats .icon-book-open') - .parent() - .text() - .trim(); - - novel.totalPages = Math.ceil(parseInt(totalChapters) / 100); - - return novel as Plugin.SourceNovel & { totalPages: number }; - } - - async parsePage(novelPath: string, page: string): Promise { - const url = `${this.site}${novelPath}/chapters?page=${page}`; - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = load(body); - - const chapters = loadedCheerio('.chapter-list li') - .map((index, ele) => { - const chapterName = - loadedCheerio(ele).find('a').attr('title') || 'No Title Found'; - const chapterPath = loadedCheerio(ele).find('a').attr('href'); - - if (!chapterPath) return null; - - return { - name: chapterName, - path: chapterPath.replace(this.site, ''), - }; - }) - .get() - .filter(chapter => chapter !== null) as Plugin.ChapterItem[]; - - return { - chapters, - }; - } - - async parseChapter(chapterPath: string): Promise { - const url = this.site + chapterPath; - const loadedCheerio = await this.getCheerio(url, false); - - const chapterText = loadedCheerio('#content'); - - loadedCheerio(chapterText).find('div').remove(); - - return chapterText.html()?.replace(/ /g, ' ') || ''; - } - - async searchNovels( - searchTerm: string, - page: number, - ): Promise { - const url = `${this.site}search?keyword=${encodeURIComponent(searchTerm)}&page=${page}`; - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = load(body); - - return loadedCheerio('.novel-list.chapters .novel-item') - .map((index, ele) => { - const novelName = - loadedCheerio(ele).find('a').attr('title') || 'No Title Found'; - const novelCover = loadedCheerio(ele) - .find('.novel-cover > img') - .attr('src'); - const novelPath = loadedCheerio(ele).find('a').attr('href'); - - if (!novelPath) return null; - - return { - name: novelName, - cover: novelCover, - path: novelPath.replace(this.site, ''), - }; - }) - .get() - .filter(novel => novel !== null); - } - - filters = { - sort: { - label: 'Sort Results By', - value: 'rank-top', - options: [ - { label: 'Rank (Top)', value: 'rank-top' }, - { label: 'Rating Score (Top)', value: 'rating-score-top' }, - { label: 'Review Count (Most)', value: 'review' }, - { label: 'Comment Count (Most)', value: 'comment' }, - { label: 'Bookmark Count (Most)', value: 'bookmark' }, - { label: 'Today Views (Most)', value: 'today-view' }, - { label: 'Monthly Views (Most)', value: 'monthly-view' }, - { label: 'Total Views (Most)', value: 'total-view' }, - { label: 'Title (A>Z)', value: 'abc' }, - { label: 'Title (Z>A)', value: 'cba' }, - { label: 'Last Updated (Newest)', value: 'date' }, - { label: 'Chapter Count (Most)', value: 'chapter-count-most' }, - ], - type: FilterTypes.Picker, - }, - status: { - label: 'Translation Status', - value: '-1', - options: [ - { label: 'All', value: '-1' }, - { label: 'Completed', value: '1' }, - { label: 'Ongoing', value: '0' }, - ], - type: FilterTypes.Picker, - }, - genre_operator: { - label: 'Genres (And/Or/Exclude)', - value: 'and', - options: [ - { label: 'AND', value: 'and' }, - { label: 'OR', value: 'or' }, - { label: 'EXCLUDE', value: 'exclude' }, - ], - type: FilterTypes.Picker, - }, - genres: { - label: 'Genres', - value: [], - options: [ - { label: 'Action', value: '3' }, - { label: 'Adult', value: '28' }, - { label: 'Adventure', value: '4' }, - { label: 'Anime', value: '46' }, - { label: 'Arts', value: '47' }, - { label: 'Comedy', value: '5' }, - { label: 'Drama', value: '24' }, - { label: 'Eastern', value: '44' }, - { label: 'Ecchi', value: '26' }, - { label: 'Fan-fiction', value: '48' }, - { label: 'Fantasy', value: '6' }, - { label: 'Game', value: '19' }, - { label: 'Gender Bender', value: '25' }, - { label: 'Harem', value: '7' }, - { label: 'Historical', value: '12' }, - { label: 'Horror', value: '37' }, - { label: 'Isekai', value: '49' }, - { label: 'Josei', value: '2' }, - { label: 'Lgbt+', value: '45' }, - { label: 'Magic', value: '50' }, - { label: 'Magical Realism', value: '51' }, - { label: 'Manhua', value: '52' }, - { label: 'Martial Arts', value: '15' }, - { label: 'Mature', value: '8' }, - { label: 'Mecha', value: '34' }, - { label: 'Military', value: '53' }, - { label: 'Modern Life', value: '54' }, - { label: 'Movies', value: '55' }, - { label: 'Mystery', value: '16' }, - { label: 'Other', value: '64' }, - { label: 'Psychological', value: '9' }, - { label: 'Realistic Fiction', value: '56' }, - { label: 'Reincarnation', value: '43' }, - { label: 'Romance', value: '1' }, - { label: 'School Life', value: '21' }, - { label: 'Sci-fi', value: '20' }, - { label: 'Seinen', value: '10' }, - { label: 'Shoujo', value: '38' }, - { label: 'Shoujo Ai', value: '57' }, - { label: 'Shounen', value: '17' }, - { label: 'Shounen Ai', value: '39' }, - { label: 'Slice of Life', value: '13' }, - { label: 'Smut', value: '29' }, - { label: 'Sports', value: '42' }, - { label: 'Supernatural', value: '18' }, - { label: 'System', value: '58' }, - { label: 'Tragedy', value: '32' }, - { label: 'Urban', value: '63' }, - { label: 'Urban Life', value: '59' }, - { label: 'Video Games', value: '60' }, - { label: 'War', value: '61' }, - { label: 'Wuxia', value: '31' }, - { label: 'Xianxia', value: '23' }, - { label: 'Xuanhuan', value: '22' }, - { label: 'Yaoi', value: '14' }, - { label: 'Yuri', value: '62' }, - ], - type: FilterTypes.CheckboxGroup, - }, - language: { - label: 'Language', - value: [], - options: [ - { label: 'Chinese', value: '1' }, - { label: 'Korean', value: '2' }, - { label: 'Japanese', value: '3' }, - { label: 'English', value: '4' }, - ], - type: FilterTypes.CheckboxGroup, - }, - rating_operator: { - label: 'Rating (Min/Max)', - value: 'min', - options: [ - { label: 'Min', value: 'min' }, - { label: 'Max', value: 'max' }, - ], - type: FilterTypes.Picker, - }, - rating: { - label: 'Rating', - value: '0', - options: [ - { label: 'All', value: '0' }, - { label: '1', value: '1' }, - { label: '2', value: '2' }, - { label: '3', value: '3' }, - { label: '4', value: '4' }, - { label: '5', value: '5' }, - ], - type: FilterTypes.Picker, - }, - chapters: { - label: 'Chapters', - value: '0', - options: [ - { label: 'All', value: '0' }, - { label: '<50', value: '1,49' }, - { label: '50-100', value: '50,100' }, - { label: '100-200', value: '100,200' }, - { label: '200-500', value: '200,500' }, - { label: '500-1000', value: '500,1000' }, - { label: '>1000', value: '1001,1000000' }, - ], - type: FilterTypes.Picker, - }, - } satisfies Filters; -} - -export default new NovelFirePaged(); - -// Custom error for when Novel Fire is rate limiting requests -class NovelFireThrottlingError extends Error { - constructor(message = 'Novel Fire is rate limiting requests') { - super(message); - this.name = 'NovelFireError'; - } -} From 8e1e89c2899bcf1112fefc9073a9edbbef277684 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:34:37 -0500 Subject: [PATCH 03/11] chore: Down site --- plugins/english/{readlitenovel.ts => readlitenovel.broken.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/english/{readlitenovel.ts => readlitenovel.broken.ts} (100%) diff --git a/plugins/english/readlitenovel.ts b/plugins/english/readlitenovel.broken.ts similarity index 100% rename from plugins/english/readlitenovel.ts rename to plugins/english/readlitenovel.broken.ts From 539c4070b93c19afcc9f7aee929b712bf087c9c1 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:35:44 -0500 Subject: [PATCH 04/11] chore: Down site --- plugins/english/{reaperscans.ts => reaperscans.broken.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/english/{reaperscans.ts => reaperscans.broken.ts} (100%) diff --git a/plugins/english/reaperscans.ts b/plugins/english/reaperscans.broken.ts similarity index 100% rename from plugins/english/reaperscans.ts rename to plugins/english/reaperscans.broken.ts From d72a7acad0400b61a6d7a474f96244377f67149b Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:38:07 -0500 Subject: [PATCH 05/11] chore: Down site --- plugins/english/{bestlightnovel.ts => bestlightnovel.broken.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/english/{bestlightnovel.ts => bestlightnovel.broken.ts} (100%) diff --git a/plugins/english/bestlightnovel.ts b/plugins/english/bestlightnovel.broken.ts similarity index 100% rename from plugins/english/bestlightnovel.ts rename to plugins/english/bestlightnovel.broken.ts From c54f8059496e8b9116a98b80992b83ed366f5c40 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 16:39:14 -0500 Subject: [PATCH 06/11] chore: Down site --- plugins/english/{earlynovel.ts => earlynovel.broken.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/english/{earlynovel.ts => earlynovel.broken.ts} (100%) diff --git a/plugins/english/earlynovel.ts b/plugins/english/earlynovel.broken.ts similarity index 100% rename from plugins/english/earlynovel.ts rename to plugins/english/earlynovel.broken.ts From 142cd72409653dd0ae18746fd6e174a7b4a17152 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 17:17:57 -0500 Subject: [PATCH 07/11] chore: Source announced termination --- plugins/multisrc/lightnovelworld/sources.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/multisrc/lightnovelworld/sources.json b/plugins/multisrc/lightnovelworld/sources.json index 67731c249..922937c4e 100644 --- a/plugins/multisrc/lightnovelworld/sources.json +++ b/plugins/multisrc/lightnovelworld/sources.json @@ -4,11 +4,6 @@ "sourceName": "Web Novel Pub", "sourceSite": "https://www.webnovelworld.org/" }, - { - "id": "lightnovelworld", - "sourceName": "LightNovelWord", - "sourceSite": "https://www.lightnovelworld.com/" - }, { "id": "lightnovelpubvip", "sourceName": "LightNovelPub Vip", From cfd10711bf09ad2c9c083e2180a45d2ab1379ac6 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 19:03:38 -0500 Subject: [PATCH 08/11] chore: Down site --- plugins/french/{phenixscans.ts => phenixscans.broken.ts} | 0 plugins/indonesian/{novelringan.ts => novelringan.broken.ts} | 0 plugins/russian/{LitSpace.ts => LitSpace.broken.ts} | 0 plugins/russian/{novelOvh.ts => novelOvh.broken.ts} | 0 plugins/russian/{ruvers.ts => ruvers.broken.ts} | 0 plugins/ukrainian/{uaranobeclub.ts => uaranobeclub.broken.ts} | 0 plugins/vietnamese/{Truyenconect.ts => Truyenconect.broken.ts} | 0 plugins/vietnamese/{truyenchu.ts => truyenchu.broken.ts} | 0 plugins/vietnamese/{truyenfull.ts => truyenfull.broken.ts} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename plugins/french/{phenixscans.ts => phenixscans.broken.ts} (100%) rename plugins/indonesian/{novelringan.ts => novelringan.broken.ts} (100%) rename plugins/russian/{LitSpace.ts => LitSpace.broken.ts} (100%) rename plugins/russian/{novelOvh.ts => novelOvh.broken.ts} (100%) rename plugins/russian/{ruvers.ts => ruvers.broken.ts} (100%) rename plugins/ukrainian/{uaranobeclub.ts => uaranobeclub.broken.ts} (100%) rename plugins/vietnamese/{Truyenconect.ts => Truyenconect.broken.ts} (100%) rename plugins/vietnamese/{truyenchu.ts => truyenchu.broken.ts} (100%) rename plugins/vietnamese/{truyenfull.ts => truyenfull.broken.ts} (100%) diff --git a/plugins/french/phenixscans.ts b/plugins/french/phenixscans.broken.ts similarity index 100% rename from plugins/french/phenixscans.ts rename to plugins/french/phenixscans.broken.ts diff --git a/plugins/indonesian/novelringan.ts b/plugins/indonesian/novelringan.broken.ts similarity index 100% rename from plugins/indonesian/novelringan.ts rename to plugins/indonesian/novelringan.broken.ts diff --git a/plugins/russian/LitSpace.ts b/plugins/russian/LitSpace.broken.ts similarity index 100% rename from plugins/russian/LitSpace.ts rename to plugins/russian/LitSpace.broken.ts diff --git a/plugins/russian/novelOvh.ts b/plugins/russian/novelOvh.broken.ts similarity index 100% rename from plugins/russian/novelOvh.ts rename to plugins/russian/novelOvh.broken.ts diff --git a/plugins/russian/ruvers.ts b/plugins/russian/ruvers.broken.ts similarity index 100% rename from plugins/russian/ruvers.ts rename to plugins/russian/ruvers.broken.ts diff --git a/plugins/ukrainian/uaranobeclub.ts b/plugins/ukrainian/uaranobeclub.broken.ts similarity index 100% rename from plugins/ukrainian/uaranobeclub.ts rename to plugins/ukrainian/uaranobeclub.broken.ts diff --git a/plugins/vietnamese/Truyenconect.ts b/plugins/vietnamese/Truyenconect.broken.ts similarity index 100% rename from plugins/vietnamese/Truyenconect.ts rename to plugins/vietnamese/Truyenconect.broken.ts diff --git a/plugins/vietnamese/truyenchu.ts b/plugins/vietnamese/truyenchu.broken.ts similarity index 100% rename from plugins/vietnamese/truyenchu.ts rename to plugins/vietnamese/truyenchu.broken.ts diff --git a/plugins/vietnamese/truyenfull.ts b/plugins/vietnamese/truyenfull.broken.ts similarity index 100% rename from plugins/vietnamese/truyenfull.ts rename to plugins/vietnamese/truyenfull.broken.ts From 4d8447bf6d62cb64d31d46ee7a7638f68ca1643e Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 20:55:30 -0500 Subject: [PATCH 09/11] chore: Mark multisrc downs --- plugins/multisrc/fictioneer/sources.json | 4 +- plugins/multisrc/hotnovelpub/sources.json | 14 +++-- plugins/multisrc/lightnovelwp/sources.json | 28 +++++++--- plugins/multisrc/madara/sources.json | 61 +++++++++++++++++----- plugins/multisrc/readwn/sources.json | 14 +++-- 5 files changed, 92 insertions(+), 29 deletions(-) diff --git a/plugins/multisrc/fictioneer/sources.json b/plugins/multisrc/fictioneer/sources.json index 103a10071..96c1d52e0 100644 --- a/plugins/multisrc/fictioneer/sources.json +++ b/plugins/multisrc/fictioneer/sources.json @@ -49,7 +49,9 @@ "sourceSite": "https://dearestrosalie.com", "sourceName": "Dearest Rosalie", "options": { - "browsePage": "stories" + "browsePage": "stories", + "down": true, + "downSince": "2026-01-12" } } ] diff --git a/plugins/multisrc/hotnovelpub/sources.json b/plugins/multisrc/hotnovelpub/sources.json index 5d56c9aa8..24521d6bc 100644 --- a/plugins/multisrc/hotnovelpub/sources.json +++ b/plugins/multisrc/hotnovelpub/sources.json @@ -233,7 +233,9 @@ } }, "options": { - "lang": "es" + "lang": "es", + "down": true, + "downSince": "2026-01-12" } }, { @@ -313,7 +315,9 @@ } }, "options": { - "lang": "pt" + "lang": "pt", + "down": true, + "downSince": "2026-01-12" } }, { @@ -381,7 +385,9 @@ } }, "options": { - "lang": "th" + "lang": "th", + "down": true, + "downSince": "2026-01-12" } } -] \ No newline at end of file +] diff --git a/plugins/multisrc/lightnovelwp/sources.json b/plugins/multisrc/lightnovelwp/sources.json index 078e5d468..97b15d957 100644 --- a/plugins/multisrc/lightnovelwp/sources.json +++ b/plugins/multisrc/lightnovelwp/sources.json @@ -53,7 +53,9 @@ "sourceName": "AllNovelRead", "options": { "lang": "Spanish", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -106,7 +108,9 @@ "sourceName": "Panda Machine Translations", "options": { "lang": "English", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -163,7 +167,9 @@ "options": { "versionIncrements": 1, "lang": "English", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -181,7 +187,9 @@ "sourceName": "ElloTL", "options": { "lang": "English", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -199,7 +207,9 @@ "sourceName": "CPUnovel", "options": { "lang": "English", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -218,7 +228,9 @@ "sourceSite": "https://betternovels.net/", "sourceName": "Better Novels", "options": { - "lang": "Portuguese" + "lang": "Portuguese", + "down": true, + "downSince": "2026-01-12" } }, { @@ -274,7 +286,9 @@ "sourceName": "Keopi Translations", "options": { "lang": "English", - "reverseChapters": true + "reverseChapters": true, + "down": true, + "downSince": "2026-01-12" } }, { diff --git a/plugins/multisrc/madara/sources.json b/plugins/multisrc/madara/sources.json index de9884969..9b861e877 100644 --- a/plugins/multisrc/madara/sources.json +++ b/plugins/multisrc/madara/sources.json @@ -3,7 +3,10 @@ "id": "novelTL", "sourceSite": "https://noveltranslate.com/", "sourceName": "NovelTranslate", - "options": {} + "options": { + "down": true, + "downSince": "2026-01-12" + } }, { "id": "lunarletters", @@ -81,7 +84,11 @@ { "id": "webnovelover", "sourceSite": "https://www.webnovelover.com/", - "sourceName": "WebNovelLover" + "sourceName": "WebNovelLover", + "options": { + "down": true, + "downSince": "2026-01-12" + } }, { "id": "wbnovel", @@ -167,7 +174,9 @@ "sourceSite": "https://guavaread.com/", "sourceName": "Guavaread", "options": { - "useNewChapterEndpoint": true + "useNewChapterEndpoint": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -181,7 +190,9 @@ "sourceName": "MTL-Novel", "options": { "useNewChapterEndpoint": false, - "versionIncrements": 1 + "versionIncrements": 1, + "down": true, + "downSince": "2026-01-12" } }, { @@ -203,7 +214,11 @@ { "id": "LightNovelUpdates", "sourceSite": "https://www.lightnovelupdates.com/", - "sourceName": "Light Novel Updates" + "sourceName": "Light Novel Updates", + "options": { + "down": true, + "downSince": "2026-01-12" + } }, { "id": "foxaholic", @@ -226,7 +241,9 @@ "sourceSite": "https://kiniga.com/", "sourceName": "Kiniga", "options": { - "lang": "Portuguese" + "lang": "Portuguese", + "down": true, + "downSince": "2026-01-12" } }, { @@ -342,7 +359,9 @@ "sourceName": "Meownovel", "options": { "useNewChapterEndpoint": true, - "lang": "English" + "lang": "English", + "down": true, + "downSince": "2026-01-12" } }, { @@ -352,7 +371,9 @@ "options": { "useNewChapterEndpoint": true, "versionIncrements": 3, - "lang": "English" + "lang": "English", + "down": true, + "downSince": "2026-01-12" } }, { @@ -361,7 +382,9 @@ "sourceName": "Olaoe.cyou", "options": { "useNewChapterEndpoint": true, - "lang": "Arabic" + "lang": "Arabic", + "down": true, + "downSince": "2026-01-12" } }, { @@ -443,7 +466,9 @@ "sourceName": "Novel oku", "options": { "useNewChapterEndpoint": true, - "lang": "Turkish" + "lang": "Turkish", + "down": true, + "downSince": "2026-01-12" } }, { @@ -452,7 +477,9 @@ "sourceName": "NABİ SCANS", "options": { "useNewChapterEndpoint": true, - "lang": "Turkish" + "lang": "Turkish", + "down": true, + "downSince": "2026-01-12" } }, { @@ -515,7 +542,9 @@ "sourceName": "Violet Lily", "options": { "lang": "English", - "useNewChapterEndpoint": true + "useNewChapterEndpoint": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -524,7 +553,9 @@ "sourceName": "Sweet Escape", "options": { "lang": "English", - "useNewChapterEndpoint": true + "useNewChapterEndpoint": true, + "down": true, + "downSince": "2026-01-12" } }, { @@ -541,7 +572,9 @@ "sourceSite": "https://animeshoy12.com/", "sourceName": "AnimesHoy12", "options": { - "lang": "Spanish" + "lang": "Spanish", + "down": true, + "downSince": "2026-01-12" } }, { diff --git a/plugins/multisrc/readwn/sources.json b/plugins/multisrc/readwn/sources.json index 48eae65be..f28c2a84e 100644 --- a/plugins/multisrc/readwn/sources.json +++ b/plugins/multisrc/readwn/sources.json @@ -7,7 +7,11 @@ { "id": "wuxiacity", "sourceSite": "https://www.wuxiafox.com", - "sourceName": "Wuxiafox" + "sourceName": "Wuxiafox", + "options": { + "down": true, + "downSince": "2026-01-12" + } }, { "id": "ltnovel", @@ -44,6 +48,10 @@ { "id": "wuxiav", "sourceSite": "https://www.wuxiav.com", - "sourceName": "WuxiaV" + "sourceName": "WuxiaV", + "options": { + "down": true, + "downSince": "2026-01-12" + } } -] \ No newline at end of file +] From 9ccf660a102b81ea9318e002536b4a8595768985 Mon Sep 17 00:00:00 2001 From: Rojikku Date: Sun, 11 Jan 2026 21:05:40 -0500 Subject: [PATCH 10/11] chore: Update icons --- .../fictioneer/prizmatranslation/icon.png | Bin 1670 -> 2192 bytes .../lightnovelworld/lightnovelworld/icon.png | Bin 2164 -> 0 bytes .../multisrc/lightnovelwp/arcane/icon.png | Bin 2970 -> 2174 bytes .../lightnovelwp/freekolnovel/icon.png | Bin 0 -> 2333 bytes .../multisrc/lightnovelwp/kolnovel/icon.png | Bin 5366 -> 2333 bytes .../multisrc/lightnovelwp/noveltr/icon.png | Bin 1183 -> 1560 bytes .../static/multisrc/madara/morenovel/icon.png | Bin 1001 -> 706 bytes .../static/multisrc/madara/mostnovel/icon.png | Bin 1772 -> 5322 bytes .../madara/webnoveltraslation/icon.png | Bin 0 -> 291 bytes public/static/src/en/leafstudio/icon.png | Bin 0 -> 1845 bytes public/static/src/en/lightnovelpub/icon.png | Bin 2164 -> 0 bytes 11 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/static/multisrc/lightnovelworld/lightnovelworld/icon.png create mode 100644 public/static/multisrc/lightnovelwp/freekolnovel/icon.png create mode 100644 public/static/multisrc/madara/webnoveltraslation/icon.png create mode 100644 public/static/src/en/leafstudio/icon.png delete mode 100644 public/static/src/en/lightnovelpub/icon.png diff --git a/public/static/multisrc/fictioneer/prizmatranslation/icon.png b/public/static/multisrc/fictioneer/prizmatranslation/icon.png index 42deacf5d5632063d328d486c5e70ea820ea0133..958b50632036f4e7f263f033da490b55ac15bb40 100644 GIT binary patch literal 2192 zcmV;B2ygd^P)$a#kTtXZ+Iy)FpU*=FW%?pt&l%`lHk|ZFj`Ea@oYMs15Ib+Q8ZZ$ zym1IkMpGGUYCnnDX!#$QFQS=))@#K%Pk9)XxG#~$7k7)XiJJalU5Yc=X`(HvV z2TI>Ud>B>Z&)6eHAF!Xib!~{IgOwQlhW&6Q79U#Qr11d$%MXIbr}t)>{DnQx{0+ii z`M*O5@t5|0WZ)9}`X3O2@=GQtpRo`CAVn^KV*EoK!t2*z*&`Byh}-^#cQCqE?7=jeeMtau3!or?zlR`v zH~3OO$lOYBY%BhHeFneARhkled{5J&c;zzoAUrn&>a&PJe9gW*uU1KN%u$0=U7t=U zKJZV`7x#b;j*R zWmI$kP(|{~qb6q%0=~RZQcb|Z{k!D)z~KV`z#d{m*JjD}8$RWitJZ-^hi9ZI14OR; zWFU?obnRX+Kc{G7t*$@`%n3vQJAJ#NvYTg?^r!&JU#{4{#~U$5^RS7e0TAa+O)6}u zHhC&Uewl;Yb4;*O1<)anWzWGynI#Z`RKQqrRhW7)gx=eehZ6z-{>rHaQwyX5ge|E6 zR`OK9II<5K84HzSs<_2c+A25@GJkBT_)#)6j;AJGnSe7O(;=E1Z@QReJ$) zA-6BWT(j?z@j)p7QM!*+Kz3gX-%9dwLV%i%pNoAxIALL5ER}_*I1KCJ!ARr<%7w<3 zXzmxfoB$}rSOLpGVaPjW10A7IFDwsG~)3lO<2@lK2LL1jK)DzMkkesyRvc~iD=K~=0PzEW7e!hF+xV>p zApjXS{QyoLFhFVA$AC%nz+py_)BxCkZM-mb0OHaBu<1xq6nhTFKK8L=fYb$u+`&fj zK(kVvoWcEgq|Pq(j|D03C+sfpK!AE}eK+xXioHJ2pq=oEPdFDq(6PA-9hyt8T(#UOv@dVHfGrOqXF`U*I3>_mVQ?Z{3*H}{k_8v#53 z6A1!f6g74X%)Gu!a@WF{aEO0C?v+T~-kp>StZPS3+k&iaYi{ho3+H`ng?<3=Fe`xP z&9|@tmhSwAvL2KQ*ca`+7Q%%S+yO&VfeJKskj<%ebezC}T5@mdIobh`$e(5rQlO}$ zG%uM2#sk&bm81gL$6?Tyr_z&faE z3S(xj?g#D=E3#WAxO1#f6^X`>wql=QP{wkdzpf`Od&@uFJadBY!k|+i zunQ44-sH5K3hs}nz+&y}`0wp=Ph*ol}AKA^S|Pqf`&mX`m2l-mIl`jyYv+{$-Ol zjmK(Q<8EFL=oE-q7t`5ruml{n%P*)7Oy*ogQr2y!RO~XV1jNC(pwbEyjbj5Fc5`gc$T}c^>`# zXDExeKdq3nKmIo4Yia(l#g%>b2jNYcjHaHk=KtrnGX^au(P)e`8by=gy#E2!Cwd(c SeZ4UN0000sf^+ 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 A761SM literal 2970 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 diff --git a/public/static/multisrc/lightnovelwp/freekolnovel/icon.png b/public/static/multisrc/lightnovelwp/freekolnovel/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c232aac647a359c143c38f50d2ae1ae3320d5ace GIT binary patch literal 2333 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 U{d$@dkpKVy07*qoM6N<$f^XmMdH?_b diff --git a/public/static/multisrc/lightnovelwp/noveltr/icon.png b/public/static/multisrc/lightnovelwp/noveltr/icon.png index 76a7ccd5afd7c595248ef2a5145d79db2116d0e3..80eac7542610b755b3ed06f558025d960fb77e4a 100644 GIT binary patch delta 1542 zcmV+h2Ko7)378C!B!4GROjJcja7-OYQxi>E6--zdNmUL{UJy=P1yNx-v$r*(sSsjs z9d>~#j+SoHa#a8T00(qZPE!CZs)APN%ruE}?*IS=nMp)JRA_Q9JoAb%*7pSF=xByAoSwqHgV@^^9y$CqRoSAG$p^Sg5odi(HGM|i@tzLj49 z{K2+?0I{UZKAoF;`Go>~#lw#s!IwDk2Y1!z)O+JUno%0K|dsk5ew{eZSB7>vP(&=FB6eo8emof zHYT_xk$={f+LQHPH4`T&c9Mau1r98AfF=}@PBq_fDfF^5!RF;62i1*@! zMsegDbmh1v8jRDsR;9+WRKRU09-%V8V-uH1JbOcIT+DY5a{q# z*cwpxbD98_*tIpn_cs^Nv^St3BOj(4+fnpEet%_ad72IewD5(HHM45tFCt?>{8Up%+y&4-Fu<$lqrAqS?&g4n%|s~VTEQw7$zb>qLE^!v-Ax>8NAY3 z#Rk31fKfcrCaNG1F&x7zDgG}qi7IZd!>}ANOOrWwF`jU zXv9%{bpqNz-FEuu2HY0lb|pU0so+HY`scrSS(=h5j`+0JKmKzU>&xysPLY#F;@e0$2_(Ob>u<7Jmwm z1illx3FO?S18A$wV`k>58006rP_XS=P*@@bAoXp#m z40UL>t~12iF!|-(O+t!|4T$}s>8|Am4HggeI6C)U$VYjkvFhvHP=reDno2Qa?hL5@ z@^-|I?`BbeZr!@fV#2N{XeHYs{(sHcfYpTRpqSZ|Q<_~SKfKUP{zKH>X~> zGnZo))M_4g#{F>%Sh|i3(n$;fwpLZD7nkF4(s7T?g~P>+>~_xL+9iRxpnq*Xo_M8a z4k9!F0;W+YV7fld*XcZR$bWW*Ju)zMsi1vxe}YNv0D$uE2!O=`-D68@@mMIFDCpbq zxqLE$&HEWM6u%B9zbJp57Vd25+O+J0j)_~2dsci+{zQNYwMA$5OWIH{vehg8nJ$4( zR8yaX?Lxs!Rqxz^%(F$u<9{Xy0FnvcyTzedpE-pW;92sH3GTSaEmz!~^s*`ClY6cQ zFJ1LGxlC&9Uzu+bE7zZ12HMR%W?V<{x9`xNKzvbrUHA8;e{oYv%{X8<{g=vYZu}KMJZdC`udgr@A}WzA99kDTg+zGZU6uP07*qoM6N<$f(UBcivR!s delta 1163 zcmV;61a$kD44(;*B!5CsOjJcja7+^s8WRy36A>B{5gHQ_8WRy36A>B{5gHN@8UO$P z0009C1`>RGfB5+Lt*oy^LrCJ{<0&XF$H&NBTw#-vmGDO{(f|Me3UpFVQvfhc|M1pp zxRMkQ-!&Nk00aU_L_t(&fz4Xkf~z159TxPuY$H0BIxyPIV5@WDEmVehF1m*NRPyp^ z_nY}M&>EOPFn{u!;W^PJFd8`d=B4$QHi6W@$!~_Y*5l0CfGgm#cX;R@o{R~&29BR* zo~#1R#Q9fXVfk!%7`{%veltF58ZhH3E`QByTomXB=cE=2G+Td$=PF-MT%4gWumxiH zcmsH<0=2d0e&HzUF}~O^q)uY{%R*7F;LVzlFsWt@Fn^;C!BMqo;x1Yc;Wf^z0$F5$ znRNn|s*wqN1m3BFBC4_m44+hfMoDUS6Zj@M9To6Y-H6n4MIxf;29~PA=K@#dd=*W> zQnk(uaZ1rG&ddbheZ+YvEJ883k|gptbfjo@oU0rT!4Y1-QMJn|6L5srIA_dZObE>9 zNq{LBE`JCWW57Uy`Eiwz1(#6g)Cog@`E8exX7h_eMyj#n=%_~w{GiGxur9y~#ZoL9 z`ov%r5G)`wTax|6c!c}(L3K}Bfpv~6$%qNA6q$+Yo}>cT zC++kAHB5`AHxCarslZI$&2XIUgD=wtUR5attAFclSJ~(4G{S2sN4uxMX}Xc;iNyKc z1kS^{r^GXPbBnd#0C9FQeJ{cWJzPQHm6eQ8g!lgJ{2rC#bq z4U{AS9}mD$ZmFu{_M~9_OR4G)2(gcl4z^2O${+NdF)2y@h!gt=X<*})x}PIOJz}bQ z55+!$OS9gK4_um7L{#0c6T)Q1hxL`4_@$5v1MC)XXMKTb=ufc70Q#{P6HSanDBWJ@QFly=K&h9N5N2s0snA0Cx-M!iocL5 zL;IJ4zcDHTuyZNgsnCFKPT70q0ti6 dJM+KeA9Kl;{Us*4h5!Hn07*qoLFnTL!H)p z?EL@dHi@UU7CcfOHeu{riAh9S})#QGQ}zJ^+?WB*F34_5i?JDj^97>e>*XeE`DZ=AZS4!x96u zP$`dV1O)(C>wixE-XtjOrcjK7LlS(o|2=5e@LM~Tb`Ln#(F6hjlC#w@;G3Y0g#!ol zHspEt(9#IYCz@!WRc@>LNJH2FB7hmRN+bb6QFX>M88k;7L(3vAon+{rA_)kJb)5jv z=u>SKdPGv0>DmIcDv~roY1w3Z5mZjzR`q>ln$8z5Ab%Okw`(ZqgCu=Va{B4@UEkoelO##h zqe%lmLH}w*6QqYL7!c6v)>d_ofTm6kM;~%B2-11jLNQ5N0<>i!0FX3;h;iz%2_%xF z!gz@_Tz@9C<5L8g05qXR7(24%lcAvVuohU;h||iQgt=Xs0O+CPF!y8oDS=k*C~Ujy zyj74r3}Uj^Z|^b0C&_Ws9sn#qr34i`=Qt#}KGc6NA`iWV>!f`ElO*5f7QA>F1?_v# zq9-*hXwM*)0$@RV7Pl0D3flIcX8_u@S5ZLFzaw}ztpF9E0#twsPywFt1EfKT>-LX> Q&j0`b07*qoM6N<$f_YajjsO4v delta 979 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 diff --git a/public/static/multisrc/madara/webnoveltraslation/icon.png b/public/static/multisrc/madara/webnoveltraslation/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3bd1625af5be83bb80022f7faaf814b764b4a428 GIT binary patch literal 291 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 Date: Tue, 13 Jan 2026 02:28:21 -0500 Subject: [PATCH 11/11] fix: Change to epoch dates --- plugins/multisrc/fictioneer/sources.json | 2 +- plugins/multisrc/hotnovelpub/sources.json | 6 ++--- plugins/multisrc/lightnovelwp/sources.json | 14 +++++------ plugins/multisrc/madara/sources.json | 28 +++++++++++----------- plugins/multisrc/readwn/sources.json | 4 ++-- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/plugins/multisrc/fictioneer/sources.json b/plugins/multisrc/fictioneer/sources.json index 96c1d52e0..7e0cb86b5 100644 --- a/plugins/multisrc/fictioneer/sources.json +++ b/plugins/multisrc/fictioneer/sources.json @@ -51,7 +51,7 @@ "options": { "browsePage": "stories", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212907 } } ] diff --git a/plugins/multisrc/hotnovelpub/sources.json b/plugins/multisrc/hotnovelpub/sources.json index 24521d6bc..1e9bb6863 100644 --- a/plugins/multisrc/hotnovelpub/sources.json +++ b/plugins/multisrc/hotnovelpub/sources.json @@ -235,7 +235,7 @@ "options": { "lang": "es", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212956 } }, { @@ -317,7 +317,7 @@ "options": { "lang": "pt", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212942 } }, { @@ -387,7 +387,7 @@ "options": { "lang": "th", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212962 } } ] diff --git a/plugins/multisrc/lightnovelwp/sources.json b/plugins/multisrc/lightnovelwp/sources.json index 97b15d957..02e6f9661 100644 --- a/plugins/multisrc/lightnovelwp/sources.json +++ b/plugins/multisrc/lightnovelwp/sources.json @@ -55,7 +55,7 @@ "lang": "Spanish", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212954 } }, { @@ -110,7 +110,7 @@ "lang": "English", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212928 } }, { @@ -169,7 +169,7 @@ "lang": "English", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212919 } }, { @@ -189,7 +189,7 @@ "lang": "English", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212947 } }, { @@ -209,7 +209,7 @@ "lang": "English", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212904 } }, { @@ -230,7 +230,7 @@ "options": { "lang": "Portuguese", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212945 } }, { @@ -288,7 +288,7 @@ "lang": "English", "reverseChapters": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212914 } }, { diff --git a/plugins/multisrc/madara/sources.json b/plugins/multisrc/madara/sources.json index 9b861e877..e3b5c7f75 100644 --- a/plugins/multisrc/madara/sources.json +++ b/plugins/multisrc/madara/sources.json @@ -5,7 +5,7 @@ "sourceName": "NovelTranslate", "options": { "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212925 } }, { @@ -87,7 +87,7 @@ "sourceName": "WebNovelLover", "options": { "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212967 } }, { @@ -176,7 +176,7 @@ "options": { "useNewChapterEndpoint": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212912 } }, { @@ -192,7 +192,7 @@ "useNewChapterEndpoint": false, "versionIncrements": 1, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212922 } }, { @@ -217,7 +217,7 @@ "sourceName": "Light Novel Updates", "options": { "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212916 } }, { @@ -243,7 +243,7 @@ "options": { "lang": "Portuguese", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212949 } }, { @@ -361,7 +361,7 @@ "useNewChapterEndpoint": true, "lang": "English", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212931 } }, { @@ -373,7 +373,7 @@ "versionIncrements": 3, "lang": "English", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212909 } }, { @@ -384,7 +384,7 @@ "useNewChapterEndpoint": true, "lang": "Arabic", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212938 } }, { @@ -468,7 +468,7 @@ "useNewChapterEndpoint": true, "lang": "Turkish", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212959 } }, { @@ -479,7 +479,7 @@ "useNewChapterEndpoint": true, "lang": "Turkish", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212965 } }, { @@ -544,7 +544,7 @@ "lang": "English", "useNewChapterEndpoint": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212936 } }, { @@ -555,7 +555,7 @@ "lang": "English", "useNewChapterEndpoint": true, "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212933 } }, { @@ -574,7 +574,7 @@ "options": { "lang": "Spanish", "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212951 } }, { diff --git a/plugins/multisrc/readwn/sources.json b/plugins/multisrc/readwn/sources.json index f28c2a84e..70627905f 100644 --- a/plugins/multisrc/readwn/sources.json +++ b/plugins/multisrc/readwn/sources.json @@ -10,7 +10,7 @@ "sourceName": "Wuxiafox", "options": { "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212969 } }, { @@ -51,7 +51,7 @@ "sourceName": "WuxiaV", "options": { "down": true, - "downSince": "2026-01-12" + "downSince": 1768289212940 } } ]