diff --git a/docs/multimedia.md b/docs/multimedia.md index 852477256a0f95..44ec929c9ea7d0 100644 --- a/docs/multimedia.md +++ b/docs/multimedia.md @@ -1211,11 +1211,17 @@ JavDB 有多个备用域名,本路由默认使用永久域名 + -### 动漫 +### 剧集 + + + +::: tip 提示 +可抓取內容根据服务器所在地区而定 +::: - + ## 哔嘀影视 diff --git a/docs/other.md b/docs/other.md index 174456d1a512c0..c512f080ec838f 100644 --- a/docs/other.md +++ b/docs/other.md @@ -396,7 +396,7 @@ type 为 all 时,category 参数不支持 cost 和 free ### 发现用户 - + 分类 | 推荐 | 最热 | @@ -413,7 +413,7 @@ type 为 all 时,category 参数不支持 cost 和 free ### 用户动态 - + ## 澳門特別行政區政府各公共部門獎助貸學金服務平台 @@ -427,15 +427,15 @@ type 为 all 时,category 参数不支持 cost 和 free -## 百度搜索风云榜 +## 百度热搜 ### 榜单 - + -| 实时热点 | 今日热点 | 七日热点 | 民生热点 | 娱乐热点 | 体育热点 | -| ---- | ---- | ---- | ---- | ---- | ---- | -| 1 | 341 | 42 | 342 | 344 | 11 | +| 热搜榜 | 小说榜 | 电影榜 | 电视剧榜 | 汽车榜 | 游戏榜 | +| -------- | ----- | ----- | -------- | --- | ---- | +| realtime | novel | movie | teleplay | car | game | diff --git a/docs/social-media.md b/docs/social-media.md index 4d7443535900c7..cd7a3ea13e6a0f 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -1183,11 +1183,11 @@ YouTube 官方亦有提供频道 RSS,形如 + ### 用户个人文章 - + ## 即刻 diff --git a/lib/middleware/parameter.js b/lib/middleware/parameter.js index ac7674ab68926c..1a89e63e0ce22f 100644 --- a/lib/middleware/parameter.js +++ b/lib/middleware/parameter.js @@ -140,9 +140,11 @@ module.exports = async (ctx, next) => { item.description = $('body').html() + '' + (config.suffix || ''); - const quote = item._extra?.links?.find((e) => e.type === 'quote'); - if (quote && $('.rsshub-quote').length) { - quote.content_html = $.html($('.rsshub-quote')); + if (item._extra?.links && $('.rsshub-quote').length) { + item._extra?.links?.map((e) => { + e.content_html = $.html($('.rsshub-quote')); + return e; + }); } } return item; @@ -271,7 +273,7 @@ module.exports = async (ctx, next) => { }); item.author = author || (parsed_result ? parsed_result.author : ''); - item.description = parsed_result ? entities.decodeXML(parsed_result.content) : description; + item.description = parsed_result && parsed_result.content.length > 40 ? entities.decodeXML(parsed_result.content) : description; }); await Promise.all(tasks); } diff --git a/lib/router.js b/lib/router.js index 3343e3fc2c9def..84d59ee055921d 100644 --- a/lib/router.js +++ b/lib/router.js @@ -176,8 +176,8 @@ router.get('/geektime/news', lazyloadRouteHandler('./routes/geektime/news')); router.get('/qdaily/:type/:id', lazyloadRouteHandler('./routes/qdaily/index')); // 爱奇艺 -router.get('/iqiyi/dongman/:id', lazyloadRouteHandler('./routes/iqiyi/dongman')); -router.get('/iqiyi/user/video/:uid', lazyloadRouteHandler('./routes/iqiyi/video')); +// router.get('/iqiyi/dongman/:id', lazyloadRouteHandler('./routes/iqiyi/dongman')); +// router.get('/iqiyi/user/video/:uid', lazyloadRouteHandler('./routes/iqiyi/video')); // 南方周末 router.get('/infzm/:id', lazyloadRouteHandler('./routes/infzm/news')); @@ -950,7 +950,7 @@ router.get('/geekpark/breakingnews', lazyloadRouteHandler('./routes/geekpark/bre // 百度 router.get('/baidu/doodles', lazyloadRouteHandler('./routes/baidu/doodles')); -router.get('/baidu/topwords/:boardId?', lazyloadRouteHandler('./routes/baidu/topwords')); +// router.get('/baidu/topwords/:boardId?', lazyloadRouteHandler('./routes/baidu/topwords')); router.get('/baidu/daily', lazyloadRouteHandler('./routes/baidu/daily')); // 搜狗 @@ -1505,8 +1505,8 @@ router.get('/bupt/news', lazyloadRouteHandler('./routes/universities/bupt/news') router.get('/bupt/funbox', lazyloadRouteHandler('./routes/universities/bupt/funbox')); // VOCUS 方格子 -router.get('/vocus/publication/:id', lazyloadRouteHandler('./routes/vocus/publication')); -router.get('/vocus/user/:id', lazyloadRouteHandler('./routes/vocus/user')); +// router.get('/vocus/publication/:id', lazyloadRouteHandler('./routes/vocus/publication')); +// router.get('/vocus/user/:id', lazyloadRouteHandler('./routes/vocus/user')); // 一亩三分地 1point3acres router.get('/1point3acres/blog/:category?', lazyloadRouteHandler('./routes/1point3acres/blog')); diff --git a/lib/routes/baidu/topwords.js b/lib/routes/baidu/topwords.js deleted file mode 100644 index cebab5f6dafd73..00000000000000 --- a/lib/routes/baidu/topwords.js +++ /dev/null @@ -1,38 +0,0 @@ -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const { boardId = 1 } = ctx.params; - const response = await got({ - method: 'get', - url: `http://top.baidu.com/mobile_v2/buzz?b=${boardId}`, - }); - - const { board, topwords, descs } = response.data.result; - const items = topwords.map((item, index) => { - const title = item.keyword; - const content = descs[index].content; - const desc = content - ? content.data[0] - : { - originlink: `https://www.baidu.com/s?ie=utf-8&wd=${encodeURIComponent(title)}`, - title, - description: title, - pubDate: Date.now(), - }; - - return { - title, - description: ` - ${desc.title}
- ${desc.description || ''} - `, - link: desc.originlink, - pubDate: new Date(desc.pubDate).toUTCString(), - }; - }); - - ctx.state.data = { - title: `百度搜索风云榜-${board.boardname}`, - item: items, - }; -}; diff --git a/lib/routes/iqiyi/dongman.js b/lib/routes/iqiyi/dongman.js deleted file mode 100644 index d7f7de0fdaa094..00000000000000 --- a/lib/routes/iqiyi/dongman.js +++ /dev/null @@ -1,42 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); - -module.exports = async (ctx) => { - const id = ctx.params.id; - - const response = await got({ - method: 'get', - url: `http://www.iqiyi.com/${id}.html`, - headers: { - Host: 'www.iqiyi.com', - Referer: `http://www.iqiyi.com/${id}.html`, - }, - }); - - const data = response.data; - const $ = cheerio.load(data); - const description = $('.episodeIntro-brief').text(); - const list = $('li[data-albumlist-elem="playItem"]'); - - ctx.state.data = { - title: $('title').text().split('-')[0], - link: `http://www.iqiyi.com/${id}.html`, - description, - item: - list && - list - .map((index, item) => { - const episode = $(item).find('p.site-piclist_info_title a').text().trim(); - const describe = $(item).find('p.site-piclist_info_describe a').text(); - const title = `${episode}-${describe}`; - - return { - title, - description: ``, - link: $(item).find('.site-piclist_pic .site-piclist_pic_link').attr('href'), - }; - }) - .get() - .reverse(), - }; -}; diff --git a/lib/routes/vocus/publication.js b/lib/routes/vocus/publication.js deleted file mode 100644 index 222d0b6346af4d..00000000000000 --- a/lib/routes/vocus/publication.js +++ /dev/null @@ -1,19 +0,0 @@ -const got = require('@/utils/got'); -const { ProcessFeed } = require('./utils'); - -module.exports = async (ctx) => { - const { id } = ctx.params; - const link = `https://vocus.cc/${id}/home`; - const configs = { headers: { Referer: link } }; - - const { _id, title, abstract } = (await got.get(`https://api.sosreader.com/api/publication/${id}`, configs)).data; - const { articles } = (await got.get(`https://api.sosreader.com/api/articles?publicationId=${_id}&status=2&num=10&page=1`, configs)).data; - const items = await ProcessFeed(articles, `https://vocus.cc/${id}`, ctx.cache); - - ctx.state.data = { - title: `${title} - 方格子`, - link, - description: abstract, - item: items, - }; -}; diff --git a/lib/routes/vocus/utils.js b/lib/routes/vocus/utils.js deleted file mode 100644 index 48cdc8e685fa83..00000000000000 --- a/lib/routes/vocus/utils.js +++ /dev/null @@ -1,29 +0,0 @@ -const got = require('@/utils/got'); - -const load = async (link, configs) => ({ - description: (await got.get(link, configs)).data.article.content, -}); - -const ProcessFeed = (list, host, caches) => { - const configs = { headers: { Referer: host } }; - - return Promise.all( - list.map(async (item) => { - const itemUrl = `https://api.sosreader.com/api/article/${item._id}`; - - const single = { - title: item.title, - author: item.user.fullname, - pubDate: new Date(item.updatedAt).toUTCString(), - link: `${host}/${item._id}`, - }; - - const other = await caches.tryGet(itemUrl, () => load(itemUrl, configs)); - return Promise.resolve(Object.assign({}, single, other)); - }) - ); -}; - -module.exports = { - ProcessFeed, -}; diff --git a/lib/v2/baidu/maintainer.js b/lib/v2/baidu/maintainer.js index b63e79ea64109d..8e0f88c0fd9a37 100644 --- a/lib/v2/baidu/maintainer.js +++ b/lib/v2/baidu/maintainer.js @@ -5,4 +5,5 @@ module.exports = { '/tieba/post/:id': ['u3u'], '/tieba/post/lz/:id': ['u3u'], '/tieba/user/:uid': ['igxlin', 'nczitzk'], + '/top/:board?': ['xyqfer'], }; diff --git a/lib/v2/baidu/radar.js b/lib/v2/baidu/radar.js index 96e5ff46f4634a..9803ecbcc7722d 100644 --- a/lib/v2/baidu/radar.js +++ b/lib/v2/baidu/radar.js @@ -56,5 +56,13 @@ module.exports = { }, }, ], + top: [ + { + title: '热搜榜单', + docs: 'https://docs.rsshub.app/other.html#bai-du-re-sou', + source: ['/board'], + target: (_, url) => `/baidu/top/${new URL(url).searchParams.get('tab')}`, + }, + ], }, }; diff --git a/lib/v2/baidu/router.js b/lib/v2/baidu/router.js index 585f674c7606eb..f01ef64f9c7d75 100644 --- a/lib/v2/baidu/router.js +++ b/lib/v2/baidu/router.js @@ -5,4 +5,5 @@ module.exports = (router) => { router.get('/tieba/post/:id', require('./tieba/post')); router.get('/tieba/post/lz/:id', require('./tieba/post')); router.get('/tieba/user/:uid', require('./tieba/user')); + router.get('/top/:board?', require('./top')); }; diff --git a/lib/v2/baidu/templates/top.art b/lib/v2/baidu/templates/top.art new file mode 100644 index 00000000000000..c7f4b680bf85b8 --- /dev/null +++ b/lib/v2/baidu/templates/top.art @@ -0,0 +1,9 @@ +{{ if item.img }} +
+{{ /if }} +{{ if item.show }} + {{ each item.show s }} + {{ s }}
+ {{ /each }} +{{ /if }} +{{ item.desc }} diff --git a/lib/v2/baidu/top.js b/lib/v2/baidu/top.js new file mode 100644 index 00000000000000..2dfb374cf7fc64 --- /dev/null +++ b/lib/v2/baidu/top.js @@ -0,0 +1,34 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { art } = require('@/utils/render'); +const path = require('path'); + +module.exports = async (ctx) => { + const { board = 'realtime' } = ctx.params; + const link = `https://top.baidu.com/board?tab=${board}`; + const { data: response } = await got(link); + + const $ = cheerio.load(response); + + const { data } = JSON.parse( + $('#sanRoot') + .contents() + .filter((e) => e.nodeType === 8) + .prevObject[0].data.match(/s-data:(.*)/)[1] + ); + + const items = data.cards[0].content.map((item) => ({ + title: item.word, + description: art(path.join(__dirname, 'templates/top.art'), { + item, + }), + link: item.rawUrl, + })); + + ctx.state.data = { + title: `${data.curBoardName} - 百度热搜`, + description: $('meta[name="description"]').attr('content'), + link, + item: items, + }; +}; diff --git a/lib/v2/iqiyi/album.js b/lib/v2/iqiyi/album.js new file mode 100644 index 00000000000000..a928bd50dde8ee --- /dev/null +++ b/lib/v2/iqiyi/album.js @@ -0,0 +1,62 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +module.exports = async (ctx) => { + const { id } = ctx.params; + + const { data: response } = await got(`https://www.iq.com/album/${id}`); + + const $ = cheerio.load(response); + const nextData = JSON.parse($('#__NEXT_DATA__').text()); + const { album } = nextData.props.initialState; + + const { + data: { data: baseInfo }, + } = await got(`https://pcw-api.iqiyi.com/album/album/baseinfo/${album.videoAlbumInfo.albumId}`); + + if (Object.keys(album.cacheAlbumList).length === 0) { + throw Error(`${baseInfo.name} is not available in this server region.`); + } + + let pos = 1; + let hasMore = false; + let epgs = []; + do { + const { + data: { data }, + // eslint-disable-next-line no-await-in-loop + } = await got(`https://pcw-api.iq.com/api/v2/episodeListSource/${album.videoAlbumInfo.albumId}`, { + searchParams: { + platformId: 3, + modeCode: 'intl', + langCode: 'zh_cn', + endOrder: album.videoAlbumInfo.maxOrder, + startOrder: pos, + }, + }); + epgs = [...epgs, ...data.epg]; + pos = data.pos; + hasMore = data.hasMore; + } while (hasMore); + + const items = epgs.map((item) => ({ + title: item.name, + description: art(path.join(__dirname, 'templates/album.art'), { + item, + }), + link: `https://www.iq.com/play/${item.playLocSuffix}`, + pubDate: parseDate(item.initIssueTime), + })); + + ctx.state.data = { + title: baseInfo.name, + description: baseInfo.description, + image: album.videoAlbumInfo.albumFocus1024, + link: `https://www.iq.com/album/${album.videoAlbumInfo.albumLocSuffix}`, + item: items, + allowEmpty: true, + }; +}; diff --git a/lib/v2/iqiyi/maintainer.js b/lib/v2/iqiyi/maintainer.js new file mode 100644 index 00000000000000..c664168821add6 --- /dev/null +++ b/lib/v2/iqiyi/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/album/:id': ['TonyRL'], + '/user/video/:uid': ['talengu'], +}; diff --git a/lib/v2/iqiyi/radar.js b/lib/v2/iqiyi/radar.js new file mode 100644 index 00000000000000..6bc0f95db0cbb5 --- /dev/null +++ b/lib/v2/iqiyi/radar.js @@ -0,0 +1,24 @@ +module.exports = { + 'iq.com': { + _name: '爱奇艺', + '.': [ + { + title: '剧集', + docs: 'https://docs.rsshub.app/multimedia.html#ai-qi-yi', + source: ['/album/:id'], + target: '/iqiyi/:category/:id', + }, + ], + }, + 'iqiyi.com': { + _name: '爱奇艺', + '.': [ + { + title: '用户视频', + docs: 'https://docs.rsshub.app/multimedia.html#ai-qi-yi', + source: ['/u/:uid/*'], + target: '/iqiyi/user/video/:uid', + }, + ], + }, +}; diff --git a/lib/v2/iqiyi/router.js b/lib/v2/iqiyi/router.js new file mode 100644 index 00000000000000..126505fcbf3461 --- /dev/null +++ b/lib/v2/iqiyi/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/album/:id', require('./album')); + router.get('/user/video/:uid', require('./video')); +}; diff --git a/lib/v2/iqiyi/templates/album.art b/lib/v2/iqiyi/templates/album.art new file mode 100644 index 00000000000000..14b1e8dd5e13f8 --- /dev/null +++ b/lib/v2/iqiyi/templates/album.art @@ -0,0 +1 @@ + diff --git a/lib/routes/iqiyi/video.js b/lib/v2/iqiyi/video.js similarity index 100% rename from lib/routes/iqiyi/video.js rename to lib/v2/iqiyi/video.js diff --git a/lib/v2/mysql/release.js b/lib/v2/mysql/release.js index 7997b7daf65072..b2cffdfc18db71 100644 --- a/lib/v2/mysql/release.js +++ b/lib/v2/mysql/release.js @@ -1,15 +1,19 @@ const got = require('@/utils/got'); +const config = require('@/config').value; const cheerio = require('cheerio'); module.exports = async (ctx) => { const version = ctx.params.version ?? '8.0'; const rootUrl = 'https://dev.mysql.com'; - const currentUrl = `${rootUrl}/doc/relnotes/mysql/${version}/en`; + const currentUrl = `${rootUrl}/doc/relnotes/mysql/${version}/en/`; const response = await got({ method: 'get', url: currentUrl, + headers: { + 'user-agent': config.trueUA, + }, }); const $ = cheerio.load(response.data); @@ -22,7 +26,7 @@ module.exports = async (ctx) => { return { title: item.text(), - link: `${currentUrl}/${item.attr('href')}`, + link: `${currentUrl}${item.attr('href')}`, }; }); @@ -32,6 +36,9 @@ module.exports = async (ctx) => { const detailResponse = await got({ method: 'get', url: item.link, + headers: { + 'user-agent': config.trueUA, + }, }); const content = cheerio.load(detailResponse.data); diff --git a/lib/v2/vocus/maintainer.js b/lib/v2/vocus/maintainer.js new file mode 100644 index 00000000000000..f1c5f11ef798d0 --- /dev/null +++ b/lib/v2/vocus/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/publication/:id': ['Maecenas'], + '/user/:id': ['LogicJake'], +}; diff --git a/lib/v2/vocus/publication.js b/lib/v2/vocus/publication.js new file mode 100644 index 00000000000000..603d5b110b5f7f --- /dev/null +++ b/lib/v2/vocus/publication.js @@ -0,0 +1,42 @@ +const got = require('@/utils/got'); +const { processList, ProcessFeed, baseUrl, apiUrl } = require('./utils'); + +module.exports = async (ctx) => { + const { id } = ctx.params; + const link = `${baseUrl}/${id}/home`; + + const publicationData = await ctx.cache.tryGet(`vocus:publication:${id}`, async () => { + const { data: publicationData } = await got(`${apiUrl}/api/publication/${id}`, { + headers: { + referer: link, + }, + }); + return { + _id: publicationData._id, + title: publicationData.title, + abstract: publicationData.abstract, + }; + }); + + const { + data: { articles }, + } = await got(`${apiUrl}/api/articles`, { + headers: { + referer: link, + }, + searchParams: { + publicationId: publicationData._id, + }, + }); + + const list = processList(articles); + + const items = await ProcessFeed(list, ctx.cache.tryGet); + + ctx.state.data = { + title: `${publicationData.title} - 文章列表|方格子 vocus`, + link, + description: publicationData.abstract, + item: items, + }; +}; diff --git a/lib/v2/vocus/radar.js b/lib/v2/vocus/radar.js new file mode 100644 index 00000000000000..710871db3208a8 --- /dev/null +++ b/lib/v2/vocus/radar.js @@ -0,0 +1,19 @@ +module.exports = { + 'vocus.cc': { + _name: '方格子', + '.': [ + { + title: '出版專題', + docs: 'https://docs.rsshub.app/social-media.html#fang-ge-zi', + source: ['/:id/home', '/:id/introduce'], + target: '/vocus/publication/:id', + }, + { + title: '用户个人文章', + docs: 'https://docs.rsshub.app/social-media.html#fang-ge-zi', + source: ['/user/:id'], + target: (params) => `/vocus/user/${params.id.replace('@', '')}`, + }, + ], + }, +}; diff --git a/lib/v2/vocus/router.js b/lib/v2/vocus/router.js new file mode 100644 index 00000000000000..7767e7a3bfd28c --- /dev/null +++ b/lib/v2/vocus/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/publication/:id', require('./publication')); + router.get('/user/:id', require('./user')); +}; diff --git a/lib/v2/vocus/user.js b/lib/v2/vocus/user.js new file mode 100644 index 00000000000000..ddb82d9a58e82e --- /dev/null +++ b/lib/v2/vocus/user.js @@ -0,0 +1,43 @@ +const got = require('@/utils/got'); +const { processList, ProcessFeed, baseUrl, apiUrl } = require('./utils'); + +module.exports = async (ctx) => { + const { id } = ctx.params; + const link = `${baseUrl}/user/@${id}`; + const userData = await ctx.cache.tryGet(`vocus:user:${id}`, async () => { + const { data: userData } = await got(`${apiUrl}/api/users/${id}`, { + headers: { + referer: link, + }, + }); + return { + _id: userData._id, + fullname: userData.fullname, + avatarUrl: userData.avatarUrl, + intro: userData.intro, + }; + }); + + const { + data: { articles }, + } = await got(`${apiUrl}/api/articles`, { + headers: { + referer: link, + }, + searchParams: { + userId: userData._id, + }, + }); + + const list = processList(articles); + + const items = await ProcessFeed(list, ctx.cache.tryGet); + + ctx.state.data = { + title: `${userData.fullname}|方格子 vocus`, + link, + description: userData.intro, + image: userData.avatarUrl, + item: items, + }; +}; diff --git a/lib/v2/vocus/utils.js b/lib/v2/vocus/utils.js new file mode 100644 index 00000000000000..4821a71e8e856b --- /dev/null +++ b/lib/v2/vocus/utils.js @@ -0,0 +1,51 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +const baseUrl = 'https://vocus.cc'; +const apiUrl = 'https://api.vocus.cc'; + +const processList = (articleData) => + articleData.map((item) => ({ + title: item.title, + description: item.abstract, + pubDate: parseDate(item.createdAt), + link: `${baseUrl}/article/${item._id}`, + author: item.user.fullname, + _id: item._id, + })); + +const ProcessFeed = (list, tryGet) => + Promise.all( + list.map((item) => + tryGet(item.link, async () => { + const { + data: { article }, + } = await got(`${apiUrl}/api/article/${item._id}`, { + headers: { + referer: item.link, + }, + }); + + const $ = cheerio.load(article.content, null, false); + + $('div.draft--imgNormal').each((_, elem) => (elem.name = 'figure')); + $('.image-block-prerender').each((_, elem) => { + elem.name = 'img'; + elem.attribs.src = elem.attribs['data-src'].split('?')[0]; + }); + + item.description = $.html(); + item.category = article.tags?.map((tag) => tag.title); + + return item; + }) + ) + ); + +module.exports = { + processList, + ProcessFeed, + baseUrl, + apiUrl, +}; diff --git a/lib/v2/youtube/user.js b/lib/v2/youtube/user.js index d722dbd0819b3d..6164e4c92da564 100644 --- a/lib/v2/youtube/user.js +++ b/lib/v2/youtube/user.js @@ -1,6 +1,8 @@ const utils = require('./utils'); const config = require('@/config').value; const { parseDate } = require('@/utils/parse-date'); +const got = require('@/utils/got'); +const cheerio = require('cheerio'); module.exports = async (ctx) => { if (!config.youtube || !config.youtube.key) { @@ -9,13 +11,23 @@ module.exports = async (ctx) => { const username = ctx.params.username; const embed = !ctx.params.embed; - const playlistId = (await utils.getChannelWithUsername(username, 'contentDetails', ctx.cache)).data.items[0].contentDetails.relatedPlaylists.uploads; + let playlistId; + let channelName; + if (username.startsWith('@')) { + const link = `https://www.youtube.com/${username}`; + const response = await got(link); + const $ = cheerio.load(response.data); + const channelId = $('meta[itemprop="channelId"]').attr('content'); + channelName = $('meta[itemprop="name"]').attr('content'); + playlistId = (await utils.getChannelWithId(channelId, 'contentDetails', ctx.cache)).data.items[0].contentDetails.relatedPlaylists.uploads; + } + playlistId = playlistId || (await utils.getChannelWithUsername(username, 'contentDetails', ctx.cache)).data.items[0].contentDetails.relatedPlaylists.uploads; const data = (await utils.getPlaylistItems(playlistId, 'snippet', ctx.cache)).data.items; ctx.state.data = { - title: `${username} - YouTube`, - link: `https://www.youtube.com/user/${username}`, + title: `${channelName || username} - YouTube`, + link: username.startsWith('@') ? `https://www.youtube.com/${username}` : `https://www.youtube.com/user/${username}`, description: `YouTube user ${username}`, item: data .filter((d) => d.snippet.title !== 'Private video' && d.snippet.title !== 'Deleted video') diff --git a/package.json b/package.json index bba3ffdfced612..49d4c8a6bf61f1 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "dependencies": { "@koa/router": "12.0.0", "@postlight/parser": "2.2.3", - "@sentry/node": "7.34.0", + "@sentry/node": "7.35.0", "aes-js": "3.1.2", "art-template": "4.13.2", "bbcodejs": "0.0.4", @@ -131,7 +131,7 @@ "pidusage": "3.0.2", "plist": "3.0.6", "proxy-chain": "2.2.0", - "puppeteer": "19.6.2", + "puppeteer": "19.6.3", "puppeteer-extra": "3.3.4", "puppeteer-extra-plugin-stealth": "2.11.1", "query-string": "7.1.3", diff --git a/yarn.lock b/yarn.lock index 53537d09bcf6f9..38287f8431f126 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1546,39 +1546,39 @@ domhandler "^5.0.3" selderee "^0.10.0" -"@sentry/core@7.34.0": - version "7.34.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.34.0.tgz#bfda8d386cf7343200aa9fb7a7a26e99b839fc0c" - integrity sha512-J1oxsYZX1N0tkEcaHt/uuDqk6zOnaivyampp+EvBsUMCdemjg7rwKvawlRB0ZtBEQu3HAhi8zecm03mlpWfCDw== +"@sentry/core@7.35.0": + version "7.35.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.35.0.tgz#2d6d3ebb3224bd3a1321da3afa4a7e2900b9bb1a" + integrity sha512-j+UJaWDUyLCWOTKMrDFivy/rH5QuSvPK9TsOmYOIFctSKfp+e9Ap0cPRPXNObwim2YTpN4wpl7TqDGDANTKhuQ== dependencies: - "@sentry/types" "7.34.0" - "@sentry/utils" "7.34.0" + "@sentry/types" "7.35.0" + "@sentry/utils" "7.35.0" tslib "^1.9.3" -"@sentry/node@7.34.0": - version "7.34.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.34.0.tgz#acf51e40b1ecbd91d7bf2df55c47ae1b30c39b40" - integrity sha512-VM4XeydRdgeaNTRe8kwqYg2oNPddVyY74PlCFEFnPEN1NccycNuwiFno68kNrApeqxxLlTTmzkJy0BWo16x2Yg== +"@sentry/node@7.35.0": + version "7.35.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.35.0.tgz#5ba48d4c4271c0304f65f0a94d429bfea49e01c2" + integrity sha512-uenomjlwSk1zX4gyNV6DdJFQXgDzzdLUcTCFWoO2D3sDqCGiJO6fmRXX+kVVanYcRXfKg14ko5uelfCj6pq9BQ== dependencies: - "@sentry/core" "7.34.0" - "@sentry/types" "7.34.0" - "@sentry/utils" "7.34.0" + "@sentry/core" "7.35.0" + "@sentry/types" "7.35.0" + "@sentry/utils" "7.35.0" cookie "^0.4.1" https-proxy-agent "^5.0.0" lru_map "^0.3.3" tslib "^1.9.3" -"@sentry/types@7.34.0": - version "7.34.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.34.0.tgz#e0dc6a927dd13e4cacbca7bfee67a088885e8309" - integrity sha512-K+OeHIrl35PSYn6Zwqe4b8WWyAJQoI5NeWxHVkM7oQTGJ1YLG4BvLsR+UiUXnKdR5krE4EDtEA5jLsDlBEyPvw== +"@sentry/types@7.35.0": + version "7.35.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.35.0.tgz#08bd28b03dcecdb52928c604da9b2160702926b5" + integrity sha512-gy1PhwYvER/F80N+ZI06PjMk55xAZ4P+r3jomsMnOXQBWzx2VEEpc2fS/3B21wymxSl+mjh+5sUlk/JpxxOQvQ== -"@sentry/utils@7.34.0": - version "7.34.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.34.0.tgz#32fb6db8b352477d219ddff8200372959c68b445" - integrity sha512-VIHHXEBw0htzqxnU8A7WkXKvmsG2pZVqHlAn0H9W/yyFQtXMuP1j1i0NsjADB/3JXUKK83kTNWGzScXvp0o+Jg== +"@sentry/utils@7.35.0": + version "7.35.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.35.0.tgz#e139e2edc0a11c3b7ff429159412782e9ae0a0f3" + integrity sha512-xB/uVNXrfSwQj5fZsYOHr70ORq9qNT+9FAoUGffAQUyVjRhXG27KxsstK1Rv2yt+FBCHY06e3vE4K9B4zwSe7Q== dependencies: - "@sentry/types" "7.34.0" + "@sentry/types" "7.35.0" tslib "^1.9.3" "@sinclair/typebox@^0.25.16": @@ -11423,10 +11423,10 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" -puppeteer-core@19.6.2: - version "19.6.2" - resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.6.2.tgz#a873a3eb7a8f843c01c7e48e1ed595a54c751c8f" - integrity sha512-il7uK658MNC1FlxPABvcnv1RdpDa9CaBFHzvtEsl+9Y4tbAJKZurkegpcvWeIWcRYGiuBIVo+t+ZSh3G82CCjw== +puppeteer-core@19.6.3: + version "19.6.3" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.6.3.tgz#e3334fbb4ccb2c1ca6f4597e2f082de5a80599da" + integrity sha512-8MbhioSlkDaHkmolpQf9Z7ui7jplFfOFTnN8d5kPsCazRRTNIH6/bVxPskn0v5Gh9oqOBlknw0eHH0/OBQAxpQ== dependencies: cross-fetch "3.1.5" debug "4.3.4" @@ -11486,16 +11486,16 @@ puppeteer-extra@3.3.4: debug "^4.1.1" deepmerge "^4.2.2" -puppeteer@19.6.2: - version "19.6.2" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-19.6.2.tgz#a8630207c68d6b6047763d1754d184b8a585325d" - integrity sha512-Y5OAXXwXLfJYbl0dEFg8JKIhvCGxn+UYaBW9yra9ErmIhkVroDnYusM6oYxJCt/YIfC2pQWhvhxoZyf/E5fV6w== +puppeteer@19.6.3: + version "19.6.3" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-19.6.3.tgz#4edc7ea87f7e7e7b2885395326a6c9e5a222a10b" + integrity sha512-K03xTtGDwS6cBXX/EoqoZxglCUKcX2SLIl92fMnGMRjYpPGXoAV2yKEh3QXmXzKqfZXd8TxjjFww+tEttWv8kw== dependencies: cosmiconfig "8.0.0" https-proxy-agent "5.0.1" progress "2.0.3" proxy-from-env "1.1.0" - puppeteer-core "19.6.2" + puppeteer-core "19.6.3" q@^1.1.2: version "1.5.1"