From d65075ac2f0a9c35a508284be3a07d7b13e1cbfb Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 23 Jan 2022 03:17:29 +0700 Subject: [PATCH] feat(route): add agirls (#8782) --- docs/new-media.md | 20 +++++++ lib/v2/agirls/index.js | 71 +++++++++++++++++++++++++ lib/v2/agirls/maintainer.js | 5 ++ lib/v2/agirls/radar.js | 25 +++++++++ lib/v2/agirls/router.js | 5 ++ lib/v2/agirls/templates/description.art | 1 + lib/v2/agirls/topic.js | 71 +++++++++++++++++++++++++ lib/v2/agirls/topic_list.js | 44 +++++++++++++++ 8 files changed, 242 insertions(+) create mode 100644 lib/v2/agirls/index.js create mode 100644 lib/v2/agirls/maintainer.js create mode 100644 lib/v2/agirls/radar.js create mode 100644 lib/v2/agirls/router.js create mode 100644 lib/v2/agirls/templates/description.art create mode 100644 lib/v2/agirls/topic.js create mode 100644 lib/v2/agirls/topic_list.js diff --git a/docs/new-media.md b/docs/new-media.md index 5fbedd2556..3665b69d5e 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -1406,6 +1406,26 @@ area 分区选项 +## 电獭少女 + +### 分类 + + + +| App 评测 | 手机开箱 | 笔电开箱 | 3C 周边 | 教学小技巧 | 科技情报 | +| -------- | -------- | -------- | ----------- | ---------- | -------- | +| app | phone | computer | accessories | tutorial | techlife | + + + +### 精选主题 + + + +### 当前精选主题列表 + + + ## 丁香园 ### 新冠疫苗实时动态 diff --git a/lib/v2/agirls/index.js b/lib/v2/agirls/index.js new file mode 100644 index 0000000000..3122cb4257 --- /dev/null +++ b/lib/v2/agirls/index.js @@ -0,0 +1,71 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); +const path = require('path'); +const { art } = require('@/utils/render'); + +module.exports = async (ctx) => { + const baseUrl = 'https://agirls.aotter.net'; + const category = ctx.params.category ?? ''; + + const response = await got({ + url: baseUrl + '/posts' + (category ? `/${category}` : ''), + header: { + Referer: baseUrl, + }, + }); + + const $ = cheerio.load(response.data); + + let items = $('div a.flex.flex-col') + .map((_, item) => { + item = $(item); + return { + title: item.find('h2').text().trim(), + link: baseUrl + item.attr('href'), + }; + }) + .get(); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const detailResponse = await got({ + url: item.link, + header: { + Referer: baseUrl + '/posts/' + (category ? `/${category}` : ''), + }, + }); + const content = cheerio.load(detailResponse.data); + + item.category = content('a.mr-2.bg-neutral-lightest.px-2.py-1.text-sm.text-neutral-light') + .toArray() + .map((e) => content(e).text().trim().replace('#', '')); + item.description = art(path.join(__dirname, 'templates/description.art'), { + desc: content('div.post-content').html(), + }); + item.pubDate = timezone(parseDate(content('time').text().trim()), +8); + item.author = content('a.mr-1.text-primary').text().trim(); + + return item; + }) + ) + ); + + ctx.state.data = { + title: $('head title').text().trim(), + link: baseUrl + '/' + category, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; + + ctx.state.json = { + title: $('head title').text().trim(), + link: baseUrl + '/' + category, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; +}; diff --git a/lib/v2/agirls/maintainer.js b/lib/v2/agirls/maintainer.js new file mode 100644 index 0000000000..cd511d9839 --- /dev/null +++ b/lib/v2/agirls/maintainer.js @@ -0,0 +1,5 @@ +module.exports = { + '/topic/:topic': ['TonyRL'], + '/topic_list': ['TonyRL'], + '/:category?': ['TonyRL'], +}; diff --git a/lib/v2/agirls/radar.js b/lib/v2/agirls/radar.js new file mode 100644 index 0000000000..1637c87b5e --- /dev/null +++ b/lib/v2/agirls/radar.js @@ -0,0 +1,25 @@ +module.exports = { + 'aotter.net': { + _name: '電獺少女', + agirls: [ + { + title: '分類', + docs: 'https://docs.rsshub.app/new-media.html##dian-ta-shao-nu', + source: ['/posts/:category'], + target: '/agirls/:category', + }, + { + title: '精選主題列表', + docs: 'https://docs.rsshub.app/new-media.html##dian-ta-shao-nu', + source: ['/', '/topic'], + target: '/agirls/topic_list', + }, + { + title: '精选主题', + docs: 'https://docs.rsshub.app/new-media.html##dian-ta-shao-nu', + source: ['/topic/:topic'], + target: '/agirls/topic/:topic', + }, + ], + }, +}; diff --git a/lib/v2/agirls/router.js b/lib/v2/agirls/router.js new file mode 100644 index 0000000000..33d4d86f1c --- /dev/null +++ b/lib/v2/agirls/router.js @@ -0,0 +1,5 @@ +module.exports = function (router) { + router.get('/topic/:topic', require('./topic')); + router.get('/topic_list', require('./topic_list')); + router.get('/:category?', require('./index')); +}; diff --git a/lib/v2/agirls/templates/description.art b/lib/v2/agirls/templates/description.art new file mode 100644 index 0000000000..7755ee9f6b --- /dev/null +++ b/lib/v2/agirls/templates/description.art @@ -0,0 +1 @@ +{{@ desc }} diff --git a/lib/v2/agirls/topic.js b/lib/v2/agirls/topic.js new file mode 100644 index 0000000000..b18d230e85 --- /dev/null +++ b/lib/v2/agirls/topic.js @@ -0,0 +1,71 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); +const path = require('path'); +const { art } = require('@/utils/render'); + +module.exports = async (ctx) => { + const baseUrl = 'https://agirls.aotter.net'; + const topic = ctx.params.topic; + + const response = await got({ + url: baseUrl + '/topic/' + topic, + header: { + Referer: baseUrl, + }, + }); + + const $ = cheerio.load(response.data); + + let items = $('div.col-12 div.row a') + .map((_, item) => { + item = $(item); + return { + title: item.find('h3').text().trim(), + link: baseUrl + item.attr('href'), + }; + }) + .get(); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const detailResponse = await got({ + url: item.link, + header: { + Referer: baseUrl + '/topic/' + topic, + }, + }); + const content = cheerio.load(detailResponse.data); + + item.category = content('a.mr-2.bg-neutral-lightest.px-2.py-1.text-sm.text-neutral-light') + .toArray() + .map((e) => content(e).text().trim().replace('#', '')); + item.description = art(path.join(__dirname, 'templates/description.art'), { + desc: content('div.post-content').html(), + }); + item.pubDate = timezone(parseDate(content('time').text().trim()), +8); + item.author = content('a.mr-1.text-primary').text().trim(); + + return item; + }) + ) + ); + + ctx.state.data = { + title: $('head title').text().trim(), + link: baseUrl + '/' + topic, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; + + ctx.state.json = { + title: $('head title').text().trim(), + link: baseUrl + '/' + topic, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; +}; diff --git a/lib/v2/agirls/topic_list.js b/lib/v2/agirls/topic_list.js new file mode 100644 index 0000000000..3602823e93 --- /dev/null +++ b/lib/v2/agirls/topic_list.js @@ -0,0 +1,44 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const baseUrl = 'https://agirls.aotter.net'; + const category = 'topic'; + + const response = await got({ + url: baseUrl + '/' + category, + header: { + Referer: baseUrl, + }, + }); + + const $ = cheerio.load(response.data); + + const items = $('div div.border-b.border-neutral-lighter') + .map((_, item) => { + item = $(item); + const link = baseUrl + item.find('a').attr('href'); + return ctx.cache.tryGet(link, () => ({ + title: item.find('h2').text().trim(), + description: item.find('a').attr('href').replace('/topic/', ''), + link, + })); + }) + .get(); + + ctx.state.data = { + title: $('head title').text().trim(), + link: baseUrl + '/' + category, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; + + ctx.state.json = { + title: $('head title').text().trim(), + link: baseUrl + '/' + category, + description: $('head meta[name=description]').attr('content'), + item: items, + language: $('html').attr('lang'), + }; +};