diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml
index 234ae8ab7a1781..8e25b730e701c3 100644
--- a/.github/workflows/docker-release.yml
+++ b/.github/workflows/docker-release.yml
@@ -13,8 +13,6 @@ on:
- '!lib/v2/test/**'
- '!test/**'
- 'Dockerfile'
- - 'package.json'
- - 'pnpm-lock.yaml'
workflow_dispatch: ~
jobs:
diff --git a/lib/v2/gamegene/maintainer.js b/lib/v2/gamegene/maintainer.js
new file mode 100644
index 00000000000000..8c0559d270cb89
--- /dev/null
+++ b/lib/v2/gamegene/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/news': ['lone1y-51'],
+};
diff --git a/lib/v2/gamegene/news.js b/lib/v2/gamegene/news.js
new file mode 100644
index 00000000000000..a93fe643be9775
--- /dev/null
+++ b/lib/v2/gamegene/news.js
@@ -0,0 +1,50 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const url = 'https://gamegene.cn/news';
+ const { data: response } = await got({
+ method: 'get',
+ url,
+ });
+ const $ = cheerio.load(response);
+ const list = $('div.mr245')
+ .toArray()
+ .map((item) => {
+ item = $(item);
+ const aEle = item.find('a').first();
+ const href = aEle.attr('href');
+ const title = aEle.find('h3').first().text();
+ const author = item.find('a.namenode').text();
+ const category = item.find('span.r').text();
+ return {
+ title,
+ link: href,
+ author,
+ category,
+ };
+ });
+ const items = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: response } = await got({
+ method: 'get',
+ url: item.link,
+ });
+ const $ = cheerio.load(response);
+ const dateTime = $('div.meta').find('time').first().text();
+ item.pubDate = parseDate(dateTime);
+ item.description = $('div.content').first().html();
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ // 在此处输出您的 RSS
+ item: items,
+ link: url,
+ title: '游戏基因 GameGene',
+ };
+};
diff --git a/lib/v2/gamegene/radar.js b/lib/v2/gamegene/radar.js
new file mode 100644
index 00000000000000..73c2281622eba3
--- /dev/null
+++ b/lib/v2/gamegene/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'gamegene.cn': {
+ _name: '游戏基因',
+ news: [
+ {
+ title: '资讯',
+ docs: 'https://docs.rsshub.app/routes/game#you-xi-ji-yin',
+ source: ['/news'],
+ target: '/gamegene/news',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/gamegene/router.js b/lib/v2/gamegene/router.js
new file mode 100644
index 00000000000000..69a5972f6a8112
--- /dev/null
+++ b/lib/v2/gamegene/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/news', require('./news'));
+};
diff --git a/lib/v2/lsnu/jiaowc/tzgg.js b/lib/v2/lsnu/jiaowc/tzgg.js
new file mode 100644
index 00000000000000..ce0b59d005c4f9
--- /dev/null
+++ b/lib/v2/lsnu/jiaowc/tzgg.js
@@ -0,0 +1,52 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+module.exports = async (ctx) => {
+ const category = ctx.params.category;
+ const url = category ? `https://jiaowc.lsnu.edu.cn/tzgg/${category}.htm` : 'https://jiaowc.lsnu.edu.cn/tzgg.htm';
+
+ const response = await got({
+ method: 'get',
+ url,
+ });
+
+ const data = response.data;
+
+ const $ = cheerio.load(data);
+ const list = $('tr[id^="line_u5_"]').get();
+
+ const out = await Promise.all(
+ list.map(async (item) => {
+ const $ = cheerio.load(item);
+ const title = $('a').attr('title');
+ const link = `https://jiaowc.lsnu.edu.cn/${$('a').attr('href')}`;
+ const date = $('td[width="80"]').text();
+
+ const single = await ctx.cache.tryGet(link, async () => {
+ const response = await got({
+ method: 'get',
+ url: link,
+ });
+
+ const articleData = response.data;
+ const article$ = cheerio.load(articleData);
+ const description = article$('.v_news_content').html();
+
+ return {
+ title,
+ link,
+ description,
+ pubDate: new Date(date).toUTCString(),
+ };
+ });
+
+ return single;
+ })
+ );
+
+ ctx.state.data = {
+ title: '乐山师范学院教学部通知公告',
+ link: 'https://jiaowc.lsnu.edu.cn/tzgg.htm',
+ item: out,
+ };
+};
diff --git a/lib/v2/lsnu/maintainer.js b/lib/v2/lsnu/maintainer.js
new file mode 100644
index 00000000000000..42dab90d42465f
--- /dev/null
+++ b/lib/v2/lsnu/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/jiaowc/tzgg/:category?': ['nyaShine'],
+};
diff --git a/lib/v2/lsnu/radar.js b/lib/v2/lsnu/radar.js
new file mode 100644
index 00000000000000..f028fb3495d5a8
--- /dev/null
+++ b/lib/v2/lsnu/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'lsnu.edu.cn': {
+ _name: '乐山师范学院',
+ '.': [
+ {
+ title: '教学部通知公告',
+ docs: 'https://docs.rsshub.app/university.html#le-shan-shi-fan-xue-yuan',
+ source: ['/'],
+ target: '/lsnu/jiaowc/tzgg',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/lsnu/router.js b/lib/v2/lsnu/router.js
new file mode 100644
index 00000000000000..1dbd6b5620c30c
--- /dev/null
+++ b/lib/v2/lsnu/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/jiaowc/tzgg/:category?', require('./jiaowc/tzgg'));
+};
diff --git a/lib/v2/rsshub/maintainer.js b/lib/v2/rsshub/maintainer.js
index b0ffddb838814b..5ab179176c3389 100644
--- a/lib/v2/rsshub/maintainer.js
+++ b/lib/v2/rsshub/maintainer.js
@@ -3,4 +3,5 @@ module.exports = {
'/rsshub/sponsors': ['DIYgod'],
'/transform/html/:url/:routeParams': ['ttttmr'],
'/transform/json/:url/:routeParams': ['ttttmr'],
+ '/transform/sitemap/:url/:routeParams?': ['flrngel'],
};
diff --git a/lib/v2/rsshub/router.js b/lib/v2/rsshub/router.js
index 960796dbf4660e..2f90c082f82a93 100644
--- a/lib/v2/rsshub/router.js
+++ b/lib/v2/rsshub/router.js
@@ -3,4 +3,5 @@ module.exports = (router) => {
router.get('/sponsors', require('./sponsors'));
router.get('/transform/html/:url/:routeParams', require('./transform/html'));
router.get('/transform/json/:url/:routeParams', require('./transform/json'));
+ router.get('/transform/sitemap/:url/:routeParams?', require('./transform/sitemap'));
};
diff --git a/lib/v2/rsshub/transform/sitemap.js b/lib/v2/rsshub/transform/sitemap.js
new file mode 100644
index 00000000000000..9fe1fabef69b67
--- /dev/null
+++ b/lib/v2/rsshub/transform/sitemap.js
@@ -0,0 +1,52 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const config = require('@/config').value;
+
+module.exports = async (ctx) => {
+ if (!config.feature.allow_user_supply_unsafe_domain) {
+ ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
+ }
+ const { url } = ctx.params;
+ const response = await got({
+ method: 'get',
+ url,
+ });
+
+ const routeParams = new URLSearchParams(ctx.params.routeParams);
+ const $ = cheerio.load(response.data, { xmlMode: true });
+
+ const rssTitle = routeParams.get('title') ? routeParams.get('title') : $('urlset url').length && $('urlset url').first().find('loc').text() ? $('urlset url').first().find('loc').text() : 'Sitemap';
+
+ let items;
+ const urls = $('urlset url').toArray();
+ if (urls && urls.length) {
+ items = urls
+ .map((item) => {
+ try {
+ const title = $(item).find('loc').text() || '';
+ const link = $(item).find('loc').text() || '';
+ const description = $(item).find('loc').text() || '';
+ const pubDate = $(item).find('lastmod').text() || undefined;
+
+ return {
+ title,
+ link,
+ description,
+ pubDate,
+ };
+ } catch (e) {
+ return null;
+ }
+ })
+ .filter(Boolean);
+ } else {
+ items = [];
+ }
+
+ ctx.state.data = {
+ title: rssTitle,
+ link: url,
+ description: `Proxy ${url}`,
+ item: items,
+ };
+};
diff --git a/package.json b/package.json
index d212294d5b054b..fb050cdc3d9712 100644
--- a/package.json
+++ b/package.json
@@ -154,17 +154,17 @@
"@types/eslint": "8.44.2",
"@types/eslint-config-prettier": "6.11.0",
"@types/etag": "1.8.1",
- "@types/fs-extra": "11.0.1",
+ "@types/fs-extra": "11.0.2",
"@types/git-rev-sync": "2.0.0",
"@types/imapflow": "1.0.13",
"@types/jsdom": "21.1.2",
"@types/json-bigint": "1.0.1",
- "@types/koa": "2.13.8",
+ "@types/koa": "2.13.9",
"@types/koa-basic-auth": "2.0.4",
- "@types/koa-favicon": "2.0.21",
- "@types/koa-mount": "4.0.2",
+ "@types/koa-favicon": "2.0.22",
+ "@types/koa-mount": "4.0.3",
"@types/koa-static": "4.0.2",
- "@types/koa__router": "12.0.0",
+ "@types/koa__router": "12.0.1",
"@types/lint-staged": "13.2.0",
"@types/mailparser": "3.4.0",
"@types/markdown-it": "13.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3562613fe693c8..8a040320bf9ce1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -215,8 +215,8 @@ devDependencies:
specifier: 1.8.1
version: 1.8.1
'@types/fs-extra':
- specifier: 11.0.1
- version: 11.0.1
+ specifier: 11.0.2
+ version: 11.0.2
'@types/git-rev-sync':
specifier: 2.0.0
version: 2.0.0
@@ -230,23 +230,23 @@ devDependencies:
specifier: 1.0.1
version: 1.0.1
'@types/koa':
- specifier: 2.13.8
- version: 2.13.8
+ specifier: 2.13.9
+ version: 2.13.9
'@types/koa-basic-auth':
specifier: 2.0.4
version: 2.0.4
'@types/koa-favicon':
- specifier: 2.0.21
- version: 2.0.21
+ specifier: 2.0.22
+ version: 2.0.22
'@types/koa-mount':
- specifier: 4.0.2
- version: 4.0.2
+ specifier: 4.0.3
+ version: 4.0.3
'@types/koa-static':
specifier: 4.0.2
version: 4.0.2
'@types/koa__router':
- specifier: 12.0.0
- version: 12.0.0
+ specifier: 12.0.1
+ version: 12.0.1
'@types/lint-staged':
specifier: 13.2.0
version: 13.2.0
@@ -1465,8 +1465,8 @@ packages:
'@types/serve-static': 1.15.2
dev: true
- /@types/fs-extra@11.0.1:
- resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==}
+ /@types/fs-extra@11.0.2:
+ resolution: {integrity: sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==}
dependencies:
'@types/jsonfile': 6.1.1
'@types/node': 20.5.6
@@ -1551,42 +1551,42 @@ packages:
/@types/koa-basic-auth@2.0.4:
resolution: {integrity: sha512-PJKvoF5OMGlEEzUnctZDGRQVqV12xB0V4KplDJvHQDX9egh9ADFa456zGXRNnhNr43t3Fe4/VzD6ziM61uM5RQ==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
/@types/koa-compose@3.2.5:
resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
- /@types/koa-favicon@2.0.21:
- resolution: {integrity: sha512-paH1nheVhijx/VduoR/RCD/qTCiX+OI/6fHLi3mZae053Ts+gUBOrKtzl3pMTDbdEBqdLolfLje3PZbb6jW0jQ==}
+ /@types/koa-favicon@2.0.22:
+ resolution: {integrity: sha512-oyLEtX7JgJ6Fm3luqcuKi6qjTBHWMwS9dQblxkIPgtQiHEyfYm99ow6igqI440yV+k61S+ubnbmv1q0kZWyV/A==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
- /@types/koa-mount@4.0.2:
- resolution: {integrity: sha512-XnuGwV8bzw22nv2WqOs5a8wCHR2VgSnLLLuBQPzNTmhyiAvH0O6c+994rQVbMaBuwQJKefUInkvKoKuk+21uew==}
+ /@types/koa-mount@4.0.3:
+ resolution: {integrity: sha512-WXhyitlW5B6zW31cKZO+RBl38afLmO9847M8PaKmcnO5tqGJy/+XcH5N/69Nsp+vKvFXhDOY9GM5uF34HrWgrw==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
/@types/koa-send@4.1.3:
resolution: {integrity: sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
/@types/koa-static@4.0.2:
resolution: {integrity: sha512-ns/zHg+K6XVPMuohjpOlpkR1WLa4VJ9czgUP9bxkCDn0JZBtUWbD/wKDZzPGDclkQK1bpAEScufCHOy8cbfL0w==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
'@types/koa-send': 4.1.3
dev: true
- /@types/koa@2.13.8:
- resolution: {integrity: sha512-Ugmxmgk/yPRW3ptBTh9VjOLwsKWJuGbymo1uGX0qdaqqL18uJiiG1ZoV0rxCOYSaDGhvEp5Ece02Amx0iwaxQQ==}
+ /@types/koa@2.13.9:
+ resolution: {integrity: sha512-tPX3cN1dGrMn+sjCDEiQqXH2AqlPoPd594S/8zxwUm/ZbPsQXKqHPUypr2gjCPhHUc+nDJLduhh5lXI/1olnGQ==}
dependencies:
'@types/accepts': 1.3.5
'@types/content-disposition': 0.5.5
@@ -1598,10 +1598,10 @@ packages:
'@types/node': 20.5.6
dev: true
- /@types/koa__router@12.0.0:
- resolution: {integrity: sha512-S6eHyZyoWCZLNHyy8j0sMW85cPrpByCbGGU2/BO4IzGiI87aHJ92lZh4E9xfsM9DcbCT469/OIqyC0sSJXSIBQ==}
+ /@types/koa__router@12.0.1:
+ resolution: {integrity: sha512-uqV+v6pCsfLZwK+Ar6XavKSZ6Cbsgw12bCEX9L0IKHj81LTWXcrayxJWkLtez5vOMQlq+ax+lZcuCyh9CgxYGw==}
dependencies:
- '@types/koa': 2.13.8
+ '@types/koa': 2.13.9
dev: true
/@types/linkify-it@3.0.3:
diff --git a/website/docs/routes/game.md b/website/docs/routes/game.md
index 968e486ae82b50..47473658688f34 100644
--- a/website/docs/routes/game.md
+++ b/website/docs/routes/game.md
@@ -76,22 +76,22 @@ Categories
Language codes
-| Language | Code |
-| -------------- | ----- |
-| Deutsch | de-de |
-| English (US) | en-us |
-| English (EU) | en-gb |
-| Español (EU) | es-es |
-| Español (Latino) | es-mx |
-| Français | fr-fr |
-| Italiano | it-it |
-| Português (Brasil) | pt-br |
-| Polski | pl-pl |
-| Русский | ru-ru |
-| 한국어 | ko-kr |
-| ภาษาไทย | th-th |
-| 日本語 | ja-jp |
-| 繁體中文 | zh-tw |
+| Language | Code |
+| ------------------ | ----- |
+| Deutsch | de-de |
+| English (US) | en-us |
+| English (EU) | en-gb |
+| Español (EU) | es-es |
+| Español (Latino) | es-mx |
+| Français | fr-fr |
+| Italiano | it-it |
+| Português (Brasil) | pt-br |
+| Polski | pl-pl |
+| Русский | ru-ru |
+| 한국어 | ko-kr |
+| ภาษาไทย | th-th |
+| 日本語 | ja-jp |
+| 繁體中文 | zh-tw |
@@ -143,8 +143,8 @@ Region
Category
-| all | topics | notices | maintenance | updates | status | developers |
-| --- | ------ | ------- | ----------- | ------- | -------- | ---------- |
+| all | topics | notices | maintenance | updates | status | developers |
+| --- | ------ | ------- | ----------- | ------- | ------ | ---------- |
@@ -178,9 +178,9 @@ Category