diff --git a/docs/new-media.md b/docs/new-media.md index e7079ae80..7528d376a 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -1812,7 +1812,7 @@ Supported sub-sites: ### 首页 - + ### 新闻 @@ -1828,7 +1828,17 @@ Supported sub-sites: ### 知识城邦 - + + +### 用户主页 + + + +| 动态 | 书评 | 视频 | +| -- | -- | -- | +| 0 | 7 | 12 | + + ## 电动邦 diff --git a/lib/router.js b/lib/router.js index b9358a332..204ac341f 100644 --- a/lib/router.js +++ b/lib/router.js @@ -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')); diff --git a/lib/routes/dedao/knowledge.js b/lib/routes/dedao/knowledge.js deleted file mode 100644 index 06fdfb9f6..000000000 --- a/lib/routes/dedao/knowledge.js +++ /dev/null @@ -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 = `

引用 ${item.s_part.nick_name} (${item.s_part.v_info}):

`; - const s_content = `

${item.s_part.note.replace(/\n\n/g, '

')}

[查看原文]`; - let s_images = '
'; - if (item.s_part.images) { - for (const i of item.s_part.images) { - s_images += ``; - } - } - s_part = s_author + s_content + s_images; - } - - let f_images = '
'; - if (item.f_part.images) { - for (const i of item.f_part.images) { - f_images += ``; - } - } - - return { - title: item.f_part.note, - author: item.f_part.nick_name, - description: `

${item.f_part.note.replace(/\n\n/g, '

')}

${f_images}
${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, - }; -}; diff --git a/lib/routes/dedao/index.js b/lib/v2/dedao/index.js similarity index 52% rename from lib/routes/dedao/index.js rename to lib/v2/dedao/index.js index 41a5725b4..e53c8bc88 100644 --- a/lib/routes/dedao/index.js +++ b/lib/v2/dedao/index.js @@ -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, diff --git a/lib/v2/dedao/knowledge.js b/lib/v2/dedao/knowledge.js new file mode 100644 index 000000000..3a1aa66a8 --- /dev/null +++ b/lib/v2/dedao/knowledge.js @@ -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, + }; +}; diff --git a/lib/routes/dedao/list.js b/lib/v2/dedao/list.js similarity index 76% rename from lib/routes/dedao/list.js rename to lib/v2/dedao/list.js index 7be680b51..0277441c3 100644 --- a/lib/routes/dedao/list.js +++ b/lib/v2/dedao/list.js @@ -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>'))[1]}`; + const listResponse = await got({ method: 'get', url: listUrl, }); - const currentUrl = `${rootUrl}${listResponse.data.match(new RegExp('' + caty + '<\\/span>[查看原文] +{{ if s_part.images }} +
+{{ set s_part_images = s_part.images }} +{{ each s_part_images image}} + +{{ /each }} +{{ /if }} +{{ /if }} \ No newline at end of file diff --git a/lib/v2/dedao/templates/user.art b/lib/v2/dedao/templates/user.art new file mode 100644 index 000000000..fc4525e23 --- /dev/null +++ b/lib/v2/dedao/templates/user.art @@ -0,0 +1,38 @@ +{{ if name }} +

{{@ content + .replace(/\n\n/g, '

') + .replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1') + }}

+
+

引用 {{ name }}{{ if vinfo }} ({{ vinfo }}){{ /if }}:

+{{ /if }} +

{{@ note + .replace(/\n\n/g, '

') + .replace(/<≧❆>{"name":"(.*?)","uid":"\d+","at":"1"}<\/≦❆>/g, ' @$1') + }}

+{{ if extra }} +
+{{ if extra.img }} +{{ if extra.share_ext }} + +{{ /if }} +
+ +
{{ extra.title }}
+
+{{ if extra.share_ext }} +
+{{ /if }} +{{ /if }} +{{ if extra.images }} +{{ set extra_images = extra.images }} +{{ each extra_images image }} + +{{ /each }} +{{ /if }} +{{ if video }} +
+ +
+{{ /if }} +{{ /if }} \ No newline at end of file diff --git a/lib/v2/dedao/user.js b/lib/v2/dedao/user.js new file mode 100644 index 000000000..9a5046498 --- /dev/null +++ b/lib/v2/dedao/user.js @@ -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, + }; +};