From 02491add100bfd3b01a6d2da727a5356ca246f89 Mon Sep 17 00:00:00 2001
From: Ethan Shen <42264778+nczitzk@users.noreply.github.com>
Date: Thu, 7 Sep 2023 00:12:23 +0800
Subject: [PATCH] =?UTF-8?q?feat(route):=20add=20=E7=90=86=E6=83=B3?=
=?UTF-8?q?=E7=94=9F=E6=B4=BB=E5=AE=9E=E9=AA=8C=E5=AE=A4=20(#13207)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat(route): add 理想生活实验室
* fix docs
* update lib/v2/toodaylab/index.js
---------
---
lib/v2/toodaylab/index.js | 99 ++++++++++++++++++++++++++++++++
lib/v2/toodaylab/maintainer.js | 7 +++
lib/v2/toodaylab/radar.js | 37 ++++++++++++
lib/v2/toodaylab/router.js | 3 +
website/docs/routes/new-media.md | 40 +++++++++++++
5 files changed, 186 insertions(+)
create mode 100644 lib/v2/toodaylab/index.js
create mode 100644 lib/v2/toodaylab/maintainer.js
create mode 100644 lib/v2/toodaylab/radar.js
create mode 100644 lib/v2/toodaylab/router.js
diff --git a/lib/v2/toodaylab/index.js b/lib/v2/toodaylab/index.js
new file mode 100644
index 000000000..fda14bfec
--- /dev/null
+++ b/lib/v2/toodaylab/index.js
@@ -0,0 +1,99 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const timezone = require('@/utils/timezone');
+const { parseDate, parseRelativeDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const { params = 'posts' } = ctx.params;
+ const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30;
+
+ const isHot = params === 'hot';
+
+ const rootUrl = 'https://www.toodaylab.com';
+ const currentUrl = new URL(isHot ? 'posts' : params, rootUrl).href;
+
+ const { data: response } = await got(currentUrl);
+
+ const $ = cheerio.load(response);
+
+ let items = isHot
+ ? $('div.hot-list a')
+ .slice(0, limit)
+ .toArray()
+ .map((item) => {
+ item = $(item);
+
+ return {
+ title: item.find('div.hot-item p').text(),
+ link: new URL(item.prop('href'), rootUrl).href,
+ };
+ })
+ : $('div.single-post')
+ .slice(0, limit)
+ .toArray()
+ .map((item) => {
+ item = $(item);
+
+ const a = item.find('p.title a');
+
+ const pubDate = item
+ .find('div.left-infos p')
+ .text()
+ .trim()
+ .split(/\/\/\s/)
+ .pop();
+
+ return {
+ title: a.text(),
+ link: new URL(a.prop('href'), rootUrl).href,
+ description: item.find('p.excerpt').html(),
+ author: item.find('div.left-infos p a').text().trim(),
+ pubDate: timezone(/年|月|日/.test(pubDate) ? parseDate(pubDate, ['YYYY年M月D日 HH:mm', 'M月D日 HH:mm']) : parseRelativeDate(pubDate), +8),
+ };
+ });
+
+ items = await Promise.all(
+ items.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: detailResponse } = await got(item.link);
+
+ const content = cheerio.load(detailResponse);
+
+ const pubDate = content('div.left-infos p')
+ .text()
+ .trim()
+ .split(/\/\/\s/)
+ .pop();
+
+ item.title = content('h1').text() || item.title;
+ item.description = content('div.post-content').html() ?? item.description;
+ item.author = content('div.left-infos p a').text().trim() ?? item.author;
+ item.category = content('div.right-infos a')
+ .slice(1)
+ .toArray()
+ .map((c) => content(c).text().replace(/#/, ''));
+ item.pubDate = item.pubDate ?? timezone(/年|月|日/.test(pubDate) ? parseDate(pubDate, ['YYYY年M月D日 HH:mm', 'M月D日 HH:mm']) : parseRelativeDate(pubDate), +8);
+ item.upvotes = content('#like_count').text() ? parseInt(content('#like_count').text(), 10) : 0;
+ item.comments = parseInt(content('div.right-infos a').first().text(), 10) || 0;
+
+ return item;
+ })
+ )
+ );
+
+ const title = $('title').text().split(/\s-/)[0];
+ const icon = $('link[rel="apple-touch-icon"]').last().prop('href');
+
+ ctx.state.data = {
+ item: items,
+ title: isHot ? title.replace(/[^|]+/, '最热 ') : title,
+ link: currentUrl,
+ description: $('meta[name="description"]').prop('content'),
+ language: $('html').prop('lang'),
+ image: $('h3.logo a img').prop('src'),
+ icon,
+ logo: icon,
+ subtitle: $('meta[name="keywords"]').prop('content'),
+ author: $('h3.logo a img').prop('alt'),
+ };
+};
diff --git a/lib/v2/toodaylab/maintainer.js b/lib/v2/toodaylab/maintainer.js
new file mode 100644
index 000000000..f7e886857
--- /dev/null
+++ b/lib/v2/toodaylab/maintainer.js
@@ -0,0 +1,7 @@
+module.exports = {
+ '/column/:id': ['nczitzk'],
+ '/field/:id': ['nczitzk'],
+ '/hot': ['nczitzk'],
+ '/posts': ['nczitzk'],
+ '/topic/:id': ['nczitzk'],
+};
diff --git a/lib/v2/toodaylab/radar.js b/lib/v2/toodaylab/radar.js
new file mode 100644
index 000000000..80a45f2b7
--- /dev/null
+++ b/lib/v2/toodaylab/radar.js
@@ -0,0 +1,37 @@
+module.exports = {
+ 'toodaylab.com': {
+ _name: '理想生活实验室',
+ '.': [
+ {
+ title: '滚动',
+ docs: 'https://docs.rsshub.app/routes/new-media#li-xiang-sheng-huo-shi-yan-shi-gun-dong',
+ source: ['/posts'],
+ target: '/toodaylab/posts',
+ },
+ {
+ title: '最热',
+ docs: 'https://docs.rsshub.app/routes/new-media#li-xiang-sheng-huo-shi-yan-shi-zui-re',
+ source: ['/posts'],
+ target: '/toodaylab/hot',
+ },
+ {
+ title: '专栏',
+ docs: 'https://docs.rsshub.app/routes/new-media#li-xiang-sheng-huo-shi-yan-shi-zhuan-lan',
+ source: ['/column/:id'],
+ target: '/toodaylab/column/:id',
+ },
+ {
+ title: '领域',
+ docs: 'https://docs.rsshub.app/routes/new-media#li-xiang-sheng-huo-shi-yan-shi-ling-yu',
+ source: ['/field/:id'],
+ target: '/toodaylab/field/:id',
+ },
+ {
+ title: '话题',
+ docs: 'https://docs.rsshub.app/routes/new-media#li-xiang-sheng-huo-shi-yan-shi-hua-ti',
+ source: ['/topic/:id'],
+ target: '/toodaylab/topic/:id',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/toodaylab/router.js b/lib/v2/toodaylab/router.js
new file mode 100644
index 000000000..a8cead003
--- /dev/null
+++ b/lib/v2/toodaylab/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/:params*', require('./'));
+};
diff --git a/website/docs/routes/new-media.md b/website/docs/routes/new-media.md
index 059223fdc..45d7fb7a0 100644
--- a/website/docs/routes/new-media.md
+++ b/website/docs/routes/new-media.md
@@ -3384,6 +3384,46 @@ column 为 third 时可选的 category:
+## 理想生活实验室 {#li-xiang-sheng-huo-shi-yan-shi}
+
+### 滚动 {#li-xiang-sheng-huo-shi-yan-shi-gun-dong}
+
+
+
+### 最热 {#li-xiang-sheng-huo-shi-yan-shi-zui-re}
+
+
+
+### 专栏 {#li-xiang-sheng-huo-shi-yan-shi-zhuan-lan}
+
+
+
+| 专题 | 攻略 |
+| ---- | ---- |
+| 299 | 300 |
+
+
+
+### 领域 {#li-xiang-sheng-huo-shi-yan-shi-ling-yu}
+
+
+
+| 快消 | 时尚 | 智能 | 娱乐 | 运动 | 生活 | 设计 | 出行 |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| 308 | 307 | 306 | 305 | 304 | 303 | 302 | 301 |
+
+
+
+### 话题 {#li-xiang-sheng-huo-shi-yan-shi-hua-ti}
+
+
+
+| 今日消费资讯 | 实验室带你过周末 | 实验室带你过假期 | 每日一图 | 每周一书 | 实验室数字 | 新鲜社会人 | 实验室TV |
+| ------------ | ---------------- | ---------------- | -------- | -------- | ---------- | ---------- | -------- |
+| 309 | 37 | 40 | 32 | 33 | 310 | 316 | 476 |
+
+
+
## 链捕手 ChainCatcher {#lian-bu-shou-chaincatcher}
### 首页 {#lian-bu-shou-chaincatcher-shou-ye}