diff --git a/lib/routes/picuki/profile.js b/lib/routes/picuki/profile.js index 58ec1921bd..0e91e10d8b 100644 --- a/lib/routes/picuki/profile.js +++ b/lib/routes/picuki/profile.js @@ -4,7 +4,7 @@ const chrono = require('chrono-node'); module.exports = async (ctx) => { const id = ctx.params.id; - const displayVideo = ctx.params.displayVideo ? true : false; + const displayVideo = !!ctx.params.displayVideo; const url = `https://www.picuki.com/profile/${id}`; @@ -17,27 +17,66 @@ module.exports = async (ctx) => { const list = $('ul.box-photos [data-s="media"]').get(); - async function getVideo(url) { + async function getMedia(url) { const response = await got.get(url); const $ = cheerio.load(response.data); - return $('.single-photo').html(); + // Instagram 允许最多 10 条图片/视频任意混合于一条 post,picuki 在所有情况下都会将它(们)置于 .single-photo 内 + const media_items = $('.single-photo img,video').get(); + let html = ''; + media_items.forEach((item) => { + item = $(item); + html += item.toString(); // 可能是视频,也可能是图片,格式都比较友好,这里直接添加 + }); + return html; + } + + function deVideo(media) { + const $ = cheerio.load(media); + const media_list = $('img,video').get(); + let media_deVideo = ''; + media_list.forEach((medium) => { + medium = $(medium); + const poster = medium.attr('poster'); + // 如果有 poster 属性,表明它是视频,将它替换为它的 poster;如果不是,就原样返回 + media_deVideo += poster ? `video poster` : medium.toString(); + }); + return media_deVideo; } const items = await Promise.all( list.map(async (post) => { post = $(post); - const isVideo = post.find('.video-icon').length !== 0 && displayVideo; - const post_image = post.find('.post-image').attr('src'); - const post_description = post.find('.photo-description').text().trim(); + const post_link = post.find('.photo > a').attr('href'); - const post_time = post.find('.time'); - return { - title: post_description || 'Untitled', - author: `@${id}`, - description: (isVideo ? await getVideo(post_link) : ``) + (post_description.length > 100 ? `

${post_description}

` : ''), - link: post_link, - pubDate: post_time ? chrono.parseDate(post_time.text()) : new Date(), - }; + const cache = await ctx.cache.get(post_link); + + let cache_d; + if (cache) { + cache_d = JSON.parse(cache); + } else { + const post_description = post.find('.photo-description').text().trim(); + const post_time = post.find('.time'); + const media_displayVideo = await getMedia(post_link); + const media = deVideo(media_displayVideo); + + cache_d = { + title: post_description || 'Untitled', + author: `@${id}`, + media_prefix: media, + media_displayVideo_prefix: media_displayVideo, + description_body: post_description.length > 100 ? `

${post_description}

` : '', + link: post_link, + pubDate: post_time ? chrono.parseDate(post_time.text()) : new Date(), + }; + + ctx.cache.set(post_link, JSON.stringify(cache_d)); + } + + cache_d.description = (displayVideo ? cache_d.media_displayVideo_prefix : cache_d.media_prefix) + cache_d.description_body; + delete cache_d.media_prefix; + delete cache_d.media_displayVideo_prefix; + delete cache_d.description_body; + return cache_d; }) );