diff --git a/docs/en/new-media.md b/docs/en/new-media.md index 7ec015df91..3946e6fd1c 100644 --- a/docs/en/new-media.md +++ b/docs/en/new-media.md @@ -79,6 +79,10 @@ Provides a better reading experience (full text articles) over the official one. +### Following diary + + + ## Nautilus ### Topics diff --git a/lib/router.js b/lib/router.js index 9792acba47..3b299bbbf7 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2177,6 +2177,7 @@ router.get('/mqube/top', require('./routes/mqube/top')); // Letterboxd router.get('/letterboxd/user/diary/:username', require('./routes/letterboxd/userdiary')); +router.get('/letterboxd/user/followingdiary/:username', require('./routes/letterboxd/followingdiary')); // 网易大神 router.get('/netease/ds/:id', require('./routes/netease/ds')); diff --git a/lib/routes/letterboxd/followingdiary.js b/lib/routes/letterboxd/followingdiary.js new file mode 100644 index 0000000000..f675c8be2e --- /dev/null +++ b/lib/routes/letterboxd/followingdiary.js @@ -0,0 +1,8 @@ +const utils = require('./utils'); + +module.exports = async (ctx) => { + const url = `https://letterboxd.com/${ctx.params.username}/following/`; + const title = `Letterboxd - following diary - ${ctx.params.username}`; + + ctx.state.data = await utils.getFollowingData(ctx, ctx.params.username, url, title); +}; diff --git a/lib/routes/letterboxd/userdiary.js b/lib/routes/letterboxd/userdiary.js index 57d4d47a34..a363f5ad3f 100644 --- a/lib/routes/letterboxd/userdiary.js +++ b/lib/routes/letterboxd/userdiary.js @@ -4,5 +4,5 @@ module.exports = async (ctx) => { const url = `https://letterboxd.com/${ctx.params.username}/films/diary/by/added/`; const title = `Letterboxd - diary - ${ctx.params.username}`; - ctx.state.data = await utils.getData(ctx, url, title); + ctx.state.data = await utils.getData(ctx, ctx.params.username, url, title); }; diff --git a/lib/routes/letterboxd/utils.js b/lib/routes/letterboxd/utils.js index 5cccb70bbc..bd7309059a 100644 --- a/lib/routes/letterboxd/utils.js +++ b/lib/routes/letterboxd/utils.js @@ -43,7 +43,7 @@ async function ProcessFeed(list, username, caches) { const rewatch = $('.td-rewatch.icon-status-off').length <= 0; const hasReview = $('.td-review.icon-status-off').length <= 0; - let descriptionText = `${filmTitle}
Watched: ${displayDate}
Rating: ${rating}`; + let descriptionText = `${filmTitle}
watched by ${username}
Date: ${displayDate}
Rating: ${rating}`; if (liked) { descriptionText = descriptionText.concat('
Liked'); @@ -75,7 +75,7 @@ async function ProcessFeed(list, username, caches) { ); } -const getData = async (ctx, url, title) => { +const getData = async (ctx, username, url, title) => { const response = await got({ method: 'get', url: url, @@ -87,7 +87,7 @@ const getData = async (ctx, url, title) => { const $ = cheerio.load(response.data); const list = $('.diary-entry-row').get(); - const result = await ProcessFeed(list, ctx.params.username, ctx.cache); + const result = await ProcessFeed(list, username, ctx.cache); return { title: title, @@ -97,6 +97,45 @@ const getData = async (ctx, url, title) => { }; }; +const getFollowingData = async (ctx, username, url, title) => { + const response = await got({ + method: 'get', + url: url, + headers: { + Referer: url, + }, + }); + + const $ = cheerio.load(response.data); + const list = $('.person-table td.table-person').get(); + + const users = list.map(function(user) { + const $ = cheerio.load(user); + return $('a.name').attr('href'); + }); + + const usersResult = await Promise.all( + users.map(async (user) => { + const userWithoutSlashes = user.replace(/^\//, '').replace(/\/$/, ''); + + const url = `https://letterboxd.com/${userWithoutSlashes}/films/diary/by/added/`; + const data = getData(ctx, userWithoutSlashes, url, title); + return data; + }) + ); + + const usersItems = usersResult.map((result) => result.item); + const flattenedItems = [].concat.apply([], usersItems); + + return { + title: title, + link: url, + description: $('meta[name="description"]').attr('content'), + item: flattenedItems, + }; +}; + module.exports = { getData, + getFollowingData, };