diff --git a/docs/social-media.md b/docs/social-media.md index 5fd4d21c03..f5d4f9a8b0 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -1146,6 +1146,16 @@ YouTube 官方亦有提供频道 RSS,形如 +## 全民 K 歌 + +### 用户作品列表 + + + +### 用户作品评论动态 + + + ## 数字尾巴 ### 首页 diff --git a/lib/v2/qq/kg/cache.js b/lib/v2/qq/kg/cache.js new file mode 100644 index 0000000000..30d83a6795 --- /dev/null +++ b/lib/v2/qq/kg/cache.js @@ -0,0 +1,28 @@ +const got = require('@/utils/got'); +const { JSDOM } = require('jsdom'); + +module.exports = { + getPlayInfo: async (ctx, shareId, ksong_mid = '') => { + const link = `https://node.kg.qq.com/play?s=${shareId}`; + const cache_key = ksong_mid ? `ksong:${ksong_mid}` : link; + const data = await ctx.cache.tryGet(cache_key, async () => { + const response = await got(link); + const { window } = new JSDOM(response.data, { + runScripts: 'dangerously', + }); + const data = window.__DATA__; + const name = data.detail.song_name; + const description = data.detail.content; + const author = data.detail.nick; + const itunes_item_image = data.detail.cover; + + const enclosure_url = data.detail.playurl; + ksong_mid = ksong_mid ? ksong_mid : data.detail.ksong_mid; + const ctime = data.detail.ctime; + const comments = data.detail.comments; + + return { name, link, description, author, enclosure_url, ksong_mid, ctime, itunes_item_image, comments }; + }); + return data; + }, +}; diff --git a/lib/v2/qq/kg/reply.js b/lib/v2/qq/kg/reply.js new file mode 100644 index 0000000000..35bffe0068 --- /dev/null +++ b/lib/v2/qq/kg/reply.js @@ -0,0 +1,21 @@ +const cache = require('./cache'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const playId = ctx.params.playId; + const url = `https://node.kg.qq.com/play?s=${playId}`; + const play_item = await cache.getPlayInfo(ctx, playId, ''); + + ctx.state.data = { + title: `${play_item.name} - ${play_item.author} 的评论`, + link: url, + image: play_item.itunes_item_image, + allowEmpty: true, + item: play_item.comments.map((item) => ({ + title: `${item.nick}:${item.content}`, + pubDate: parseDate(item.ctime * 1000), + link: url, + guid: `ksong:${play_item.ksong_mid}:${item.comment_id}`, + })), + }; +}; diff --git a/lib/v2/qq/kg/user.js b/lib/v2/qq/kg/user.js new file mode 100644 index 0000000000..8194507571 --- /dev/null +++ b/lib/v2/qq/kg/user.js @@ -0,0 +1,50 @@ +const got = require('@/utils/got'); +const { JSDOM } = require('jsdom'); +const cache = require('./cache'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const userId = ctx.params.userId; + const url = `https://node.kg.qq.com/personal?uid=${userId}`; + const response = await got(url); + + const { window } = new JSDOM(response.data, { + runScripts: 'dangerously', + }); + const data = window.__DATA__; + const author = data.data.nickname; + const authorimg = data.data.head_img_url; + const ugcList = data.data.ugclist; + + const items = await Promise.all( + ugcList.map(async (item) => { + const link = `https://node.kg.qq.com/play?s=${item.shareid}`; + const item_info = await cache.getPlayInfo(ctx, item.shareid, item.ksong_mid); + + const single = { + title: item.title || '', + description: item_info.description, + link, + guid: `ksong:${item.ksong_mid}`, + author, + pubDate: parseDate(item_info.ctime * 1000) || parseDate(item.ctime, 'X'), + itunes_item_image: item_info.itunes_item_image || item.avatar, + enclosure_url: item_info.enclosure_url, + enclosure_type: 'audio/x-m4a', + }; + + return single; + }) + ); + + ctx.state.data = { + title: `${author} - 全民K歌`, + link: url, + description: data.share.content, + allowEmpty: true, + item: items, + image: authorimg, + itunes_author: author, + itunes_category: '全民K歌', + }; +}; diff --git a/lib/v2/qq/maintainer.js b/lib/v2/qq/maintainer.js index 2161661481..5c76fc5d2b 100644 --- a/lib/v2/qq/maintainer.js +++ b/lib/v2/qq/maintainer.js @@ -1,5 +1,7 @@ module.exports = { '/ac/comic/:id': ['nczitzk'], '/ac/rank/:type?/:time?': ['nczitzk'], + '/kg/:userId': ['zhangxiang012'], + '/kg/reply/:playId': ['zhangxiang012'], '/live/:id': ['nczitzk'], }; diff --git a/lib/v2/qq/radar.js b/lib/v2/qq/radar.js index 818cb96395..14f4d289b2 100644 --- a/lib/v2/qq/radar.js +++ b/lib/v2/qq/radar.js @@ -23,5 +23,19 @@ module.exports = { target: '/qq/live/:id', }, ], + 'node.kg': [ + { + title: '用户作品列表 - 全民 K 歌', + docs: 'https://docs.rsshub.app/live.html#qi-e-zhi-bo-zhi-bo-jian-ti-xing', + source: ['/personal'], + target: (_params, url) => `/qq/kg/${new URL(url).searchParams.get('uid')}`, + }, + { + title: '用户作品评论动态 - 全民 K 歌', + docs: 'https://docs.rsshub.app/live.html#qi-e-zhi-bo-zhi-bo-jian-ti-xing', + source: ['/play'], + target: (_params, url) => `/qq/kg/${new URL(url).searchParams.get('s')}`, + }, + ], }, }; diff --git a/lib/v2/qq/router.js b/lib/v2/qq/router.js index 1ed1c24a80..cdcf119fad 100644 --- a/lib/v2/qq/router.js +++ b/lib/v2/qq/router.js @@ -1,5 +1,7 @@ module.exports = function (router) { router.get('/ac/comic/:id?', require('./ac/comic')); router.get('/ac/rank/:type?/:time?', require('./ac/rank')); + router.get('/kg/:userId', require('./kg/user')); + router.get('/kg/reply/:playId', require('./kg/reply')); router.get('/live/:id', require('./live')); };