mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-09-24 23:12:34 +08:00
* feat(route): add 秀动网 (#12489) * docs(maintainer): amend route path * update(route/showstart): remove 'keyword' param in '/event' path, add tags to xml title * refactor(route/showstart): extract service method * update(showstart/route): add '/search' path * update(route/showstart): add title for '/search' path, clean code * Update website/docs/routes/shopping.mdx * Update lib/v2/showstart/radar.js * Update lib/v2/showstart/radar.js * update(route/showstart): add request utils * update(showstart): use web api * update(showstart): add event tags * update(showstart): change pageSize * fix: add a note to crpsign calculation ---------
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
HOST: 'https://www.showstart.com',
|
||||
TITLE: '秀动网',
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
const { TITLE, HOST } = require('./const');
|
||||
const { fetchActivityList, fetchDictionary } = require('./service');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const cityCode = parseInt(ctx.params.cityCode);
|
||||
const showStyle = parseInt(ctx.params.showStyle);
|
||||
const { items } = await fetchActivityList({
|
||||
cityCode,
|
||||
showStyle,
|
||||
});
|
||||
const { cityName, showName } = await fetchDictionary(cityCode, showStyle);
|
||||
const tags = [cityName, showName].filter((item) => Boolean(item)).join(' - ');
|
||||
ctx.state.data = {
|
||||
title: `${TITLE} - ${tags}`,
|
||||
link: HOST,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
'/event/:cityCode/:showStyle?': ['lchtao26'],
|
||||
'/search/:keyword': ['lchtao26'],
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
module.exports = {
|
||||
'showstart.com': {
|
||||
_name: '秀动网',
|
||||
www: [
|
||||
{
|
||||
title: '演出更新',
|
||||
docs: 'https://docs.rsshub.app/routes/shopping#xiu-dong-wang-yan-chu-geng-xin',
|
||||
source: ['/event/list'],
|
||||
target: (_, url) => {
|
||||
const search = new URL(url).searchParams;
|
||||
const cityCode = search.get('cityCode') || 0;
|
||||
const showStyle = search.get('showStyle') || 0;
|
||||
return `/showstart/event/${cityCode}/${showStyle}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '演出搜索',
|
||||
docs: 'https://docs.rsshub.app/routes/shopping#xiu-dong-wang-yan-chu-sou-suo',
|
||||
source: ['/event/list'],
|
||||
target: (_, url) => {
|
||||
const search = new URL(url).searchParams;
|
||||
const keyword = search.get('keyword') || '';
|
||||
return `/showstart/search/${keyword}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/event/:cityCode/:showStyle?', require('./event'));
|
||||
router.get('/search/:keyword', require('./search'));
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
const { TITLE, HOST } = require('./const');
|
||||
const { fetchActivityList } = require('./service');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const keyword = ctx.params.keyword;
|
||||
const { items } = await fetchActivityList({
|
||||
keyword,
|
||||
});
|
||||
ctx.state.data = {
|
||||
title: `${TITLE} - ${keyword}`,
|
||||
link: HOST,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
const { HOST } = require('./const');
|
||||
const { getAccessToken, post } = require('./utils');
|
||||
|
||||
async function fetchActivityList(
|
||||
params = {
|
||||
pageNo: '1',
|
||||
pageSize: '30',
|
||||
cityCode: '',
|
||||
activityIds: '',
|
||||
coupon: '',
|
||||
keyword: '',
|
||||
organizerId: '',
|
||||
performerId: '',
|
||||
showStyle: '',
|
||||
showTime: '',
|
||||
showType: '',
|
||||
siteId: '',
|
||||
sortType: '',
|
||||
themeId: '',
|
||||
timeRange: '',
|
||||
tourId: '',
|
||||
type: '',
|
||||
tag: '',
|
||||
}
|
||||
) {
|
||||
const accessToken = await getAccessToken();
|
||||
const resp = await post('/web/activity/list', accessToken, params);
|
||||
return {
|
||||
items: resp.result.result.map((item) => ({
|
||||
title: item.title,
|
||||
link: `${HOST}/event/${item.id}`,
|
||||
description: `地点:${item.cityName} | ${item.siteName}`,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchDictionary(cityCode, showStyle) {
|
||||
const accessToken = await getAccessToken();
|
||||
const resp = await post('/web/activity/list/params', accessToken);
|
||||
const target = resp.result.find((item) => item.cityCode === cityCode);
|
||||
if (!target) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
cityName: target.cityName,
|
||||
showName: target.styles.find((item) => item.key === showStyle)?.showName,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchActivityList,
|
||||
fetchDictionary,
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
const got = require('@/utils/got');
|
||||
const md5 = require('@/utils/md5');
|
||||
|
||||
const uuid = (length = 20) => {
|
||||
const e = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + Date.now();
|
||||
const r = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
r.push(e.charAt(Math.floor(Math.random() * e.length)));
|
||||
}
|
||||
return r.join('');
|
||||
};
|
||||
|
||||
const cookieMap = new Map([['token', uuid(32).toLowerCase()]]);
|
||||
|
||||
const devioceInfo = {
|
||||
vendorName: '',
|
||||
deviceMode: '',
|
||||
deviceName: '',
|
||||
systemName: '',
|
||||
systemVersion: '',
|
||||
cpuMode: ' ', // Note the space
|
||||
cpuCores: '',
|
||||
cpuArch: '',
|
||||
memerySize: '',
|
||||
diskSize: '',
|
||||
network: '',
|
||||
resolution: '1920*1080',
|
||||
pixelResolution: '',
|
||||
};
|
||||
|
||||
const getAccessToken = async () => {
|
||||
const { result } = await post('/waf/gettoken');
|
||||
cookieMap.set('accessToken', result.accessToken.access_token);
|
||||
cookieMap.set('idToken', result.idToken.id_token);
|
||||
return cookieMap.get('accessToken');
|
||||
};
|
||||
|
||||
const post = async (requestPath, accessToken = md5(Date.now().toString()), payload) => {
|
||||
const traceId = uuid(32) + Date.now();
|
||||
|
||||
const { data: response } = await got.post(`https://www.showstart.com/api${requestPath}`, {
|
||||
headers: {
|
||||
cdeviceinfo: encodeURIComponent(JSON.stringify(devioceInfo)),
|
||||
cdeviceno: cookieMap.get('token'),
|
||||
cookie: [...cookieMap.entries()].map(([key, value]) => `${key}=${value}`).join('; '),
|
||||
crpsign: md5(accessToken + /* sign/cusut (empty) + idToken (empty) + userInfo.userId (empty) + */ 'web' + cookieMap.get('token') + (payload ? JSON.stringify(payload) : '') + requestPath + '999web' + traceId),
|
||||
crtraceid: traceId,
|
||||
csappid: 'web',
|
||||
cterminal: 'web',
|
||||
cusat: accessToken,
|
||||
cusid: '',
|
||||
cusit: '',
|
||||
cusname: '',
|
||||
cusut: '',
|
||||
cversion: '999',
|
||||
},
|
||||
json: payload,
|
||||
});
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
post,
|
||||
getAccessToken,
|
||||
uuid,
|
||||
};
|
||||
@@ -329,6 +329,18 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3
|
||||
|
||||
城市、分类名、子分类名,请参见[大麦网搜索页面](https://search.damai.cn/search.htm)
|
||||
|
||||
## 秀动网 {#xiu-dong-wang}
|
||||
|
||||
### 演出更新 {#xiu-dong-wang-yan-chu-geng-xin}
|
||||
|
||||
<Route author="lchtao26" example="/showstart/event/571/3" path="/showstart/event/:cityCode/:showStyle?" paramsDesc={['演出城市 (编号)', '演出风格 (编号)']}/>
|
||||
|
||||
相关路由参数可在 URL 中找到,如:`https://www.showstart.com/event/list?pageNo=1&pageSize=20&cityCode=571&showStyle=26`
|
||||
|
||||
### 演出搜索 {#xiu-dong-wang-yan-chu-sou-suo}
|
||||
|
||||
<Route author="lchtao26" example="/showstart/search/live" path="/showstart/search/:keyword" paramsDesc={['搜索关键词']}/>
|
||||
|
||||
## 多抓鱼 {#duo-zhua-yu}
|
||||
|
||||
### 搜索结果 {#duo-zhua-yu-sou-suo-jie-guo}
|
||||
|
||||
Reference in New Issue
Block a user