diff --git a/assets/radar-rules.js b/assets/radar-rules.js index cc3690f48..48c8667bc 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -71,7 +71,6 @@ 'ishuhui.com': { _name: '鼠绘漫画', www: [{ title: '鼠绘漫画', docs: 'https://docs.rsshub.app/anime.html#shu-hui-man-hua', source: '/comics/anime/:id', target: '/shuhui/comics/:id' }] }, 'www.chicagotribune.com': { _name: 'Chicago Tribune', www: [{ title: 'Chicago Tribune', docs: 'https://docs.rsshub.app/traditional_media.html#chicago-tribune', source: '/' }] }, 'haimaoba.com': { _name: '海猫吧', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#hai-mao-ba', source: '/catalog/:id', target: '/haimaoba/:id' }] }, - 'copymanga.com': { _name: '拷贝漫画', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kao-bei-man-hua', source: '/comic/:id/', target: '/manhuagui/comic/:id/5' }] }, 'pgyer.com': { _name: '蒲公英应用分发', www: [{ title: 'app更新', docs: 'https://docs.rsshub.app/program-update.html#pu-gong-ying-ying-yong-fen-fa', source: '/:app', target: '/pgyer/:app' }] }, 'wineyun.com': { _name: '酒云网', www: [{ title: '最新商品', docs: 'https://docs.rsshub.app/other.html#jiu-yun-wang', source: ['/:category'], target: '/wineyun/:category' }] }, 'epicgames.com': { _name: 'Epic Games', www: [{ title: '每周免费游戏', docs: 'https://docs.rsshub.app/game.html#epicgames-freegame', source: '/store/zh-CN/free-games', target: '/epicgames/freegames' }] }, diff --git a/docs/anime.md b/docs/anime.md index e39f3f40f..3a75aa7ec 100644 --- a/docs/anime.md +++ b/docs/anime.md @@ -695,7 +695,7 @@ Sources ### 漫画更新 - + ## 漫画 DB diff --git a/lib/router.js b/lib/router.js index bfc2adcf1..55e8ec8f7 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1001,10 +1001,10 @@ router.get('/tencentvideo/playlist/:id', lazyloadRouteHandler('./routes/tencent/ // router.get('/twmanhuagui/comic/:id/:chapterCnt?', lazyloadRouteHandler('./routes/twmanhuagui/comic')); // 拷贝漫画 -router.get('/copymanga/comic/:id/:chapterCnt?', lazyloadRouteHandler('./routes/copymanga/comic')); +// router.get('/copymanga/comic/:id/:chapterCnt?', lazyloadRouteHandler('./routes/copymanga/comic')); // 拷贝漫画 -router.get('/copymanga/comic/:id', lazyloadRouteHandler('./routes/copymanga/comic')); +// router.get('/copymanga/comic/:id', lazyloadRouteHandler('./routes/copymanga/comic')); // 動漫狂 router.get('/cartoonmad/comic/:id', lazyloadRouteHandler('./routes/cartoonmad/comic')); diff --git a/lib/routes/copymanga/comic.js b/lib/routes/copymanga/comic.js deleted file mode 100644 index c42a368b7..000000000 --- a/lib/routes/copymanga/comic.js +++ /dev/null @@ -1,74 +0,0 @@ -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -// 直接调用拷贝漫画的接口 -module.exports = async (ctx) => { - const { id } = ctx.params; - // 用于控制返回的章节数量 - const chapterCnt = Number(ctx.params.chapterCnt || 0); - // 获取漫画列表 - let bHasNextPage = false; - const iReqLimit = (ctx.queries && ctx.queries.limit) || 100; - let iReqOffSet = 0; - const strBaseUrl = `https://api.copymanga.com/api/v3/comic/${id}/group/default/chapters?`; - let chapterArray = []; - - do { - bHasNextPage = false; - // eslint-disable-next-line no-await-in-loop - const { data } = await got.get(strBaseUrl + 'limit=' + iReqLimit + '&offset=' + iReqOffSet); - const { code, results } = data; - - if (code !== 200) { - break; - } - - if (results.limit + results.offset < results.total) { - bHasNextPage = true; - } - iReqOffSet += iReqLimit; - - chapterArray = chapterArray.concat(results.list); - } while (bHasNextPage); - - chapterArray = chapterArray - .map(({ comic_path_word, uuid, name, size, datetime_created, index }) => ({ - link: 'https://copymanga.com/comic/' + comic_path_word + '/chapter/' + uuid, - title: name, - num: size, - updateTime: datetime_created, - index, - })) - .reverse(); - - // 获取漫画标题、介绍 - const { bookTitle, bookIntro } = await ctx.cache.tryGet(`https://copymanga.com/comic/${id}`, async () => { - const { data } = await got.get(`https://copymanga.com/comic/${id}`); - const $ = cheerio.load(data); - return { - bookTitle: $('.comicParticulars-title-right > ul > li > h6').text(), - bookIntro: $('.intro').text(), - }; - }); - - const genResult = (chapter) => ({ - link: chapter.link, - title: chapter.title, - description: ` -

${chapter.num}p

- `.trim(), - }); - - let itemsLen = chapterArray.length; - - if (chapterCnt > 0) { - itemsLen = chapterCnt; - } - - ctx.state.data = { - title: `拷贝漫画 - ${bookTitle}`, - link: `https://copymanga.com/comic/${id}`, - description: bookIntro, - item: chapterArray.map(genResult).slice(0, itemsLen), - }; -}; diff --git a/lib/v2/copymanga/comic.js b/lib/v2/copymanga/comic.js new file mode 100644 index 000000000..843da8116 --- /dev/null +++ b/lib/v2/copymanga/comic.js @@ -0,0 +1,110 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const host = 'copymanga.site'; +const baseUrl = `https://${host}`; +const apiBaseUrl = `https://api.${host}`; + +// 直接调用拷贝漫画的接口 +module.exports = async (ctx) => { + const { id } = ctx.params; + // 用于控制返回的章节数量 + const chapterCnt = Number(ctx.params.chapterCnt || 0); + // 获取漫画列表 + let bHasNextPage = false; + const iReqLimit = (ctx.queries && ctx.queries.limit) || 100; + let iReqOffSet = 0; + const strBaseUrl = `${apiBaseUrl}/api/v3/comic/${id}/group/default/chapters`; + let chapterArray = []; + + do { + bHasNextPage = false; + // eslint-disable-next-line no-await-in-loop + const { data } = await got(strBaseUrl, { + headers: { + platform: 1, + }, + searchParams: { + limit: iReqLimit, + offset: iReqOffSet === 0 ? undefined : iReqOffSet, + }, + }); + const { code, results } = data; + + if (code !== 200) { + break; + } + + if (results.limit + results.offset < results.total) { + bHasNextPage = true; + } + iReqOffSet += iReqLimit; + + chapterArray = [...chapterArray, ...results.list]; + } while (bHasNextPage); + + chapterArray = chapterArray + .map(({ comic_path_word, uuid, name, size, datetime_created /* , index*/ }) => ({ + link: `${baseUrl}/comic/${comic_path_word}/chapter/${uuid}`, + uuid, + title: name, + size, + pubDate: datetime_created, + // index, + })) + .reverse(); + + // 获取漫画标题、介绍 + const { bookTitle, bookIntro } = await ctx.cache.tryGet(`${baseUrl}/comic/${id}`, async () => { + const { data } = await got(`${baseUrl}/comic/${id}`); + const $ = cheerio.load(data); + return { + bookTitle: $('.comicParticulars-title-right > ul > li > h6').text(), + bookIntro: $('.intro').text(), + }; + }); + + const genResult = async (chapter) => { + const { + data: { results }, + } = await got(`${apiBaseUrl}/api/v3/comic/${id}/chapter2/${chapter.uuid}`, { + headers: { + webp: 1, + }, + }); + + const pageNumbers = Object.values(results.chapter.words); + const contents = results.chapter.contents + .map((content, index) => ({ + page: pageNumbers[index], + url: content.url, + })) + .sort((a, b) => a.page - b.page); + + return { + link: chapter.link, + title: chapter.title, + description: art(path.join(__dirname, './templates/comic.art'), { + size: chapter.size, + contents, + }), + pubDate: parseDate(chapter.pubDate, 'YYYY-MM-DD'), + }; + }; + + let itemsLen = chapterArray.length; + + if (chapterCnt > 0) { + itemsLen = chapterCnt; + } + + ctx.state.data = { + title: `拷贝漫画 - ${bookTitle}`, + link: `${baseUrl}/comic/${id}`, + description: bookIntro, + item: await Promise.all(chapterArray.slice(0, itemsLen).map((chapter) => ctx.cache.tryGet(chapter.link, () => genResult(chapter)))), + }; +}; diff --git a/lib/v2/copymanga/maintainer.js b/lib/v2/copymanga/maintainer.js new file mode 100644 index 000000000..f8e88f349 --- /dev/null +++ b/lib/v2/copymanga/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/comic/:id/:chapterCnt?': ['btdwv', 'marvolo666', 'yan12125'], +}; diff --git a/lib/v2/copymanga/radar.js b/lib/v2/copymanga/radar.js new file mode 100644 index 000000000..4ac9d9ce5 --- /dev/null +++ b/lib/v2/copymanga/radar.js @@ -0,0 +1,19 @@ +const copymanga = { + _name: '拷贝漫画', + '.': [ + { + title: '漫画更新', + docs: 'https://docs.rsshub.app/anime.html#kao-bei-man-hua', + source: '/comic/:id', + target: '/copymanga/comic/:id/5', + }, + ], +}; + +module.exports = { + 'copymanga.com': copymanga, + 'copymanga.info': copymanga, + 'copymanga.net': copymanga, + 'copymanga.org': copymanga, + 'copymanga.site': copymanga, +}; diff --git a/lib/v2/copymanga/router.js b/lib/v2/copymanga/router.js new file mode 100644 index 000000000..c0eb83ef5 --- /dev/null +++ b/lib/v2/copymanga/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/comic/:id/:chapterCnt?', require('./comic')); +}; diff --git a/lib/v2/copymanga/templates/comic.art b/lib/v2/copymanga/templates/comic.art new file mode 100644 index 000000000..e2f092d60 --- /dev/null +++ b/lib/v2/copymanga/templates/comic.art @@ -0,0 +1,4 @@ +

{{ size }}p


+{{ each contents img }} +{{ img.page }} +{{ /each }}