From ae3bccdf2a69c0ce57ca19c246d4ee44831e7a83 Mon Sep 17 00:00:00 2001 From: Tony Date: Wed, 15 Feb 2023 18:05:01 +0100 Subject: [PATCH] feat(route): 500px (#11876) * feat(route): 500px * fix: tribe image --- docs/picture.md | 10 +++ lib/v2/500px/maintainer.js | 4 + lib/v2/500px/radar.js | 19 +++++ lib/v2/500px/router.js | 4 + lib/v2/500px/templates/tribeSet.art | 6 ++ lib/v2/500px/templates/user.art | 3 + lib/v2/500px/tribeSet.js | 29 +++++++ lib/v2/500px/user.js | 32 ++++++++ lib/v2/500px/utils.js | 122 ++++++++++++++++++++++++++++ 9 files changed, 229 insertions(+) create mode 100644 lib/v2/500px/maintainer.js create mode 100644 lib/v2/500px/radar.js create mode 100644 lib/v2/500px/router.js create mode 100644 lib/v2/500px/templates/tribeSet.art create mode 100644 lib/v2/500px/templates/user.art create mode 100644 lib/v2/500px/tribeSet.js create mode 100644 lib/v2/500px/user.js create mode 100644 lib/v2/500px/utils.js diff --git a/docs/picture.md b/docs/picture.md index 49b289ed5..a5879aa72 100644 --- a/docs/picture.md +++ b/docs/picture.md @@ -64,6 +64,16 @@ pageClass: routes +## 500px 摄影社区 + +### 部落影集 + + + +### 摄影师作品 + + + ## 8KCosplay ### 最新 diff --git a/lib/v2/500px/maintainer.js b/lib/v2/500px/maintainer.js new file mode 100644 index 000000000..e2aa1857b --- /dev/null +++ b/lib/v2/500px/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/tribe/set/:id': ['TonyRL'], + '/user/works/:id': ['TonyRL'], +}; diff --git a/lib/v2/500px/radar.js b/lib/v2/500px/radar.js new file mode 100644 index 000000000..1f2202b76 --- /dev/null +++ b/lib/v2/500px/radar.js @@ -0,0 +1,19 @@ +module.exports = { + '500px.com.cn': { + _name: '500px 摄影社区', + '.': [ + { + title: '部落影集', + docs: 'https://docs.rsshub.app/picture.html#_500px-she-ying-she-qu', + source: ['/page/tribe/detail'], + target: (_, url) => `/500px/tribe/set/${url.searchParams.get('tribeId')}`, + }, + { + title: '摄影师作品', + docs: 'https://docs.rsshub.app/picture.html#_500px-she-ying-she-qu', + source: ['/:id', '/community/user-details/:id', '/community/user-details/:id/*'], + target: '/500px/user/works/:id', + }, + ], + }, +}; diff --git a/lib/v2/500px/router.js b/lib/v2/500px/router.js new file mode 100644 index 000000000..bb34cfef1 --- /dev/null +++ b/lib/v2/500px/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/tribe/set/:id', require('./tribeSet')); + router.get('/user/works/:id', require('./user')); +}; diff --git a/lib/v2/500px/templates/tribeSet.art b/lib/v2/500px/templates/tribeSet.art new file mode 100644 index 000000000..c9d7688fb --- /dev/null +++ b/lib/v2/500px/templates/tribeSet.art @@ -0,0 +1,6 @@ +{{ if item.description }}

{{ item.description }}

{{ /if }} +{{ if item.photos }} + {{ each item.photos p }} + + {{ /each }} +{{ /if }} diff --git a/lib/v2/500px/templates/user.art b/lib/v2/500px/templates/user.art new file mode 100644 index 000000000..0499ef506 --- /dev/null +++ b/lib/v2/500px/templates/user.art @@ -0,0 +1,3 @@ +{{ if item.url }} + +{{ /if }} diff --git a/lib/v2/500px/tribeSet.js b/lib/v2/500px/tribeSet.js new file mode 100644 index 000000000..aba1ace53 --- /dev/null +++ b/lib/v2/500px/tribeSet.js @@ -0,0 +1,29 @@ +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const { baseUrl, getTribeDetail, getTribeSets } = require('./utils'); + +module.exports = async (ctx) => { + const { id } = ctx.params; + const limit = parseInt(ctx.query.limit) || 100; + + const { tribe } = await getTribeDetail(id, ctx.cache.tryGet); + const tribeSets = await getTribeSets(id, limit, ctx.cache.tryGet); + + const items = tribeSets.map((item) => ({ + title: item.title, + description: art(path.join(__dirname, 'templates/tribeSet.art'), { item }), + author: item.uploaderInfo.nickName, + pubDate: parseDate(item.createdTime, 'x'), + link: `${baseUrl}/community/set/${item.id}/details`, + })); + + ctx.state.data = { + title: tribe.name, + description: `${tribe.watchword} - ${tribe.introduce}`, + link: `${baseUrl}/page/tribe/detail?tribeId=${id}&pagev=set`, + image: tribe.avatar.a1, + item: items, + }; +}; diff --git a/lib/v2/500px/user.js b/lib/v2/500px/user.js new file mode 100644 index 000000000..c20c0f705 --- /dev/null +++ b/lib/v2/500px/user.js @@ -0,0 +1,32 @@ +const { art } = require('@/utils/render'); +const { parseDate } = require('@/utils/parse-date'); +const path = require('path'); +const { baseUrl, getUserInfoFromUsername, getUserInfoFromId, getUserWorks } = require('./utils'); + +module.exports = async (ctx) => { + let { id } = ctx.params; + const limit = parseInt(ctx.query.limit) || 100; + + if (id.length !== 33) { + id = (await getUserInfoFromUsername(id, ctx.cache.tryGet)).id; + } + + const userInfo = await getUserInfoFromId(id, ctx.cache.tryGet); + const userWorks = await getUserWorks(id, limit, ctx.cache.tryGet); + + const items = userWorks.map((item) => ({ + title: item.title || '无题', + description: art(path.join(__dirname, 'templates/user.art'), { item }), + author: item.uploaderInfo.nickName, + pubDate: parseDate(item.createdTime, 'x'), + link: `${baseUrl}/community/photo-details/${item.id}`, + })); + + ctx.state.data = { + title: userInfo.nickName, + description: userInfo.about, + image: userInfo.avatar.a1, + link: `${baseUrl}/${id}`, + item: items, + }; +}; diff --git a/lib/v2/500px/utils.js b/lib/v2/500px/utils.js new file mode 100644 index 000000000..91bb641f6 --- /dev/null +++ b/lib/v2/500px/utils.js @@ -0,0 +1,122 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const config = require('@/config').value; + +const baseUrl = 'https://500px.com.cn'; + +/* +ty_rum.server = { + id: 'Fm3hXcTiLT8', + ignore_err: true, + beacon: 'beacon.tingyun.com', + beacon_err: 'beacon-err.tingyun.com', + key: 'M1laN7-zRM0', + trace_threshold: 7000, + custom_urls: [], + sr: 1.0, +}; +v && v.id && this._ty_rum && y(this._ty_rum.url) && (this._ty_rum.r = (new Date).getTime() % 1e8, +this.setRequestHeader && this.setRequestHeader("X-Tingyun-Id", v.id + ";r=" + this._ty_rum.r)) +*/ +const headers = { + // {"anonymousId":"","latitude":null,"longitude":null,"manufacturer":"","province":"","area":"","city":""} + 'x-500px-client-info': 'eyJhbm9ueW1vdXNJZCI6IiIsImxhdGl0dWRlIjpudWxsLCJsb25naXR1ZGUiOm51bGwsIm1hbnVmYWN0dXJlciI6IiIsInByb3ZpbmNlIjoiIiwiYXJlYSI6IiIsImNpdHkiOiIifQ==', + 'X-Tingyun-Id': `Fm3hXcTiLT8;r=${new Date().getTime() % 1e8}`, +}; + +const getUserInfoFromUsername = (username, tryGet) => + tryGet(`500px:user:${username}`, async () => { + const { data } = await got(`${baseUrl}/${username}`); + const $ = cheerio.load(data); + return JSON.parse( + $('script[type="text/javascript"]') + .text() + .match(/var cur_user = new Object\((.*?)\);/)[1] + ); + }); + +const getUserInfoFromId = (id, tryGet) => + tryGet(`500px:user:indexInfo:${id}`, async () => { + const { data } = await got(`${baseUrl}/community/v2/user/indexInfo`, { + headers: { + ...headers, + }, + searchParams: { + queriedUserId: id, + }, + }); + return data.data; + }); + +const getUserWorks = (id, limit, tryGet) => + tryGet( + `500px:user:profile:${id}`, + async () => { + const { data } = await got(`${baseUrl}/community/v2/user/profile`, { + headers: { + ...headers, + }, + searchParams: { + resourceType: '0,2,4', + imgsize: 'p1,p2,p3,p4', + queriedUserId: id, + startTime: '', + page: 1, + size: limit, + type: 'json', + }, + }); + return data.data; + }, + config.cache.routeExpire, + false + ); + +const getTribeDetail = (id, tryGet) => + tryGet( + `500px:tribeDetail:${id}`, + async () => { + const { data } = await got(`${baseUrl}/community/tribe/tribeDetail`, { + headers: { + ...headers, + }, + searchParams: { + tribeId: id, + }, + }); + return data.data; + }, + config.cache.routeExpire, + false + ); + +const getTribeSets = (id, limit, tryGet) => + tryGet( + `500px:tribeSets:${id}`, + async () => { + const { data } = await got(`${baseUrl}/community/tribe/getTribeSetsV2`, { + headers: { + ...headers, + }, + searchParams: { + tribeId: id, + privacy: 1, + page: 1, + size: limit, + type: 'json', + }, + }); + return data.data; + }, + config.cache.routeExpire, + false + ); + +module.exports = { + baseUrl, + getUserInfoFromUsername, + getUserInfoFromId, + getUserWorks, + getTribeDetail, + getTribeSets, +};