feat(route): 得到用户主页 (#10993)
* feat(route): 得到用户主页 * fix typo * fix: maintainer
This commit is contained in:
parent
8de58eeeb0
commit
4dbadfe2b8
|
|
@ -1812,7 +1812,7 @@ Supported sub-sites:
|
|||
|
||||
### 首页
|
||||
|
||||
<Route author="nczitzk" example="/dedao/list/年度日更" path="/dedao/list/:caty?" :paramsDesc="['分类名,默认为年度日更']"/>
|
||||
<Route author="nczitzk" example="/dedao/list/年度日更" path="/dedao/list/:category?" :paramsDesc="['分类名,默认为年度日更']"/>
|
||||
|
||||
### 新闻
|
||||
|
||||
|
|
@ -1828,7 +1828,17 @@ Supported sub-sites:
|
|||
|
||||
### 知识城邦
|
||||
|
||||
<Route author="nczitzk" example="/dedao/knowledge" path="/dedao/knowledge/:topic?/:type?" :paramsDesc="['话题 id,可在话题页 URL 中找到', '分享类型,`true` 指精选,`false` 指最新,默认为精选']"/>
|
||||
<Route author="nczitzk" example="/dedao/knowledge" path="/dedao/knowledge/:topic?/:type?" :paramsDesc="['话题 id,可在对应话题页 URL 中找到', '分享类型,`true` 指精选,`false` 指最新,默认为精选']"/>
|
||||
|
||||
### 用户主页
|
||||
|
||||
<Route author="nczitzk" example="/dedao/user/VkA5OqLX4RyGxmZRNBMlwBrDaJQ9og" path="/dedao/user/:id/:type?" :paramsDesc="['用户 id,可在对应用户主页 URL 中找到', '类型,见下表,默认为`0`,即动态']">
|
||||
|
||||
| 动态 | 书评 | 视频 |
|
||||
| -- | -- | -- |
|
||||
| 0 | 7 | 12 |
|
||||
|
||||
</Route>
|
||||
|
||||
## 电动邦
|
||||
|
||||
|
|
|
|||
|
|
@ -3353,9 +3353,9 @@ router.get('/nwpu/:column', lazyloadRouteHandler('./routes/nwpu/index'));
|
|||
router.get('/us/supremecourt/argument_audio/:year?', lazyloadRouteHandler('./routes/us/supremecourt/argument_audio'));
|
||||
|
||||
// 得到
|
||||
router.get('/dedao/list/:caty?', lazyloadRouteHandler('./routes/dedao/list'));
|
||||
router.get('/dedao/knowledge/:topic?/:type?', lazyloadRouteHandler('./routes/dedao/knowledge'));
|
||||
router.get('/dedao/:caty?', lazyloadRouteHandler('./routes/dedao/index'));
|
||||
// router.get('/dedao/list/:caty?', lazyloadRouteHandler('./routes/dedao/list'));
|
||||
// router.get('/dedao/knowledge/:topic?/:type?', lazyloadRouteHandler('./routes/dedao/knowledge'));
|
||||
// router.get('/dedao/:caty?', lazyloadRouteHandler('./routes/dedao/index'));
|
||||
|
||||
// 未名新闻
|
||||
router.get('/mitbbs/:caty?', lazyloadRouteHandler('./routes/mitbbs/index'));
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const date = require('@/utils/date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const topic = ctx.params.topic || '';
|
||||
const type = ctx.params.type || 'true';
|
||||
const rootUrl = 'https://www.dedao.cn';
|
||||
const detailUrl = `${rootUrl}/pc/ledgers/topic/detail`;
|
||||
const currentUrl = `${rootUrl}/knowledge${topic === '' ? '' : '/topic/' + topic}`;
|
||||
const apiUrl = `${rootUrl}/pc/ledgers/${topic === '' ? 'notes/friends_timeline' : 'topic/notes/list'}`;
|
||||
|
||||
let title = '',
|
||||
description = '';
|
||||
|
||||
if (topic !== '') {
|
||||
const detailResponse = await got({
|
||||
method: 'post',
|
||||
url: detailUrl,
|
||||
json: {
|
||||
incr_view_count: false,
|
||||
topic_id_hazy: topic,
|
||||
},
|
||||
});
|
||||
|
||||
title = detailResponse.data.c.name;
|
||||
description = detailResponse.data.c.intro;
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'post',
|
||||
url: apiUrl,
|
||||
json: {
|
||||
count: 20,
|
||||
load_chain: true,
|
||||
is_elected: type === 'true',
|
||||
page_id: 0,
|
||||
topic_id_hazy: topic,
|
||||
version: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const items = (topic === '' ? response.data.c.notes : response.data.c.note_detail_list).map((item) => {
|
||||
let s_part = '';
|
||||
if (item.s_part) {
|
||||
const s_author = `<p>引用 ${item.s_part.nick_name} (${item.s_part.v_info}):</p>`;
|
||||
const s_content = `<p>${item.s_part.note.replace(/\n\n/g, '</p><p>')}</p> <a href="${rootUrl}/knowledge/note/${item.s_part.note_id_hazy}">[查看原文]</a>`;
|
||||
let s_images = '<br>';
|
||||
if (item.s_part.images) {
|
||||
for (const i of item.s_part.images) {
|
||||
s_images += `<img src="${i.match(/"url":"(.*)"/)[1]}">`;
|
||||
}
|
||||
}
|
||||
s_part = s_author + s_content + s_images;
|
||||
}
|
||||
|
||||
let f_images = '<br>';
|
||||
if (item.f_part.images) {
|
||||
for (const i of item.f_part.images) {
|
||||
f_images += `<img src="${i.match(/"url":"(.*)"/)[1]}">`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: item.f_part.note,
|
||||
author: item.f_part.nick_name,
|
||||
description: `<p>${item.f_part.note.replace(/\n\n/g, '</p><p>')}</p>${f_images}<br>${s_part}`,
|
||||
link: `${rootUrl}/knowledge/note/${item.f_part.note_id_hazy}`,
|
||||
pubDate: new Date(date(item.f_part.time_desc)).toUTCString(),
|
||||
};
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `得到 - 知识城邦${title === '' ? '' : ' - ' + title}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
description,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const caty = ctx.params.caty || 'news';
|
||||
const rootUrl = `https://www.igetget.com/${caty === 'video' ? 'video' : 'news'}`;
|
||||
const category = ctx.params.category ?? 'news';
|
||||
|
||||
const rootUrl = `https://www.igetget.com/${category === 'video' ? 'video' : 'news'}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
|
|
@ -12,19 +14,20 @@ module.exports = async (ctx) => {
|
|||
|
||||
const data = JSON.parse(response.data.match(/window.__INITIAL_STATE__= (.*);<\/script>/)[1]);
|
||||
|
||||
const list = (caty === 'news' ? data.news : caty === 'figure' ? data.figure : data.videoList).map((item) => ({
|
||||
let items = (category === 'news' ? data.news : category === 'figure' ? data.figure : data.videoList).map((item) => ({
|
||||
title: item.title,
|
||||
pubDate: new Date(item.online_time).toUTCString(),
|
||||
link: `${rootUrl}/${caty === 'news' ? 'article/' : caty === 'figure' ? 'people/' : ''}${item.online_time.split('T')[0].split('-').join('')}/${item.token}`,
|
||||
pubDate: parseDate(item.online_time),
|
||||
link: `${rootUrl}/${category === 'news' ? 'article/' : category === 'figure' ? 'people/' : ''}${item.online_time.split('T')[0].split('-').join('')}/${item.token}`,
|
||||
}));
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
item.description = content('.menu-article').html();
|
||||
|
|
@ -35,7 +38,7 @@ module.exports = async (ctx) => {
|
|||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `得到${caty === 'video' ? '' : '大事件'} - ${caty === 'news' ? '新闻' : caty === 'figure' ? '人物故事' : '视频'}`,
|
||||
title: `得到${category === 'video' ? '' : '大事件'} - ${category === 'news' ? '新闻' : category === 'figure' ? '人物故事' : '视频'}`,
|
||||
link: rootUrl,
|
||||
item: items,
|
||||
description: data.description,
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const topic = ctx.params.topic ?? '';
|
||||
const type = /t|y/i.test(ctx.params.type ?? 'true');
|
||||
const count = ctx.query.limit ? parseInt(ctx.query.limit) : 100;
|
||||
|
||||
const rootUrl = 'https://www.dedao.cn';
|
||||
const currentUrl = `${rootUrl}/knowledge${topic === '' ? '' : '/topic/' + topic}`;
|
||||
const apiUrl = `${rootUrl}/pc/ledgers/${topic === '' ? 'notes/friends_timeline' : 'topic/notes/list'}`;
|
||||
const detailUrl = `${rootUrl}/pc/ledgers/topic/detail`;
|
||||
|
||||
let title = '',
|
||||
description = '';
|
||||
|
||||
if (topic !== '') {
|
||||
const detailResponse = await got({
|
||||
method: 'post',
|
||||
url: detailUrl,
|
||||
json: {
|
||||
incr_view_count: false,
|
||||
topic_id_hazy: topic,
|
||||
},
|
||||
});
|
||||
|
||||
title = detailResponse.data.c.name;
|
||||
description = detailResponse.data.c.intro;
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'post',
|
||||
url: apiUrl,
|
||||
json: {
|
||||
count,
|
||||
load_chain: true,
|
||||
is_elected: type,
|
||||
page_id: 0,
|
||||
topic_id_hazy: topic,
|
||||
version: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const items = (topic === '' ? response.data.c.notes : response.data.c.note_detail_list).map((item) => ({
|
||||
title: item.f_part.note,
|
||||
author: item.f_part.nick_name,
|
||||
link: `${rootUrl}/knowledge/note/${item.f_part.note_id_hazy}`,
|
||||
pubDate: parseDate(item.f_part.time_desc, 'MM-DD'),
|
||||
description: art(path.join(__dirname, 'templates/knowledge.art'), {
|
||||
rootUrl,
|
||||
f_part: item.f_part,
|
||||
s_part: item.s_part,
|
||||
}),
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
title: `得到 - 知识城邦${title === '' ? '' : ' - ' + title}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
description,
|
||||
};
|
||||
};
|
||||
|
|
@ -2,20 +2,24 @@ const got = require('@/utils/got');
|
|||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const caty = ctx.params.caty || '年度日更';
|
||||
const category = ctx.params.category ?? '年度日更';
|
||||
|
||||
const rootUrl = 'https://www.igetget.com';
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: rootUrl,
|
||||
});
|
||||
|
||||
const listUrl = `${rootUrl}${response.data.match(new RegExp('<a href="(.*)">年度日更<\\/a>'))[1]}`;
|
||||
|
||||
const listResponse = await got({
|
||||
method: 'get',
|
||||
url: listUrl,
|
||||
});
|
||||
|
||||
const currentUrl = `${rootUrl}${listResponse.data.match(new RegExp('<span>' + caty + '<\\/span><a href="(.*)" rel="tag"><\\/a>'))[1].split('"')[0]}`;
|
||||
const currentUrl = `${rootUrl}${listResponse.data.match(new RegExp('<span>' + category + '<\\/span><a href="(.*)" rel="tag"><\\/a>'))[1].split('"')[0]}`;
|
||||
|
||||
const currentResponse = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
|
|
@ -23,24 +27,26 @@ module.exports = async (ctx) => {
|
|||
|
||||
const $ = cheerio.load(currentResponse.data);
|
||||
|
||||
const list = $('.pro-info p a')
|
||||
.slice(0, 10)
|
||||
.map((_, item) => {
|
||||
let items = $('.pro-info p a')
|
||||
.toArray()
|
||||
.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 10)
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
|
||||
return {
|
||||
title: item.text(),
|
||||
link: `${rootUrl}${item.attr('href')}`,
|
||||
};
|
||||
})
|
||||
.get();
|
||||
});
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
content('.more-bt').remove();
|
||||
|
|
@ -53,7 +59,7 @@ module.exports = async (ctx) => {
|
|||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `得到 - ${caty}`,
|
||||
title: `得到 - ${category}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
'/figure': ['nczitzk'],
|
||||
'/knowledge/:topic?/:type?': ['nczitzk'],
|
||||
'/list/:category?': ['nczitzk'],
|
||||
'/news': ['nczitzk'],
|
||||
'/user/:id/:type?': ['nczitzk'],
|
||||
'/video': ['nczitzk'],
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
module.exports = {
|
||||
'dedao.cn': {
|
||||
_name: '得到',
|
||||
'.': [
|
||||
{
|
||||
title: '知识城邦',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-zhi-shi-cheng-bang',
|
||||
source: ['/knowledge/topic/:topic', '/knowledge', '/'],
|
||||
target: '/dedao/knowledge/:topic?/:type?',
|
||||
},
|
||||
],
|
||||
},
|
||||
'igetget.com': {
|
||||
_name: '得到',
|
||||
'.': [
|
||||
{
|
||||
title: '首页',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-shou-ye',
|
||||
source: ['/'],
|
||||
target: '/dedao/list/:category?',
|
||||
},
|
||||
{
|
||||
title: '新闻',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-xin-wen',
|
||||
source: ['/news', '/'],
|
||||
target: '/dedao/news',
|
||||
},
|
||||
{
|
||||
title: '人物故事',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-ren-wu-gu-shi',
|
||||
source: ['/news', '/'],
|
||||
target: '/dedao/figure',
|
||||
},
|
||||
{
|
||||
title: '视频',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-shi-pin',
|
||||
source: ['/video', '/'],
|
||||
target: '/dedao/video',
|
||||
},
|
||||
],
|
||||
m: [
|
||||
{
|
||||
title: '用户主页',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#de-dao-yong-hu-zhu-ye',
|
||||
source: ['/native/mine/account', '/'],
|
||||
target: (params, url) => `/dedao/user/${new URL(url).searchParams.get('enId')}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/knowledge/:topic?/:type?', require('./knowledge'));
|
||||
router.get('/list/:category?', require('./list'));
|
||||
router.get('/user/:id/:type?', require('./user'));
|
||||
router.get('/:category?', require('./index'));
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{{ if f_part.note }}
|
||||
<p>{{@ f_part.note
|
||||
.replace(/\n\n/g, '</p><p>')
|
||||
.replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1')
|
||||
}}</p>
|
||||
{{ /if }}
|
||||
{{ if f_part.images }}
|
||||
<br>
|
||||
{{ set f_part_images = f_part.images }}
|
||||
{{ each f_part_images image }}
|
||||
<img src="{{ image.match(/"url":"(.*?)"/)[1] }}">
|
||||
{{ /each }}
|
||||
{{ /if }}
|
||||
{{ if s_part }}
|
||||
<br>
|
||||
<p>引用 {{ s_part.nick_name }}{{ if s_part.v_info }} ({{ s_part.v_info }}){{ /if }}:</p>
|
||||
<p>{{@ s_part.note
|
||||
.replace(/\n\n/g, '</p><p>')
|
||||
.replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1')
|
||||
}}</p>
|
||||
<a href="{{ rootUrl }}/knowledge/note/{{ s_part.note_id_hazy }}">[查看原文]</a>
|
||||
{{ if s_part.images }}
|
||||
<br>
|
||||
{{ set s_part_images = s_part.images }}
|
||||
{{ each s_part_images image}}
|
||||
<img src="{{ image.match(/"url":"(.*?)"/)[1] }}">
|
||||
{{ /each }}
|
||||
{{ /if }}
|
||||
{{ /if }}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{{ if name }}
|
||||
<p>{{@ content
|
||||
.replace(/\n\n/g, '</p><p>')
|
||||
.replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1')
|
||||
}}</p>
|
||||
<br>
|
||||
<p>引用 {{ name }}{{ if vinfo }} ({{ vinfo }}){{ /if }}:</p>
|
||||
{{ /if }}
|
||||
<p>{{@ note
|
||||
.replace(/\n\n/g, '</p><p>')
|
||||
.replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1')
|
||||
}}</p>
|
||||
{{ if extra }}
|
||||
<br>
|
||||
{{ if extra.img }}
|
||||
{{ if extra.share_ext }}
|
||||
<a href="{{ extra.share_ext.h_5_url }}">
|
||||
{{ /if }}
|
||||
<figure>
|
||||
<img src="{{ extra.img }}">
|
||||
<figcaption>{{ extra.title }}</figcaption>
|
||||
</figure>
|
||||
{{ if extra.share_ext }}
|
||||
</a>
|
||||
{{ /if }}
|
||||
{{ /if }}
|
||||
{{ if extra.images }}
|
||||
{{ set extra_images = extra.images }}
|
||||
{{ each extra_images image }}
|
||||
<img src="{{ image.match(/"url":"(.*?)"/)[1] }}">
|
||||
{{ /each }}
|
||||
{{ /if }}
|
||||
{{ if video }}
|
||||
<figure>
|
||||
<img src="{{ video.match(/"url":"(.*?)"/)[1] }}">
|
||||
</figure>
|
||||
{{ /if }}
|
||||
{{ /if }}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
const types = {
|
||||
0: '动态',
|
||||
7: '书评',
|
||||
12: '视频',
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id ?? '';
|
||||
const type = ctx.params.type ? parseInt(ctx.params.type) : 0;
|
||||
const count = ctx.query.limit ? parseInt(ctx.query.limit) : 100;
|
||||
|
||||
const rootUrl = 'https://m.igetget.com';
|
||||
const currentUrl = `${rootUrl}/native/mine/account#/user/detail?enId=${id}`;
|
||||
const apiUrl = `${rootUrl}/native/api/homePage/topicNote`;
|
||||
const infoUrl = `${rootUrl}/native/api/homePage/userInfo`;
|
||||
|
||||
const detailResponse = await got({
|
||||
method: 'post',
|
||||
url: infoUrl,
|
||||
json: {
|
||||
hazy: id,
|
||||
},
|
||||
});
|
||||
|
||||
const data = detailResponse.data;
|
||||
|
||||
const author = data.c.nickname;
|
||||
const image = data.c.avatar;
|
||||
const description = `${data.c.v_info}: ${data.c.slogan}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'post',
|
||||
url: apiUrl,
|
||||
json: {
|
||||
uid: null,
|
||||
max_id_str: '0',
|
||||
count,
|
||||
max_createtime: 0,
|
||||
is_only_repost: 0,
|
||||
load_chain: true,
|
||||
load_tag: 1,
|
||||
source: 0,
|
||||
note_type: type,
|
||||
only_origin: false,
|
||||
with_highlight: true,
|
||||
hazy: id,
|
||||
},
|
||||
});
|
||||
|
||||
const items = response.data.c.list.map((item) => ({
|
||||
author,
|
||||
title: item.content || item.note || item.extra.title,
|
||||
link: item.share_url,
|
||||
pubDate: parseDate(item.create_time * 1000),
|
||||
description: art(path.join(__dirname, 'templates/user.art'), {
|
||||
rootUrl,
|
||||
name: item.origin_notes_owner.name,
|
||||
vinfo: item.origin_notes_owner.Vinfo,
|
||||
content: item.content,
|
||||
note: item.note,
|
||||
extra: item.extra,
|
||||
video: item.video.video_cover,
|
||||
}),
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${author}的得到主页 - ${types[type]}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
image,
|
||||
description,
|
||||
allowEmpty: true,
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue