From 3c8755810c9848b909ed8d0d6bdd1de18da667d2 Mon Sep 17 00:00:00 2001
From: lchtao26 <52860060+lchtao26@users.noreply.github.com>
Date: Fri, 24 Nov 2023 02:04:06 +0800
Subject: [PATCH] =?UTF-8?q?feat(route):=20add=20=E7=A7=80=E5=8A=A8?=
=?UTF-8?q?=E7=BD=91=20(#12489)=20(#13866)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 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
---------
---
lib/v2/showstart/const.js | 4 ++
lib/v2/showstart/event.js | 18 +++++++++
lib/v2/showstart/maintainer.js | 4 ++
lib/v2/showstart/radar.js | 28 +++++++++++++
lib/v2/showstart/router.js | 4 ++
lib/v2/showstart/search.js | 14 +++++++
lib/v2/showstart/service.js | 53 +++++++++++++++++++++++++
lib/v2/showstart/utils.js | 67 ++++++++++++++++++++++++++++++++
website/docs/routes/shopping.mdx | 12 ++++++
9 files changed, 204 insertions(+)
create mode 100644 lib/v2/showstart/const.js
create mode 100644 lib/v2/showstart/event.js
create mode 100644 lib/v2/showstart/maintainer.js
create mode 100644 lib/v2/showstart/radar.js
create mode 100644 lib/v2/showstart/router.js
create mode 100644 lib/v2/showstart/search.js
create mode 100644 lib/v2/showstart/service.js
create mode 100644 lib/v2/showstart/utils.js
diff --git a/lib/v2/showstart/const.js b/lib/v2/showstart/const.js
new file mode 100644
index 0000000000..f7880faed0
--- /dev/null
+++ b/lib/v2/showstart/const.js
@@ -0,0 +1,4 @@
+module.exports = {
+ HOST: 'https://www.showstart.com',
+ TITLE: '秀动网',
+};
diff --git a/lib/v2/showstart/event.js b/lib/v2/showstart/event.js
new file mode 100644
index 0000000000..38e6aafc15
--- /dev/null
+++ b/lib/v2/showstart/event.js
@@ -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,
+ };
+};
diff --git a/lib/v2/showstart/maintainer.js b/lib/v2/showstart/maintainer.js
new file mode 100644
index 0000000000..1eea6511d8
--- /dev/null
+++ b/lib/v2/showstart/maintainer.js
@@ -0,0 +1,4 @@
+module.exports = {
+ '/event/:cityCode/:showStyle?': ['lchtao26'],
+ '/search/:keyword': ['lchtao26'],
+};
diff --git a/lib/v2/showstart/radar.js b/lib/v2/showstart/radar.js
new file mode 100644
index 0000000000..5554847998
--- /dev/null
+++ b/lib/v2/showstart/radar.js
@@ -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}`;
+ },
+ },
+ ],
+ },
+};
diff --git a/lib/v2/showstart/router.js b/lib/v2/showstart/router.js
new file mode 100644
index 0000000000..e8588a62ac
--- /dev/null
+++ b/lib/v2/showstart/router.js
@@ -0,0 +1,4 @@
+module.exports = (router) => {
+ router.get('/event/:cityCode/:showStyle?', require('./event'));
+ router.get('/search/:keyword', require('./search'));
+};
diff --git a/lib/v2/showstart/search.js b/lib/v2/showstart/search.js
new file mode 100644
index 0000000000..3a9bddb58f
--- /dev/null
+++ b/lib/v2/showstart/search.js
@@ -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,
+ };
+};
diff --git a/lib/v2/showstart/service.js b/lib/v2/showstart/service.js
new file mode 100644
index 0000000000..925918ab27
--- /dev/null
+++ b/lib/v2/showstart/service.js
@@ -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,
+};
diff --git a/lib/v2/showstart/utils.js b/lib/v2/showstart/utils.js
new file mode 100644
index 0000000000..7a8b9a5513
--- /dev/null
+++ b/lib/v2/showstart/utils.js
@@ -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,
+};
diff --git a/website/docs/routes/shopping.mdx b/website/docs/routes/shopping.mdx
index a3672d1b62..76836f9429 100644
--- a/website/docs/routes/shopping.mdx
+++ b/website/docs/routes/shopping.mdx
@@ -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}
+
+
+
+相关路由参数可在 URL 中找到,如:`https://www.showstart.com/event/list?pageNo=1&pageSize=20&cityCode=571&showStyle=26`
+
+### 演出搜索 {#xiu-dong-wang-yan-chu-sou-suo}
+
+
+
## 多抓鱼 {#duo-zhua-yu}
### 搜索结果 {#duo-zhua-yu-sou-suo-jie-guo}