From 3e93529df14d1f31c00339b2c4248520a52c0fbf Mon Sep 17 00:00:00 2001 From: NeverBehave Date: Mon, 11 Jan 2021 01:02:22 -0500 Subject: [PATCH 01/16] template: make CI identifier clear (#6663) * docs: add more details on how to use template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f44e784cf..70abbfb07 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -31,7 +31,7 @@ NOROUTE ``` --> - + ```routes ``` From 1076839f7cacc0ea97d3ee8f49bb5e04ace8b807 Mon Sep 17 00:00:00 2001 From: zytomorrow Date: Mon, 11 Jan 2021 17:50:07 +0800 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=E9=A3=8E=E4=B9=8B=E5=8A=A8?= =?UTF-8?q?=E6=BC=AB=E5=8F=AF=E5=85=A8=E6=96=87=E8=BE=93=E5=87=BA=E6=BC=AB?= =?UTF-8?q?=E7=94=BB=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/anime.md | 2 +- lib/router.js | 2 +- lib/routes/fzdm/manhua.js | 56 ++++++++++++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/docs/anime.md b/docs/anime.md index bcc037374..cf25578ec 100644 --- a/docs/anime.md +++ b/docs/anime.md @@ -288,7 +288,7 @@ pageClass: routes ### 风之动漫 - + ## 海猫吧 diff --git a/lib/router.js b/lib/router.js index 2da405237..caf0600ea 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2931,7 +2931,7 @@ router.get('/grubstreet', require('./routes/grubstreet/index')); router.get('/manhuadui/manhua/:name/:serial?', require('./routes/manhuadui/manhua')); // 风之漫画 -router.get('/fzdm/manhua/:id', require('./routes/fzdm/manhua')); +router.get('/fzdm/manhua/:id/:nums?', require('./routes/fzdm/manhua')); // Aljazeera 半岛网 router.get('/aljazeera/news', require('./routes/aljazeera/news')); diff --git a/lib/routes/fzdm/manhua.js b/lib/routes/fzdm/manhua.js index 8d47d5fe8..949b8f2ae 100644 --- a/lib/routes/fzdm/manhua.js +++ b/lib/routes/fzdm/manhua.js @@ -2,8 +2,42 @@ const got = require('@/utils/got'); const host = 'https://manhua.fzdm.com'; const cheerio = require('cheerio'); +const get_pic = (id, chapert, caches) => { + const picUrlPattern = RegExp(/var (mhurl1|mhurl)="(.*?)";/); + return caches.tryGet(`${host}/${id}/${chapert}/`, async () => { + let is_last_page = false; + let index = 0; + let pic_content = ''; + while (!is_last_page) { + // eslint-disable-next-line no-await-in-loop + const response = await got.get(`${host}/${id}/${chapert}/index_${index}.html`, { + headers: { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36', + Host: 'manhua.fzdm.com', + 'Accept-Encoding': 'gzip, deflate, br', + Connection: 'keep-alive', + }, + }); + const data = response.data; + if (response.data !== undefined) { + const picurl = data.match(picUrlPattern); + pic_content += `
`; + } else { + pic_content += ''; + is_last_page = true; + } + if (data.match('最后一页了') !== null) { + is_last_page = true; + } + index += 1; + } + return pic_content; + }); +}; + module.exports = async (ctx) => { const id = ctx.params.id; + const nums = ctx.params.nums || 1; const comicPage = host + `/${id}/`; const response = await got({ method: 'get', @@ -13,16 +47,24 @@ module.exports = async (ctx) => { const $ = cheerio.load(data); const list = $('div#content > li > a'); const comicTitle = $('div#content > img').attr('alt').replace(/漫画/, ''); + const chapter_detail = await Promise.all( + list.splice(0, nums).map(async (item) => { + const pic_content = await get_pic(id, $(item).attr('href').replace('/', ''), ctx.cache); + return { + title: $(item).text().trim(), + description: pic_content, + link: item.link, + }; + }) + ); ctx.state.data = { title: '风之动漫 - ' + comicTitle, link: comicPage, description: '风之动漫', - item: list - .map((i, item) => ({ - title: $(item).text().trim(), - description: $(item).text().trim(), - link: comicPage + $(item).attr('href'), - })) - .get(), + item: chapter_detail.map((item) => ({ + title: item.title, + description: item.description, + link: item.link, + })), }; }; From 286f8cd21bdbb86d7315b74a04ff21fbd1f01001 Mon Sep 17 00:00:00 2001 From: zytomorrow Date: Mon, 11 Jan 2021 18:04:31 +0800 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=E9=A3=8E=E4=B9=8B=E5=8A=A8?= =?UTF-8?q?=E6=BC=AB=E5=8F=AF=E5=85=A8=E6=96=87=E8=BE=93=E5=87=BA=E6=BC=AB?= =?UTF-8?q?=E7=94=BB=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/fzdm/manhua.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/routes/fzdm/manhua.js b/lib/routes/fzdm/manhua.js index 949b8f2ae..b28fa5ad5 100644 --- a/lib/routes/fzdm/manhua.js +++ b/lib/routes/fzdm/manhua.js @@ -22,13 +22,14 @@ const get_pic = (id, chapert, caches) => { if (response.data !== undefined) { const picurl = data.match(picUrlPattern); pic_content += `
`; + if (data.match('最后一页了') !== null) { + is_last_page = true; + } } else { pic_content += ''; is_last_page = true; } - if (data.match('最后一页了') !== null) { - is_last_page = true; - } + index += 1; } return pic_content; From b7b107111c98b32f0c8a74fca369d9d9d21a6bce Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 11 Jan 2021 20:33:33 +0800 Subject: [PATCH 04/16] =?UTF-8?q?[Instagram]=20=E4=BF=AE=E5=A4=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8path.join=E5=AF=BC=E8=87=B4=E7=9A=84URL=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/instagram/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/routes/instagram/index.js b/lib/routes/instagram/index.js index 504a1f611..0874214b9 100644 --- a/lib/routes/instagram/index.js +++ b/lib/routes/instagram/index.js @@ -55,7 +55,7 @@ module.exports = async (ctx) => { logo = userInfo.hd_profile_pic_url_info.url; const fullName = userInfo.full_name; title = `${fullName} (@${username}) - Instagram`; - link = path.join('https://www.instagram.com', username); + link = `https://www.instagram.com/${username}`; itemsRaw = await ig.feed.user(id).items(); break; @@ -64,7 +64,7 @@ module.exports = async (ctx) => { const tag = nameOrId; title = `#${tag}) - Instagram`; - link = path.join('https://www.instagram.com', 'explore', 'tags', tag); + link = `https://www.instagram.com/explore/tags/${tag}`; itemsRaw = await (await ig.feed.tags(tag).items()).slice(1); // the 0 item is undefined for unknown reason break; @@ -89,7 +89,7 @@ module.exports = async (ctx) => { } // Metadata - const url = path.join('https://www.instagram.com', 'p', item.code); + const url = `https://www.instagram.com/p/${item.code}`; const pubDate = new Date(item.taken_at * 1000).toUTCString(); const title = summary.split('\n')[0]; From 7c7c1419b872faa4c081e5c995059edc9b691e6f Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 11 Jan 2021 20:49:21 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/instagram/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/routes/instagram/index.js b/lib/routes/instagram/index.js index 0874214b9..497e51596 100644 --- a/lib/routes/instagram/index.js +++ b/lib/routes/instagram/index.js @@ -1,5 +1,4 @@ const cheerio = require('cheerio'); -const path = require('path'); const { IgLoginRequiredError } = require('instagram-private-api'); const { ig, login } = require('./utils'); From 91c6e6dfc26e9c4635c706976b51a8675d79001a Mon Sep 17 00:00:00 2001 From: Troy Liu Date: Mon, 11 Jan 2021 21:46:34 +0800 Subject: [PATCH 06/16] feat: load pics of searched items --- lib/routes/hentai-cosplays/porn-images-xxx.js | 2 +- lib/routes/hentai-cosplays/utils.js | 56 +++++++++++++------ 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/routes/hentai-cosplays/porn-images-xxx.js b/lib/routes/hentai-cosplays/porn-images-xxx.js index a2fc3880e..b16829c20 100644 --- a/lib/routes/hentai-cosplays/porn-images-xxx.js +++ b/lib/routes/hentai-cosplays/porn-images-xxx.js @@ -2,7 +2,7 @@ const { processFeed } = require('./utils'); module.exports = async (ctx) => { const url = ctx.params.type ? `https://ja.porn-images-xxx.com/search/${ctx.params.type}/${encodeURIComponent(ctx.params.name)}/` : 'https://ja.porn-images-xxx.com/search/'; - const items = await processFeed(url); + const items = await processFeed(ctx, url); ctx.state.data = { title: `${ctx.params.name || '新着画像一覧'} - エロ画像`, link: url, diff --git a/lib/routes/hentai-cosplays/utils.js b/lib/routes/hentai-cosplays/utils.js index 80770e3bc..85be00b28 100644 --- a/lib/routes/hentai-cosplays/utils.js +++ b/lib/routes/hentai-cosplays/utils.js @@ -1,26 +1,46 @@ const cheerio = require('cheerio'); const got = require('@/utils/got'); -exports.processFeed = async function processFeed(link) { +const host = 'https://ja.porn-images-xxx.com/'; + +exports.processFeed = async function processFeed(ctx, link) { const response = await got.get(link); const $ = cheerio.load(response.body); - const list = $('ul#image-list li'); + const list = $('ul#image-list li') + .map(function (index, item) { + item = $(item); + return { + title: item.find('.image-list-item-title').text(), + link: item.find('.image-list-item-title > a').attr('href'), + date: item.find('.image-list-item-regist-date > span').text(), + }; + }) + .get(); + return await Promise.all( + list.map(async (info) => { + const title = info.title.trim(); + const date = info.date; + const itemUrl = host + info.link; - return ( - list && - list - .map((index, item) => { - item = $(item); - return { - title: item.find('.image-list-item-title').text(), - link: item.find('.image-list-item-title > a').attr('href'), - description: item - .find('.image-list-item-image') - .html() - .replace(/\/p=\d+x\d+/, ''), - pubDate: new Date(item.find('.image-list-item-regist-date').text()), - }; - }) - .get() + const cache = await ctx.cache.get(itemUrl); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + + const response = await got.get(itemUrl); + const $ = cheerio.load(response.data); + const images = $('.icon-overlay > a > img'); + const desc = cheerio.html(images); + const item = { + title: title, + link: itemUrl, + description: desc, + pubDate: new Date(date).toUTCString(), + }; + if (desc) { + ctx.cache.set(itemUrl, JSON.stringify(item)); + } + return Promise.resolve(item); + }) ); }; From f2347d5919a1a138698f7f38e8a692c86e8d94c2 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Mon, 11 Jan 2021 22:25:50 +0800 Subject: [PATCH 07/16] fix: fix tesla link path --- lib/routes/tesla/update.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/routes/tesla/update.js b/lib/routes/tesla/update.js index 979b06d98..9c801ca1b 100644 --- a/lib/routes/tesla/update.js +++ b/lib/routes/tesla/update.js @@ -34,7 +34,7 @@ module.exports = async (ctx) => { title: item.find('.container h1').text(), description: item.find('.notes-container').text() + '', pubDate: targetDate[0], - link: 'https://www.notateslaapp.com' + item.find('.selector-container-notes a').attr('href'), + link: 'https://www.notateslaapp.com' + item.find('.notes-container > .button-container > a').attr('href'), }; }) .get(), From 3a553c7f1c6416b2ded6d579282488c829881c6e Mon Sep 17 00:00:00 2001 From: NeverBehave Date: Mon, 11 Jan 2021 10:49:57 -0500 Subject: [PATCH 08/16] docs: close pr on wrong format, reopen to rescan (#6669) * template: enforcing rules and use reopen as trigger to retest route --- .github/PULL_REQUEST_TEMPLATE.md | 6 +----- .github/workflows/pr-deploy-route-test.yml | 2 ++ scripts/workflow/test-route/identify.js | 21 ++++++++++++++++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 70abbfb07..a00661cf5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ diff --git a/.github/workflows/pr-deploy-route-test.yml b/.github/workflows/pr-deploy-route-test.yml index c5d965a78..2042fe581 100644 --- a/.github/workflows/pr-deploy-route-test.yml +++ b/.github/workflows/pr-deploy-route-test.yml @@ -2,9 +2,11 @@ name: PR route test # https://github.com/actions/first-interaction/issues/10#issuecomment-670968624 # https://github.com/actions/first-interaction/issues/10#issuecomment-752360668 +# Reopen Included on: - pull_request_target + jobs: testRoute: runs-on: ubuntu-latest diff --git a/scripts/workflow/test-route/identify.js b/scripts/workflow/test-route/identify.js index 534cd3990..9eb66899b 100644 --- a/scripts/workflow/test-route/identify.js +++ b/scripts/workflow/test-route/identify.js @@ -44,7 +44,7 @@ module.exports = async ({ github, context, core }, body, number) => { } } - core.info('seems no route found, failing'); + core.warning('seems no route found, failing'); await github.issues .addLabels({ @@ -56,6 +56,25 @@ module.exports = async ({ github, context, core }, body, number) => { .catch((e) => { core.warning(e); }); + await github.issues + .createComment({ + issue_number: number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `自动检测失败, 请确认PR正文部分符合格式规范并重新开启, 详情请检查日志 +Auto Route test failed, please check your PR body format and reopen pull request. Check logs for more details`, + }) + .catch((e) => { + core.warning(e); + }); + await github.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_nulber: number, + state: "closed" + }).catch((e) => { + core.warning(e); + }); throw 'Please follow the PR rules: failed to detect route'; }; From 57634bfbec8fa9386a98e7f24394c7d3011ccd09 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 11 Jan 2021 15:51:59 +0000 Subject: [PATCH 09/16] style: auto format --- scripts/workflow/test-route/identify.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/workflow/test-route/identify.js b/scripts/workflow/test-route/identify.js index 9eb66899b..7fcf08fe4 100644 --- a/scripts/workflow/test-route/identify.js +++ b/scripts/workflow/test-route/identify.js @@ -67,14 +67,16 @@ Auto Route test failed, please check your PR body format and reopen pull request .catch((e) => { core.warning(e); }); - await github.pulls.update({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_nulber: number, - state: "closed" - }).catch((e) => { - core.warning(e); - }); + await github.pulls + .update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_nulber: number, + state: 'closed', + }) + .catch((e) => { + core.warning(e); + }); throw 'Please follow the PR rules: failed to detect route'; }; From ab4963756f75bf688f7d5447ef9e3c072257c0d5 Mon Sep 17 00:00:00 2001 From: zph Date: Tue, 12 Jan 2021 00:24:02 +0800 Subject: [PATCH 10/16] add gab --- docs/en/social-media.md | 10 ++++++++++ docs/social-media.md | 10 ++++++++++ lib/router.js | 5 +++++ lib/routes/gab/explore.js | 31 +++++++++++++++++++++++++++++++ lib/routes/gab/user.js | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 lib/routes/gab/explore.js create mode 100644 lib/routes/gab/user.js diff --git a/docs/en/social-media.md b/docs/en/social-media.md index fe64739a3..152b04a6b 100644 --- a/docs/en/social-media.md +++ b/docs/en/social-media.md @@ -34,6 +34,16 @@ pageClass: routes +## Gab + +### User's Posts + + + +### Popular Posts + + + ## Instagram ::: warning diff --git a/docs/social-media.md b/docs/social-media.md index 02a01239a..71bdca940 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -320,6 +320,16 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 +## Gab + +### 用戶時間線 + + + +### 熱門 + + + ## iCity ### 用户动态 diff --git a/lib/router.js b/lib/router.js index 9e7177507..df997de2b 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3800,6 +3800,7 @@ router.get('/semiconductors/latest-news', require('./routes/semiconductors/lates // VOA News router.get('/voa/day-photos', require('./routes/voa/day-photos')); + // Voice of America router.get('/voa/:language/:channel?', require('./routes/voa/index')); @@ -3861,4 +3862,8 @@ router.get('/booth.pm/shop/:subdomain', require('./routes/booth-pm/shop')); // Minecraft feed the beast router.get('/feed-the-beast/modpack/:modpackEntry', require('./routes/feed-the-beast/modpack')); +// Gab +router.get('/gab/user/:username', require('./routes/gab/user')); +router.get('/gab/popular/:sort?', require('./routes/gab/explore')); + module.exports = router; diff --git a/lib/routes/gab/explore.js b/lib/routes/gab/explore.js new file mode 100644 index 000000000..5c9a66454 --- /dev/null +++ b/lib/routes/gab/explore.js @@ -0,0 +1,31 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); + +module.exports = async (ctx) => { + const sort = ctx.params.sort || 'hot'; + + let baseURL = 'https://gab.com/api/v1/timelines/explore?page=1&sort_by='; + baseURL += sort === 'hot' ? 'hot' : 'top_today'; + + const response = await got.get(baseURL); + + const result = await Promise.all( + response.data.map((item) => { + const media = item.media_attachments.map((item) => ``).join('
'); + const $ = cheerio.load(item.content); + + return { + title: $.text() || 'Untitled', + description: item.content + (media && '
' + media), + link: item.url || baseURL, + pubDate: new Date(item.created_at).toISOString(), + }; + }) + ); + + ctx.state.data = { + title: `Gab - Popular posts`, + link: baseURL, + item: result, + }; +}; diff --git a/lib/routes/gab/user.js b/lib/routes/gab/user.js new file mode 100644 index 000000000..8cb350ff7 --- /dev/null +++ b/lib/routes/gab/user.js @@ -0,0 +1,32 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); + +module.exports = async (ctx) => { + const username = ctx.params.username; + + const response = await got.get('https://gab.com/api/v1/account_by_username/' + username); + const id = response.data.id; + const gabs = await got.get(`https://gab.com/api/v1/accounts/${id}/statuses?exclude_replies=true`); + + const result = await Promise.all( + gabs.data + .filter((item) => !item.reblog) + .map((item) => { + const media = item.media_attachments.map((item) => ``).join('
'); + const $ = cheerio.load(item.content); + + return { + title: $.text() || 'Untitled', + description: item.content + (media && '
' + media), + link: item.url || `https://gab.com/${username}`, + pubDate: new Date(item.created_at).toISOString(), + }; + }) + ); + + ctx.state.data = { + title: `Gab - ${username}`, + link: `https://gab.com/${username}`, + item: result, + }; +}; From 2b68e64cbe8212d2d315777190487dd7f6b55e06 Mon Sep 17 00:00:00 2001 From: NeverBehave Date: Mon, 11 Jan 2021 15:01:07 -0500 Subject: [PATCH 11/16] Revert "feat: add fulltext to the article route of caixin" --- lib/routes/caixin/article.js | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/lib/routes/caixin/article.js b/lib/routes/caixin/article.js index 6874fe8aa..29fd6d70a 100644 --- a/lib/routes/caixin/article.js +++ b/lib/routes/caixin/article.js @@ -1,5 +1,4 @@ const got = require('@/utils/got'); -const cheerio = require('cheerio'); module.exports = async (ctx) => { const response = await got({ @@ -13,33 +12,15 @@ module.exports = async (ctx) => { const data = response.data.data.list; - const items = await Promise.all( - data.map(async (item) => { - const link = item.web_url; - const summary = `

${item.summary}

`; - - const fullText = await ctx.cache.tryGet(link, async () => { - const result = await got.get(link); - - const $ = cheerio.load(result.data); - - return $('#Main_Content_Val').html(); - }); - - return { - title: item.title, - description: fullText ? summary + fullText : summary, - link: link, - pubDate: new Date(item.time * 1000), - author: item.author_name, - }; - }) - ); - ctx.state.data = { title: `财新网 - 首页`, link: `http://www.caixin.com/`, description: '财新网 - 首页', - item: items, + item: data.map((item) => ({ + title: item.title, + description: `

${item.summary}

`, + link: item.web_url, + pubDate: new Date(item.time * 1000), + })), }; }; From 7ed6dd8e778832a02ee871fd9df72489a237b867 Mon Sep 17 00:00:00 2001 From: cgking <58586625+cgkings@users.noreply.github.com> Date: Tue, 12 Jan 2021 09:12:51 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E6=96=B0=E5=A2=9E141jav&141ppv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/141jav/141jav.js | 37 +++++++++++++++++++++++++++++++++++++ lib/routes/141ppv/141ppv.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/routes/141jav/141jav.js create mode 100644 lib/routes/141ppv/141ppv.js diff --git a/lib/routes/141jav/141jav.js b/lib/routes/141jav/141jav.js new file mode 100644 index 000000000..440f34f1b --- /dev/null +++ b/lib/routes/141jav/141jav.js @@ -0,0 +1,37 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const type = ctx.params.type || 'new'; + const key = type === 'day' ? ctx.params.key.slice(0, 4) + '/' + ctx.params.key.slice(4, 6) + '/' + ctx.params.key.slice(6, 8) : ctx.params.key || ''; + const link = 'https://www.141jav.com' + `/${type === 'day' ? '' : type}${type === 'new' ? '' : '/' + key}`.replace('//', '/'); + const response = await got({ + method: 'get', + url: link, + }); + + const $ = cheerio.load(response.data); + const list = $('div.columns'); + + let itemPicUrl; + + ctx.state.data = { + title: `141jav - ${type} ${key}`, + link: link, + item: + list && + list + .map((index, item) => { + item = $(item); + itemPicUrl = item.find('img').attr('src'); + return { + title: '【' + item.find('div.card-content.is-flex > h5 > a').text() + '】' + item.find('div.card-content.is-flex > h5 > span').text(), + description: `
Time: ${item.find('p.subtitle.is-6 > a').text()}
Desc: ${item.find('p.level.has-text-grey-dark').text()}`, + link: item.find('div.card-content.is-flex > h5 > a').attr('href'), + enclosure_url: item.find('div.card-content.is-flex > a').attr('href'), + enclosure_type: 'application/x-bittorrent', + }; + }) + .get(), + }; +}; diff --git a/lib/routes/141ppv/141ppv.js b/lib/routes/141ppv/141ppv.js new file mode 100644 index 000000000..ec3d8e63d --- /dev/null +++ b/lib/routes/141ppv/141ppv.js @@ -0,0 +1,37 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const type = ctx.params.type || 'new'; + const key = type === 'day' ? ctx.params.key.slice(0, 4) + '/' + ctx.params.key.slice(4, 6) + '/' + ctx.params.key.slice(6, 8) : ctx.params.key || ''; + const link = 'https://www.141ppv.com' + `/${type === 'day' ? '' : type}${type === 'new' ? '' : '/' + key}`.replace('//', '/'); + const response = await got({ + method: 'get', + url: link, + }); + + const $ = cheerio.load(response.data); + const list = $('div.columns'); + + let itemPicUrl; + + ctx.state.data = { + title: `141ppv - ${type} ${key}`, + link: link, + item: + list && + list + .map((index, item) => { + item = $(item); + itemPicUrl = item.find('img').attr('src'); + return { + title: '【' + item.find('div.card-content.is-flex > h5 > a').text() + '】' + item.find('div.card-content.is-flex > h5 > span').text(), + description: `
Time: ${item.find('p.subtitle.is-6 > a').text()}
Desc: ${item.find('p.level.has-text-grey-dark').text()}`, + link: item.find('div.card-content.is-flex > h5 > a').attr('href'), + enclosure_url: item.find('div.card-content.is-flex > a').attr('href'), + enclosure_type: 'application/x-bittorrent', + }; + }) + .get(), + }; +}; From 3550e29bdd32267e416fa5e6b92fe691eab3de03 Mon Sep 17 00:00:00 2001 From: cgking <58586625+cgkings@users.noreply.github.com> Date: Tue, 12 Jan 2021 09:20:47 +0800 Subject: [PATCH 13/16] =?UTF-8?q?141jav&141ppv=E5=85=B3=E8=81=94=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/radar-rules.js | 76 ++++++++++++++++++++++++++++++++++ docs/multimedia.md | 96 +++++++++++++++++++++++++++++++++++++++++++ lib/router.js | 6 +++ 3 files changed, 178 insertions(+) diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 8eba20708..99a84e604 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -2035,6 +2035,82 @@ }, ], }, + '141jav.com': { + _name: '141JAV BT', + '.': [ + { + title: '今日种子', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: '/', + target: (params, url, document) => { + const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + return `/141jav/day/${today}`; + }, + }, + { + title: '今日演员', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: '/', + target: (params, url, document) => { + const star = document.querySelector('div.card-content > div > a').getAttribute('href'); + return `/141jav${star}`; + }, + }, + { + title: '页面种子', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], + target: (params, url, document) => { + const itype = params.morekey === undefined ? `${params.type}` : params.type === 'tag' ? 'tag' : 'day'; + let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; + if (ikey === '' && itype === 'tag') { + ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); + } else if (ikey === '' && itype === 'actress') { + ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); + } + return `/141jav/${itype}/${ikey}`; + }, + }, + ], + }, + '141ppv.com': { + _name: '141ppv BT', + '.': [ + { + title: '今日种子', + docs: 'https://docs.rsshub.app/multimedia.html#141pvp', + source: '/', + target: (params, url, document) => { + const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + return `/141ppv/day/${today}`; + }, + }, + { + title: '今日演员', + docs: 'https://docs.rsshub.app/multimedia.html#141ppv', + source: '/', + target: (params, url, document) => { + const star = document.querySelector('div.card-content > div > a').getAttribute('href'); + return `/141ppv${star}`; + }, + }, + { + title: '页面种子', + docs: 'https://docs.rsshub.app/multimedia.html#141ppv', + source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], + target: (params, url, document) => { + const itype = params.morekey === undefined ? `${params.type}` : params.type === 'tag' ? 'tag' : 'day'; + let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; + if (ikey === '' && itype === 'tag') { + ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); + } else if (ikey === '' && itype === 'actress') { + ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); + } + return `/141ppv/${itype}/${ikey}`; + }, + }, + ], + }, 'sexinsex.net': { _name: 'sexinsex', '.': [ diff --git a/docs/multimedia.md b/docs/multimedia.md index bec28475e..d8f6cee87 100644 --- a/docs/multimedia.md +++ b/docs/multimedia.md @@ -398,6 +398,102 @@ pageClass: routes
+## 141JAV + +::: tip 提示 + +官方提供的订阅源不支持 BT 下载订阅,地址为 + +::: + +### 141JAV BT + + + +**类型** + +| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | +| ---- | ------- | ------ | -------- | -------- | -------- | +| new | popular | random | actress | tag | day | + +**关键词** + +| 空 | 日期范围 | 演员名 | 标签名 | 日期 | +| -- | ----------- | ------------ | -------------- | -------- | +| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | + +**示例说明** + +- `/141jav/new` + + 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** + +- `/141jav/popular/30` + + `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 + +- `/141jav/actress/Yua%20Mikami` + + `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141jav.com/actress/) 演员单页链接中获取 + +- `/141jav/tag/Adult%20Awards` + + `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141jav.com/tag/) 标签单页链接中获取 + +- `/141jav/day/20200730` + + `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 + + + +## 141PPV + +::: tip 提示 + +官方提供的订阅源不支持 BT 下载订阅,地址为 + +::: + +### 141PPV BT + + + +**类型** + +| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | +| ---- | ------- | ------ | -------- | -------- | -------- | +| new | popular | random | actress | tag | day | + +**关键词** + +| 空 | 日期范围 | 演员名 | 标签名 | 日期 | +| -- | ----------- | ------------ | -------------- | -------- | +| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | + +**示例说明** + +- `/141ppv/new` + + 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** + +- `/141ppv/popular/30` + + `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 + +- `/141ppv/actress/Yua%20Mikami` + + `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141ppv.com/actress/) 演员单页链接中获取 + +- `/141ppv/tag/Adult%20Awards` + + `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141ppv.com/tag/) 标签单页链接中获取 + +- `/141ppv/day/20200730` + + `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 + + + ## PornHub ### 分类 diff --git a/lib/router.js b/lib/router.js index 53dc5ce41..c852de52c 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3204,6 +3204,12 @@ router.get('/scut/scet/notice', require('./routes/universities/scut/scet/notice' // OneJAV router.get('/onejav/:type/:key?', require('./routes/onejav/one')); +// 141jav +router.get('/141jav/:type/:key?', require('./routes/141jav/141jav')); + +// 141ppv +router.get('/141ppv/:type/:key?', require('./routes/141ppv/141ppv')); + // CuriousCat router.get('/curiouscat/user/:id', require('./routes/curiouscat/user')); From c695cd3d610d9862b026996847b939357622f5fe Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 12 Jan 2021 01:40:33 +0000 Subject: [PATCH 14/16] style: auto format --- docs/multimedia.md | 192 ++++++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/docs/multimedia.md b/docs/multimedia.md index d8f6cee87..bf59d65da 100644 --- a/docs/multimedia.md +++ b/docs/multimedia.md @@ -4,6 +4,102 @@ pageClass: routes # 音视频 +## 141JAV + +::: tip 提示 + +官方提供的订阅源不支持 BT 下载订阅,地址为 + +::: + +### 141JAV BT + + + +**类型** + +| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | +| ---- | ------- | ------ | -------- | -------- | -------- | +| new | popular | random | actress | tag | day | + +**关键词** + +| 空 | 日期范围 | 演员名 | 标签名 | 日期 | +| -- | ----------- | ------------ | -------------- | -------- | +| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | + +**示例说明** + +- `/141jav/new` + + 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** + +- `/141jav/popular/30` + + `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 + +- `/141jav/actress/Yua%20Mikami` + + `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141jav.com/actress/) 演员单页链接中获取 + +- `/141jav/tag/Adult%20Awards` + + `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141jav.com/tag/) 标签单页链接中获取 + +- `/141jav/day/20200730` + + `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 + + + +## 141PPV + +::: tip 提示 + +官方提供的订阅源不支持 BT 下载订阅,地址为 + +::: + +### 141PPV BT + + + +**类型** + +| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | +| ---- | ------- | ------ | -------- | -------- | -------- | +| new | popular | random | actress | tag | day | + +**关键词** + +| 空 | 日期范围 | 演员名 | 标签名 | 日期 | +| -- | ----------- | ------------ | -------------- | -------- | +| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | + +**示例说明** + +- `/141ppv/new` + + 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** + +- `/141ppv/popular/30` + + `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 + +- `/141ppv/actress/Yua%20Mikami` + + `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141ppv.com/actress/) 演员单页链接中获取 + +- `/141ppv/tag/Adult%20Awards` + + `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141ppv.com/tag/) 标签单页链接中获取 + +- `/141ppv/day/20200730` + + `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 + + + ## 2048 核基地 ### 论坛更新 @@ -398,102 +494,6 @@ pageClass: routes
-## 141JAV - -::: tip 提示 - -官方提供的订阅源不支持 BT 下载订阅,地址为 - -::: - -### 141JAV BT - - - -**类型** - -| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | -| ---- | ------- | ------ | -------- | -------- | -------- | -| new | popular | random | actress | tag | day | - -**关键词** - -| 空 | 日期范围 | 演员名 | 标签名 | 日期 | -| -- | ----------- | ------------ | -------------- | -------- | -| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | - -**示例说明** - -- `/141jav/new` - - 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** - -- `/141jav/popular/30` - - `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 - -- `/141jav/actress/Yua%20Mikami` - - `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141jav.com/actress/) 演员单页链接中获取 - -- `/141jav/tag/Adult%20Awards` - - `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141jav.com/tag/) 标签单页链接中获取 - -- `/141jav/day/20200730` - - `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 - - - -## 141PPV - -::: tip 提示 - -官方提供的订阅源不支持 BT 下载订阅,地址为 - -::: - -### 141PPV BT - - - -**类型** - -| 最新 | 热门 | 随机 | 指定演员 | 指定标签 | 指定日期 | -| ---- | ------- | ------ | -------- | -------- | -------- | -| new | popular | random | actress | tag | day | - -**关键词** - -| 空 | 日期范围 | 演员名 | 标签名 | 日期 | -| -- | ----------- | ------------ | -------------- | -------- | -| | 7 / 30 / 60 | Yua%20Mikami | Adult%20Awards | YYYYMMDD | - -**示例说明** - -- `/141ppv/new` - - 仅当类型为 `new` `popular` 或 `random` 时关键词可为 **空** - -- `/141ppv/popular/30` - - `popular` `random` 类型的关键词可填写 `7` `30` 或 `60` 三个 **日期范围** 之一 - -- `/141ppv/actress/Yua%20Mikami` - - `actress` 类型的关键词必须填写 **演员名** ,可在 [此处](https://141ppv.com/actress/) 演员单页链接中获取 - -- `/141ppv/tag/Adult%20Awards` - - `tag` 类型的关键词必须填写 **标签名** 且标签中的 `/` 必须替换为 `%2F` ,可在 [此处](https://141ppv.com/tag/) 标签单页链接中获取 - -- `/141ppv/day/20200730` - - `day` 类型的关键词必须填写 **日期** ,按照示例写成形如 `20200730` 的格式 - - - ## PornHub ### 分类 From 9706affa70bb8aae8a56b2453f0070498ed24f22 Mon Sep 17 00:00:00 2001 From: NeverBehave Date: Mon, 11 Jan 2021 20:51:33 -0500 Subject: [PATCH 15/16] docs: bilibili cookie name --- docs/install/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install/README.md b/docs/install/README.md index 7df0eb514..87af9dcc1 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -520,7 +520,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `BILIBILI_COOKIE_{uid}`: 对应 uid 的 b 站用户登录后的 Cookie 值,`{uid}` 替换为 uid,如 `BILIBILI_COOKIE_2267573`,获取方式: 1. 打开 2. 打开控制台,切换到 Network 面板,刷新 - 3. 点击 dynamic_new 请求,找到 Cookie + 3. 点击 dynamic_new 请求,找到 Cookie。(Key:`SESSDATA`) - 语雀 全部路由:[注册地址](https://www.yuque.com/register) From cb25f84da51fd5846314bc63b53d881d1190e4c1 Mon Sep 17 00:00:00 2001 From: nczitzk Date: Tue, 12 Jan 2021 10:05:33 +0800 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20add=20NEW=E5=AD=97=E5=B9=95?= =?UTF-8?q?=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/multimedia.md | 12 ++++++ lib/router.js | 3 ++ lib/routes/newzmz/index.js | 76 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 lib/routes/newzmz/index.js diff --git a/docs/multimedia.md b/docs/multimedia.md index bec28475e..e436eb43a 100644 --- a/docs/multimedia.md +++ b/docs/multimedia.md @@ -344,6 +344,18 @@ pageClass: routes +## NEW 字幕组 + +### 分类 + + + +| 最近更新 | 剧集推荐 | 电影推荐 | 纪录片推荐 | 动画推荐 | 真人秀推荐 | +| -------- | -------- | -------- | ---------- | -------- | ---------- | +| 1 | 2 | 3 | 4 | 5 | 6 | + + + ## Nyaa ### 搜索结果 diff --git a/lib/router.js b/lib/router.js index 53dc5ce41..6ffff0552 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3866,4 +3866,7 @@ router.get('/feed-the-beast/modpack/:modpackEntry', require('./routes/feed-the-b router.get('/gab/user/:username', require('./routes/gab/user')); router.get('/gab/popular/:sort?', require('./routes/gab/explore')); +// NEW字幕组 +router.get('/newzmz/:category?', require('./routes/newzmz/index')); + module.exports = router; diff --git a/lib/routes/newzmz/index.js b/lib/routes/newzmz/index.js new file mode 100644 index 000000000..e3cc8b720 --- /dev/null +++ b/lib/routes/newzmz/index.js @@ -0,0 +1,76 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const category = parseInt(ctx.params.category || '1'); + + const rootUrl = 'https://newzmz.com'; + const response = await got({ + method: 'get', + url: rootUrl, + }); + + const $ = cheerio.load(response.data); + const target = $('.rowMod').eq(category); + + const links = await Promise.all( + target + .find('.slides li a') + .slice(0, 15) + .map((_, item) => { + item = $(item); + + return { + title: item.text(), + link: `${rootUrl}${item.attr('href')}`, + }; + }) + .get() + .map( + async (item) => + await ctx.cache.tryGet(item.link, async () => { + const resourceResponse = await got({ + method: 'get', + url: item.link, + }); + const $ = cheerio.load(resourceResponse.data); + + item.link = $('.addgz').attr('href'); + item.pubDate = new Date($('.duration').text().replace(/更新时间:/, '')).toUTCString(); + + return item; + }) + ) + ); + + const items = await Promise.all( + links.map( + async (item) => + await ctx.cache.tryGet(item.link, async () => { + const detailResponse = await got({ + method: 'get', + url: item.link, + }); + const content = cheerio.load(detailResponse.data); + + content('img, .link-name').remove(); + + content('a[title]').each(function () { + content(this).text(content(this).attr('title')); + }); + + item.description = content('.faq--area').html(); + item.enclosure_type = 'application/x-bittorrent'; + item.enclosure_url = content('a[title="磁力链下载"]').attr('href'); + + return item; + }) + ) + ); + + ctx.state.data = { + title: `${target.find('.row-header-title').text()} - NEW字幕组`, + link: rootUrl, + item: items, + }; +};