diff --git a/docs/social-media.md b/docs/social-media.md index 4914a9eab..90527ead1 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -766,6 +766,10 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 +### 最新回应过的日记 + + + ### 话题 diff --git a/lib/router.js b/lib/router.js index e0a00b850..16cdbc170 100644 --- a/lib/router.js +++ b/lib/router.js @@ -195,6 +195,7 @@ router.get('/douban/doulist/:id', require('./routes/douban/doulist')); router.get('/douban/explore/column/:id', require('./routes/douban/explore_column')); router.get('/douban/people/:userid/status/:routeParams?', require('./routes/douban/people/status.js')); router.get('/douban/replies/:uid', require('./routes/douban/replies')); +router.get('/douban/replied/:uid', require('./routes/douban/replied')); router.get('/douban/topic/:id/:sort?', require('./routes/douban/topic.js')); router.get('/douban/channel/:id/:nav?', require('./routes/douban/channel/topic.js')); router.get('/douban/channel/:id/subject/:nav', require('./routes/douban/channel/subject.js')); diff --git a/lib/routes/douban/replied.js b/lib/routes/douban/replied.js new file mode 100644 index 000000000..3f4c73afb --- /dev/null +++ b/lib/routes/douban/replied.js @@ -0,0 +1,87 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const currentUrl = `https://www.douban.com/people/${ctx.params.uid}/notes`; + const response = await got({ + method: 'get', + url: currentUrl, + }); + + const $ = cheerio.load(response.data); + const list = $('div.recent-replied-mod ul.comment-list li') + .map((_, item) => { + item = $(item); + const p = item.find('p'); + const nid = p + .find('a') + .attr('href') + .match(/%2Fnote%2F(.*?)%2F&type=note/)[1]; + const title = p.find('a').text(); + p.remove(); + + return { + title: `${item.find('a.lnk-people').text()} - ${title}`, + link: `https://www.douban.com/note/${nid}`, + }; + }) + .get(); + + const items = await Promise.all( + list.map( + async (item) => + await ctx.cache.tryGet(item.link, async () => { + try { + const detailResponse = await got({ + method: 'get', + url: item.link, + }); + const match = detailResponse.data.match(/'comments':(.*)}],/); + + if (match.length > 1) { + const content = cheerio.load(detailResponse.data); + const title = `${content('a.note-author').text()} - ${content('h1').text()}`; + + const comments = JSON.parse(match[1] + '}]'); + + let latest = new Date(0), + description, + pubDate, + author; + + for (const c of comments) { + if (c.author.uid === ctx.params.uid && new Date(c.create_time) > new Date(latest)) { + latest = new Date(c.create_time + ' GMT+8'); + pubDate = latest.toUTCString(); + description = c.text; + author = c.author.name; + } else if (c.replies.length > 0) { + comments.push(...c.replies); + } + } + + return { + title, + description, + pubDate, + author, + link: item.link, + }; + } + throw Error('No comments'); + } catch (error) { + return { + title: item.title, + link: item.link, + }; + } + }) + ) + ); + + ctx.state.data = { + title: $('title').text() + ' - 最新回应过', + link: currentUrl, + item: items, + }; +};