rsshub 1.0.0-master.fc5a2f6 → 1.0.0-master.fc648b5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/config.js +4 -0
- package/lib/middleware/anti-hotlink.js +90 -22
- package/lib/middleware/parameter.js +65 -32
- package/lib/middleware/templates/iframe.art +14 -0
- package/lib/radar-rules.js +0 -92
- package/lib/router.js +22 -22
- package/lib/routes/agefans/update.js +1 -1
- package/lib/routes/novel/biqugeinfo.js +2 -2
- package/lib/routes/universities/uestc/sice.js +12 -33
- package/lib/routes/weibo/user.js +10 -19
- package/lib/v2/19lou/index.js +74 -0
- package/lib/v2/19lou/maintainer.js +3 -0
- package/lib/v2/19lou/radar.js +29 -0
- package/lib/v2/19lou/router.js +3 -0
- package/lib/v2/36kr/router.js +1 -1
- package/lib/v2/36kr/user.js +47 -22
- package/lib/v2/acfun/article.js +100 -0
- package/lib/{routes → v2}/acfun/bangumi.js +7 -7
- package/lib/v2/acfun/maintainer.js +5 -0
- package/lib/v2/acfun/radar.js +25 -0
- package/lib/v2/acfun/router.js +5 -0
- package/lib/v2/acfun/video.js +45 -0
- package/lib/v2/agora0/index.js +54 -0
- package/lib/v2/agora0/maintainer.js +3 -0
- package/lib/v2/agora0/radar.js +13 -0
- package/lib/v2/agora0/router.js +3 -0
- package/lib/v2/apnews/maintainer.js +3 -0
- package/lib/v2/apnews/radar.js +13 -0
- package/lib/v2/apnews/router.js +3 -0
- package/lib/v2/apnews/templates/description.art +14 -0
- package/lib/v2/apnews/topics.js +44 -0
- package/lib/v2/appleinsider/index.js +59 -0
- package/lib/v2/appleinsider/maintainer.js +3 -0
- package/lib/v2/appleinsider/radar.js +13 -0
- package/lib/v2/appleinsider/router.js +3 -0
- package/lib/v2/cbnweek/index.js +46 -0
- package/lib/v2/cbnweek/maintainer.js +3 -0
- package/lib/v2/cbnweek/radar.js +13 -0
- package/lib/v2/cbnweek/router.js +3 -0
- package/lib/v2/ccac/news.js +12 -3
- package/lib/v2/cde/index.js +2 -2
- package/lib/v2/cde/maintainer.js +1 -0
- package/lib/v2/cde/radar.js +22 -4
- package/lib/v2/cde/router.js +1 -0
- package/lib/v2/cde/templates/xxgk/breakthroughCure.art +18 -0
- package/lib/v2/cde/templates/xxgk/cliniCal.art +16 -0
- package/lib/v2/cde/templates/xxgk/priorityApproval.art +18 -0
- package/lib/v2/cde/utils.js +2 -2
- package/lib/v2/cde/xxgk.js +73 -0
- package/lib/v2/chinadegrees/maintainer.js +3 -0
- package/lib/v2/chinadegrees/province.js +66 -0
- package/lib/v2/chinadegrees/radar.js +13 -0
- package/lib/v2/chinadegrees/router.js +3 -0
- package/lib/v2/chinadegrees/templates/description.art +4 -0
- package/lib/v2/cnjxol/index.js +94 -0
- package/lib/v2/cnjxol/maintainer.js +4 -0
- package/lib/v2/cnjxol/radar.js +19 -0
- package/lib/v2/cnjxol/router.js +3 -0
- package/lib/v2/cnjxol/templates/description.art +2 -0
- package/lib/v2/cscse/maintainer.js +3 -0
- package/lib/v2/cscse/radar.js +13 -0
- package/lib/v2/cscse/router.js +3 -0
- package/lib/v2/cscse/tzgg.js +54 -0
- package/lib/v2/dgjyw/index.js +67 -0
- package/lib/v2/dgjyw/maintainer.js +3 -0
- package/lib/v2/dgjyw/radar.js +13 -0
- package/lib/v2/dgjyw/router.js +3 -0
- package/lib/v2/domp4/detail.js +67 -0
- package/lib/v2/domp4/latest.js +31 -0
- package/lib/v2/domp4/maintainer.js +4 -0
- package/lib/v2/domp4/radar.js +25 -0
- package/lib/v2/domp4/router.js +4 -0
- package/lib/v2/domp4/utils.js +72 -0
- package/lib/v2/douyin/hashtag.js +5 -43
- package/lib/v2/douyin/live.js +68 -0
- package/lib/v2/douyin/maintainer.js +2 -0
- package/lib/v2/douyin/radar.js +8 -0
- package/lib/v2/douyin/router.js +1 -0
- package/lib/v2/douyin/user.js +5 -43
- package/lib/v2/douyin/utils.js +50 -0
- package/lib/v2/economist/full.js +6 -4
- package/lib/v2/elsevier/issue.js +62 -0
- package/lib/v2/elsevier/journal.js +72 -0
- package/lib/v2/elsevier/maintainer.js +2 -2
- package/lib/v2/elsevier/radar.js +5 -5
- package/lib/v2/elsevier/router.js +4 -2
- package/lib/v2/elsevier/templates/description.art +5 -5
- package/lib/v2/gov/beijing/jw/tzgg.js +58 -0
- package/lib/v2/gov/customs/list.js +21 -17
- package/lib/v2/gov/customs/utils.js +9 -5
- package/lib/v2/gov/maintainer.js +3 -0
- package/lib/v2/gov/nmpa/generic.js +76 -0
- package/lib/v2/gov/pbc/goutongjiaoliu.js +20 -15
- package/lib/v2/gov/pbc/tradeAnnouncement.js +18 -14
- package/lib/v2/gov/radar.js +57 -27
- package/lib/v2/gov/router.js +3 -0
- package/lib/v2/gov/xuzhou/hrss.js +54 -0
- package/lib/v2/hackertalk/index.js +23 -0
- package/lib/v2/hackertalk/maintainer.js +3 -0
- package/lib/v2/hackertalk/radar.js +13 -0
- package/lib/v2/hackertalk/router.js +3 -0
- package/lib/v2/hashnode/blog.js +62 -0
- package/lib/v2/hashnode/maintainer.js +3 -0
- package/lib/v2/hashnode/radar.js +13 -0
- package/lib/v2/hashnode/router.js +3 -0
- package/lib/v2/hashnode/templates/description.art +2 -0
- package/lib/v2/hdu/cs/{index.js → notice.js} +1 -4
- package/lib/v2/hdu/cs/pg.js +54 -0
- package/lib/v2/hdu/maintainer.js +1 -0
- package/lib/v2/hdu/radar.js +6 -0
- package/lib/v2/hdu/router.js +2 -1
- package/lib/v2/heu/gx/list.js +2 -2
- package/lib/v2/heu/job/list.js +2 -2
- package/lib/v2/heu/uae/list.js +2 -2
- package/lib/v2/heu/yjsy/list.js +2 -2
- package/lib/v2/hk01/channel.js +40 -0
- package/lib/{routes → v2}/hk01/hot.js +2 -1
- package/lib/v2/hk01/issue.js +41 -0
- package/lib/v2/hk01/maintainer.js +7 -0
- package/lib/v2/hk01/radar.js +37 -0
- package/lib/v2/hk01/router.js +7 -0
- package/lib/{routes → v2}/hk01/tag.js +2 -1
- package/lib/{routes → v2}/hk01/zone.js +3 -2
- package/lib/v2/hotukdeals/index.js +1 -1
- package/lib/v2/ieee/journal.js +78 -0
- package/lib/v2/ieee/maintainer.js +2 -2
- package/lib/v2/ieee/radar.js +4 -4
- package/lib/v2/ieee/{latestdate.js → recent.js} +34 -42
- package/lib/v2/ieee/router.js +4 -2
- package/lib/v2/ieee/templates/description.art +5 -5
- package/lib/v2/ielts/index.js +7 -2
- package/lib/v2/keep/maintainer.js +3 -0
- package/lib/v2/keep/radar.js +13 -0
- package/lib/v2/keep/router.js +3 -0
- package/lib/v2/keep/templates/user.art +16 -0
- package/lib/{routes → v2}/keep/user.js +14 -4
- package/lib/v2/mdpi/journal.js +65 -0
- package/lib/v2/mdpi/maintainer.js +3 -0
- package/lib/v2/mdpi/radar.js +13 -0
- package/lib/v2/mdpi/router.js +3 -0
- package/lib/v2/mdpi/templates/description.art +12 -0
- package/lib/v2/mindmeister/example.js +44 -0
- package/lib/v2/mindmeister/maintainer.js +3 -0
- package/lib/v2/mindmeister/radar.js +13 -0
- package/lib/v2/mindmeister/router.js +3 -0
- package/lib/v2/mindmeister/templates/image.art +1 -0
- package/lib/v2/mirror/index.js +34 -0
- package/lib/v2/mirror/maintainer.js +3 -0
- package/lib/v2/mirror/radar.js +17 -0
- package/lib/v2/mirror/router.js +3 -0
- package/lib/v2/nbd/radar.js +2 -2
- package/lib/v2/ncwu/maintainer.js +3 -0
- package/lib/v2/ncwu/notice.js +27 -0
- package/lib/v2/ncwu/radar.js +13 -0
- package/lib/v2/ncwu/router.js +3 -0
- package/lib/v2/netease/exclusive.js +148 -0
- package/lib/v2/netease/maintainer.js +1 -0
- package/lib/v2/netease/radar.js +8 -0
- package/lib/v2/netease/router.js +1 -0
- package/lib/v2/netease/templates/exclusive.art +11 -0
- package/lib/v2/nju/rczp.js +34 -24
- package/lib/v2/njust/utils.js +4 -0
- package/lib/v2/nuaa/utils/pypasswaf.js +4 -5
- package/lib/v2/nyaa/maintainer.js +4 -0
- package/lib/v2/nyaa/radar.js +32 -0
- package/lib/v2/nyaa/router.js +4 -0
- package/lib/{routes → v2}/nyaa/search.js +4 -2
- package/lib/v2/nytimes/daily_briefing_chinese.js +47 -41
- package/lib/v2/nytimes/index.js +3 -3
- package/lib/v2/nytimes/maintainer.js +1 -1
- package/lib/v2/nytimes/templates/image.art +3 -0
- package/lib/v2/nytimes/utils.js +7 -1
- package/lib/v2/oceanengine/arithmeticIndex.js +145 -0
- package/lib/v2/oceanengine/maintainer.js +3 -0
- package/lib/v2/oceanengine/radar.js +13 -0
- package/lib/v2/oceanengine/router.js +3 -0
- package/lib/v2/oceanengine/templates/content.art +14 -0
- package/lib/v2/openwrt/maintainer.js +3 -0
- package/lib/v2/openwrt/radar.js +13 -0
- package/lib/v2/openwrt/releases.js +25 -0
- package/lib/v2/openwrt/router.js +3 -0
- package/lib/v2/pincong/utils.js +7 -1
- package/lib/v2/pku/maintainer.js +3 -0
- package/lib/v2/pku/radar.js +20 -0
- package/lib/v2/pku/router.js +3 -0
- package/lib/v2/pku/ss/admission.js +53 -0
- package/lib/v2/pku/ss/notice.js +53 -0
- package/lib/v2/pku/ss/pg_admin.js +53 -0
- package/lib/v2/prestige-av/maintainer.js +3 -0
- package/lib/v2/prestige-av/radar.js +18 -0
- package/lib/v2/prestige-av/router.js +3 -0
- package/lib/{routes → v2}/prestige-av/series.js +8 -5
- package/lib/v2/qq/kg/cache.js +28 -0
- package/lib/v2/qq/kg/reply.js +21 -0
- package/lib/v2/qq/kg/user.js +50 -0
- package/lib/v2/qq/maintainer.js +2 -0
- package/lib/v2/qq/radar.js +14 -0
- package/lib/v2/qq/router.js +2 -0
- package/lib/v2/samsung/maintainer.js +3 -0
- package/lib/v2/samsung/radar.js +13 -0
- package/lib/v2/samsung/research/blog.js +49 -0
- package/lib/v2/samsung/router.js +3 -0
- package/lib/v2/{jasa/latest.js → scitation/journal.js} +24 -27
- package/lib/v2/scitation/maintainer.js +4 -0
- package/lib/v2/scitation/radar.js +19 -0
- package/lib/v2/scitation/router.js +4 -0
- package/lib/v2/scitation/section.js +90 -0
- package/lib/v2/scitation/templates/description.art +11 -0
- package/lib/v2/shuiguopai/index.js +76 -0
- package/lib/v2/shuiguopai/maintainer.js +3 -0
- package/lib/v2/shuiguopai/radar.js +13 -0
- package/lib/v2/shuiguopai/router.js +3 -0
- package/lib/v2/shuiguopai/templates/description.art +6 -0
- package/lib/v2/springer/journal.js +72 -0
- package/lib/v2/springer/maintainer.js +3 -0
- package/lib/v2/springer/radar.js +13 -0
- package/lib/v2/springer/router.js +3 -0
- package/lib/v2/springer/templates/description.art +12 -0
- package/lib/v2/supchina/index.js +67 -0
- package/lib/v2/supchina/maintainer.js +4 -0
- package/lib/v2/supchina/podcasts.js +66 -0
- package/lib/v2/supchina/radar.js +19 -0
- package/lib/v2/supchina/router.js +4 -0
- package/lib/v2/techflow520/index.js +34 -0
- package/lib/v2/techflow520/maintainer.js +4 -0
- package/lib/v2/techflow520/newsflash.js +32 -0
- package/lib/v2/techflow520/radar.js +19 -0
- package/lib/v2/techflow520/router.js +4 -0
- package/lib/v2/tencent/cloud/column.js +51 -0
- package/lib/v2/tencent/maintainer.js +1 -0
- package/lib/v2/tencent/radar.js +11 -0
- package/lib/v2/tencent/router.js +1 -0
- package/lib/v2/test/index.js +16 -1
- package/lib/v2/tiktok/user.js +28 -38
- package/lib/v2/trending/allTrending.js +169 -0
- package/lib/v2/trending/maintainer.js +3 -0
- package/lib/v2/trending/radar.js +35 -0
- package/lib/v2/trending/router.js +3 -0
- package/lib/v2/trending/templates/content.art +24 -0
- package/lib/v2/u3c3/index.js +59 -0
- package/lib/v2/u3c3/maintainer.js +3 -0
- package/lib/v2/u3c3/radar.js +29 -0
- package/lib/v2/u3c3/router.js +3 -0
- package/lib/v2/uraaka-joshi/uraaka-joshi-user.js +7 -1
- package/lib/v2/uraaka-joshi/uraaka-joshi.js +8 -1
- package/lib/v2/vlive/index.js +71 -0
- package/lib/v2/vlive/maintainer.js +3 -0
- package/lib/v2/vlive/radar.js +13 -0
- package/lib/v2/vlive/router.js +3 -0
- package/lib/v2/vlive/templates/post.art +8 -0
- package/lib/v2/vlive/templates/video.art +3 -0
- package/lib/v2/xiaohongshu/util.js +6 -6
- package/lib/v2/xjtu/2yuan/news.js +61 -0
- package/lib/v2/xjtu/dean.js +83 -0
- package/lib/{routes/universities → v2}/xjtu/ee.js +5 -5
- package/lib/{routes/universities → v2}/xjtu/gs/tzgg.js +6 -6
- package/lib/v2/xjtu/international.js +51 -0
- package/lib/v2/xjtu/job.js +81 -0
- package/lib/v2/xjtu/maintainer.js +9 -0
- package/lib/v2/xjtu/radar.js +53 -0
- package/lib/v2/xjtu/router.js +9 -0
- package/lib/v2/xjtu/std.js +58 -0
- package/lib/v2/xjtu/templates/attachments.art +3 -0
- package/lib/v2/xjtu/templates/std.art +4 -0
- package/lib/v2/xueqiu/column.js +42 -0
- package/lib/v2/xueqiu/maintainer.js +1 -0
- package/lib/v2/xueqiu/radar.js +6 -0
- package/lib/v2/xueqiu/router.js +1 -0
- package/lib/v2/zhangyoubao/index.js +42 -0
- package/lib/v2/zhangyoubao/maintainer.js +3 -0
- package/lib/v2/zhangyoubao/radar.js +13 -0
- package/lib/v2/zhangyoubao/router.js +3 -0
- package/lib/v2/zhangyoubao/templates/article.art +1 -0
- package/package.json +20 -19
- package/lib/routes/acfun/video.js +0 -44
- package/lib/routes/apnews/topics.js +0 -43
- package/lib/routes/dgjyw/index.js +0 -66
- package/lib/routes/hk01/channel.js +0 -22
- package/lib/routes/hk01/issue.js +0 -22
- package/lib/routes/mirror/entries.js +0 -80
- package/lib/routes/universities/ncwu/notice.js +0 -42
- package/lib/routes/universities/xjtu/dean.js +0 -86
- package/lib/routes/universities/xjtu/international.js +0 -53
- package/lib/routes/universities/xjtu/job.js +0 -50
- package/lib/v2/elsevier/latest.js +0 -87
- package/lib/v2/elsevier/volume.js +0 -75
- package/lib/v2/ieee/latestvol.js +0 -87
- package/lib/v2/jasa/maintainer.js +0 -4
- package/lib/v2/jasa/radar.js +0 -19
- package/lib/v2/jasa/router.js +0 -4
- package/lib/v2/jasa/section.js +0 -95
- package/lib/v2/jasa/templates/description.art +0 -11
package/lib/config.js
CHANGED
|
@@ -91,6 +91,10 @@ const calculateValue = () => {
|
|
|
91
91
|
includePaths: envs.HOTLINK_INCLUDE_PATHS && envs.HOTLINK_INCLUDE_PATHS.split(','),
|
|
92
92
|
excludePaths: envs.HOTLINK_EXCLUDE_PATHS && envs.HOTLINK_EXCLUDE_PATHS.split(','),
|
|
93
93
|
},
|
|
94
|
+
feature: {
|
|
95
|
+
allow_user_hotlink_template: envs.ALLOW_USER_HOTLINK_TEMPLATE === 'true',
|
|
96
|
+
filter_regex_engine: envs.FILTER_REGEX_ENGINE || 're2',
|
|
97
|
+
},
|
|
94
98
|
suffix: envs.SUFFIX,
|
|
95
99
|
titleLengthLimit: parseInt(envs.TITLE_LENGTH_LIMIT) || 150,
|
|
96
100
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
const config = require('@/config').value;
|
|
2
2
|
const cheerio = require('cheerio');
|
|
3
3
|
const logger = require('@/utils/logger');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { art } = require('@/utils/render');
|
|
6
|
+
|
|
7
|
+
const templateRegex = /\$\{([^{}]+)}/g;
|
|
8
|
+
const allowedUrlProperties = ['hash', 'host', 'hostname', 'href', 'origin', 'password', 'pathname', 'port', 'protocol', 'search', 'searchParams', 'username'];
|
|
9
|
+
const IframeWrapperTemplate = path.join(__dirname, 'templates/iframe.art');
|
|
4
10
|
|
|
5
11
|
// match path or sub-path
|
|
6
12
|
const matchPath = (path, paths) => {
|
|
@@ -19,9 +25,16 @@ const filterPath = (path) => {
|
|
|
19
25
|
return !(include && !matchPath(path, include)) && !(exclude && matchPath(path, exclude));
|
|
20
26
|
};
|
|
21
27
|
|
|
22
|
-
const interpolate = (str, obj) =>
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
const interpolate = (str, obj) =>
|
|
29
|
+
str.replace(templateRegex, (_, prop) => {
|
|
30
|
+
let needEncode = false;
|
|
31
|
+
if (prop.endsWith('_ue')) {
|
|
32
|
+
// url encode
|
|
33
|
+
prop = prop.slice(0, -3);
|
|
34
|
+
needEncode = true;
|
|
35
|
+
}
|
|
36
|
+
return needEncode ? encodeURIComponent(obj[prop]) : obj[prop];
|
|
37
|
+
});
|
|
25
38
|
const parseUrl = (str) => {
|
|
26
39
|
let url;
|
|
27
40
|
try {
|
|
@@ -32,48 +45,103 @@ const parseUrl = (str) => {
|
|
|
32
45
|
|
|
33
46
|
return url;
|
|
34
47
|
};
|
|
35
|
-
const replaceUrls = (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const old_src = $(this).attr('src');
|
|
45
|
-
const url = parseUrl(old_src);
|
|
46
|
-
if (url) {
|
|
47
|
-
const new_src = interpolate(template, url);
|
|
48
|
-
$(this).attr('src', new_src);
|
|
48
|
+
const replaceUrls = ($, selector, template, attribute = 'src') => {
|
|
49
|
+
$(selector).each(function () {
|
|
50
|
+
const old_src = $(this).attr(attribute);
|
|
51
|
+
if (old_src) {
|
|
52
|
+
const url = parseUrl(old_src);
|
|
53
|
+
if (url) {
|
|
54
|
+
// Cheerio will do the right thing to prohibit XSS.
|
|
55
|
+
$(this).attr(attribute, interpolate(template, url));
|
|
56
|
+
}
|
|
49
57
|
}
|
|
50
58
|
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const wrapWithIframe = ($, selector) => {
|
|
62
|
+
$(selector).each((_, elem) => {
|
|
63
|
+
elem = $(elem);
|
|
64
|
+
elem.replaceWith(art(IframeWrapperTemplate, { content: elem.toString() }));
|
|
65
|
+
});
|
|
66
|
+
};
|
|
51
67
|
|
|
52
|
-
|
|
68
|
+
const process = (html, image_hotlink_template, multimedia_hotlink_template, wrap_multimedia_in_iframe) => {
|
|
69
|
+
const $ = cheerio.load(html, undefined, false);
|
|
70
|
+
if (image_hotlink_template) {
|
|
71
|
+
replaceUrls($, 'img, picture > source', image_hotlink_template);
|
|
72
|
+
replaceUrls($, 'video[poster]', image_hotlink_template, 'poster');
|
|
73
|
+
}
|
|
74
|
+
if (multimedia_hotlink_template) {
|
|
75
|
+
replaceUrls($, 'video, video > source, audio, audio > source', multimedia_hotlink_template);
|
|
76
|
+
if (!image_hotlink_template) {
|
|
77
|
+
replaceUrls($, 'video[poster]', multimedia_hotlink_template, 'poster');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (wrap_multimedia_in_iframe) {
|
|
81
|
+
wrapWithIframe($, 'video, audio');
|
|
82
|
+
}
|
|
83
|
+
return $.html();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const validateTemplate = (template) => {
|
|
87
|
+
if (!template) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
[...template.matchAll(templateRegex)].forEach((match) => {
|
|
91
|
+
const prop = match[1].endsWith('_ue') ? match[1].slice(0, -3) : match[1];
|
|
92
|
+
if (!allowedUrlProperties.includes(prop)) {
|
|
93
|
+
throw new Error(`Invalid URL property: ${prop}`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
53
96
|
};
|
|
54
97
|
|
|
55
98
|
module.exports = async (ctx, next) => {
|
|
56
99
|
await next();
|
|
57
100
|
|
|
58
|
-
|
|
101
|
+
let image_hotlink_template = undefined;
|
|
102
|
+
let multimedia_hotlink_template = undefined;
|
|
103
|
+
const shouldWrapInIframe = ctx.query.wrap_multimedia_in_iframe === '1';
|
|
59
104
|
|
|
60
|
-
|
|
105
|
+
// Read params if enabled
|
|
106
|
+
if (config.feature.allow_user_hotlink_template) {
|
|
107
|
+
// By default, the config turns these features off. Set corresponding config to
|
|
108
|
+
// true to turn this feature on.
|
|
109
|
+
// A risk is that the media URLs will be replaced by user-supplied templates,
|
|
110
|
+
// so a user could literally take the control of "where are the media from",
|
|
111
|
+
// but only in their personal-use feed URL.
|
|
112
|
+
multimedia_hotlink_template = ctx.query.multimedia_hotlink_template;
|
|
113
|
+
image_hotlink_template = ctx.query.image_hotlink_template;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Force config hotlink template on conflict
|
|
117
|
+
if (config.hotlink.template) {
|
|
118
|
+
if (!filterPath(ctx.request.path)) {
|
|
119
|
+
image_hotlink_template = undefined;
|
|
120
|
+
} else {
|
|
121
|
+
image_hotlink_template = config.hotlink.template;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!image_hotlink_template && !multimedia_hotlink_template && !shouldWrapInIframe) {
|
|
61
126
|
return;
|
|
62
127
|
}
|
|
63
128
|
|
|
129
|
+
validateTemplate(image_hotlink_template);
|
|
130
|
+
validateTemplate(multimedia_hotlink_template);
|
|
131
|
+
|
|
64
132
|
// Assume that only description include image link
|
|
65
133
|
// and here we will only check them in description.
|
|
66
134
|
// Use Cheerio to load the description as html and filter all
|
|
67
135
|
// image link
|
|
68
136
|
if (ctx.state.data) {
|
|
69
137
|
if (ctx.state.data.description) {
|
|
70
|
-
ctx.state.data.description =
|
|
138
|
+
ctx.state.data.description = process(ctx.state.data.description, image_hotlink_template, multimedia_hotlink_template, shouldWrapInIframe);
|
|
71
139
|
}
|
|
72
140
|
|
|
73
141
|
ctx.state.data.item &&
|
|
74
142
|
ctx.state.data.item.forEach((item) => {
|
|
75
143
|
if (item.description) {
|
|
76
|
-
item.description =
|
|
144
|
+
item.description = process(item.description, image_hotlink_template, multimedia_hotlink_template, shouldWrapInIframe);
|
|
77
145
|
}
|
|
78
146
|
});
|
|
79
147
|
}
|
|
@@ -3,9 +3,26 @@ const cheerio = require('cheerio');
|
|
|
3
3
|
const { simplecc } = require('simplecc-wasm');
|
|
4
4
|
const got = require('@/utils/got');
|
|
5
5
|
const config = require('@/config').value;
|
|
6
|
+
const RE2 = require('re2');
|
|
6
7
|
|
|
7
8
|
let mercury_parser;
|
|
8
9
|
|
|
10
|
+
const resolveRelativeLink = ($, elem, attr, baseUrl) => {
|
|
11
|
+
const $elem = $(elem);
|
|
12
|
+
|
|
13
|
+
if (baseUrl) {
|
|
14
|
+
try {
|
|
15
|
+
const oldAttr = $elem.attr(attr);
|
|
16
|
+
if (oldAttr) {
|
|
17
|
+
// e.g. <video><source src="https://example.com"></video> should leave <video> unchanged
|
|
18
|
+
$elem.attr(attr, new URL(oldAttr, baseUrl).href);
|
|
19
|
+
}
|
|
20
|
+
} catch (e) {
|
|
21
|
+
// no-empty
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
9
26
|
module.exports = async (ctx, next) => {
|
|
10
27
|
await next();
|
|
11
28
|
|
|
@@ -76,50 +93,49 @@ module.exports = async (ctx, next) => {
|
|
|
76
93
|
|
|
77
94
|
$('script').remove();
|
|
78
95
|
|
|
79
|
-
$('a').each((_, ele) => {
|
|
80
|
-
const $ele = $(ele);
|
|
81
|
-
|
|
82
|
-
// absolute link
|
|
83
|
-
if (baseUrl) {
|
|
84
|
-
try {
|
|
85
|
-
$ele.attr('href', new URL($ele.attr('href'), baseUrl).href);
|
|
86
|
-
} catch (e) {
|
|
87
|
-
// no-empty
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
96
|
$('img').each((_, ele) => {
|
|
93
97
|
const $ele = $(ele);
|
|
94
98
|
|
|
95
99
|
// fix lazyload
|
|
96
100
|
if (!$ele.attr('src')) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const lazySrc = $ele.attr('data-src') || $ele.attr('data-original');
|
|
102
|
+
if (lazySrc) {
|
|
103
|
+
$ele.attr('src', lazySrc);
|
|
104
|
+
} else {
|
|
105
|
+
for (const key in ele.attribs) {
|
|
106
|
+
const value = ele.attribs[key].trim();
|
|
107
|
+
if (['.gif', '.png', '.jpg', '.webp'].some((suffix) => value.includes(suffix))) {
|
|
108
|
+
$ele.attr('src', value);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
113
|
}
|
|
105
114
|
|
|
106
|
-
// absolute link
|
|
107
|
-
if (baseUrl) {
|
|
108
|
-
try {
|
|
109
|
-
$ele.attr('src', new URL($ele.attr('src'), baseUrl).href);
|
|
110
|
-
} catch (e) {
|
|
111
|
-
// no-empty
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// referrerpolicy
|
|
116
|
-
$ele.attr('referrerpolicy', 'no-referrer');
|
|
117
|
-
|
|
118
115
|
// redundant attributes
|
|
119
116
|
['onclick', 'onerror', 'onload'].forEach((e) => {
|
|
120
117
|
$ele.removeAttr(e);
|
|
121
118
|
});
|
|
122
119
|
});
|
|
120
|
+
|
|
121
|
+
// resolve relative link & fix referrer policy
|
|
122
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
|
123
|
+
// https://www.w3schools.com/tags/att_href.asp
|
|
124
|
+
$('a, area').each((_, elem) => {
|
|
125
|
+
resolveRelativeLink($, elem, 'href', baseUrl);
|
|
126
|
+
// $(elem).attr('rel', 'noreferrer'); // currently no such a need
|
|
127
|
+
});
|
|
128
|
+
// https://www.w3schools.com/tags/att_src.asp
|
|
129
|
+
$('img, video, audio, source, iframe, embed, track').each((_, elem) => {
|
|
130
|
+
resolveRelativeLink($, elem, 'src', baseUrl);
|
|
131
|
+
});
|
|
132
|
+
$('video[poster]').each((_, elem) => {
|
|
133
|
+
resolveRelativeLink($, elem, 'poster', baseUrl);
|
|
134
|
+
});
|
|
135
|
+
$('img, iframe').each((_, elem) => {
|
|
136
|
+
$(elem).attr('referrerpolicy', 'no-referrer');
|
|
137
|
+
});
|
|
138
|
+
|
|
123
139
|
item.description = $('body').html() + '' + (config.suffix || '');
|
|
124
140
|
}
|
|
125
141
|
return item;
|
|
@@ -136,10 +152,25 @@ module.exports = async (ctx, next) => {
|
|
|
136
152
|
// filter
|
|
137
153
|
const makeRegex = (string) => {
|
|
138
154
|
// default: case_senstivie = true
|
|
155
|
+
const engine = config.feature.filter_regex_engine;
|
|
139
156
|
if (ctx.query.filter_case_sensitive === 'false') {
|
|
140
|
-
|
|
157
|
+
switch (engine) {
|
|
158
|
+
case 'regexp':
|
|
159
|
+
return new RegExp(string, 'i');
|
|
160
|
+
case 're2':
|
|
161
|
+
return new RE2(string, 'i');
|
|
162
|
+
default:
|
|
163
|
+
throw Error(`Invalid Engine Value: ${engine}, please check your config.`);
|
|
164
|
+
}
|
|
141
165
|
} else {
|
|
142
|
-
|
|
166
|
+
switch (engine) {
|
|
167
|
+
case 'regexp':
|
|
168
|
+
return new RegExp(string);
|
|
169
|
+
case 're2':
|
|
170
|
+
return new RE2(string);
|
|
171
|
+
default:
|
|
172
|
+
throw Error(`Invalid Engine Value: ${engine}, please check your config.`);
|
|
173
|
+
}
|
|
143
174
|
}
|
|
144
175
|
};
|
|
145
176
|
|
|
@@ -272,6 +303,8 @@ module.exports = async (ctx, next) => {
|
|
|
272
303
|
throw Error(`Invalid parameter <code>brief=${ctx.query.brief}</code>. Please check the doc https://docs.rsshub.app/parameter.html#shu-chu-jian-xun`);
|
|
273
304
|
}
|
|
274
305
|
}
|
|
306
|
+
|
|
307
|
+
// some parameters are processed in `anti-hotlink.js`
|
|
275
308
|
}
|
|
276
309
|
}
|
|
277
310
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<iframe referrerpolicy="no-referrer" width=100% height=150vh frameborder=0 marginheight=0 marginwidth=0
|
|
2
|
+
style="border:0; margin:0; padding:0; width:100%; height:150vh;"
|
|
3
|
+
srcdoc="
|
|
4
|
+
<!DOCTYPE html>
|
|
5
|
+
<html>
|
|
6
|
+
<head>
|
|
7
|
+
<meta name="referrer" content="no-referrer">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
{{ content }}
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
13
|
+
">
|
|
14
|
+
</iframe>
|
package/lib/radar-rules.js
CHANGED
|
@@ -1135,17 +1135,6 @@ module.exports = {
|
|
|
1135
1135
|
},
|
|
1136
1136
|
],
|
|
1137
1137
|
},
|
|
1138
|
-
'apnews.com': {
|
|
1139
|
-
_name: 'AP News',
|
|
1140
|
-
'.': [
|
|
1141
|
-
{
|
|
1142
|
-
title: '话题',
|
|
1143
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#ap-news',
|
|
1144
|
-
source: '/:topic',
|
|
1145
|
-
target: '/apnews/topics/:topic',
|
|
1146
|
-
},
|
|
1147
|
-
],
|
|
1148
|
-
},
|
|
1149
1138
|
'csc.edu.cn': {
|
|
1150
1139
|
_name: '国家留学网',
|
|
1151
1140
|
www: [
|
|
@@ -1589,41 +1578,6 @@ module.exports = {
|
|
|
1589
1578
|
},
|
|
1590
1579
|
],
|
|
1591
1580
|
},
|
|
1592
|
-
'hk01.com': {
|
|
1593
|
-
_name: '香港01',
|
|
1594
|
-
www: [
|
|
1595
|
-
{
|
|
1596
|
-
title: '最 Hit',
|
|
1597
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01',
|
|
1598
|
-
source: ['/hot', '/'],
|
|
1599
|
-
target: '/hk01/hot',
|
|
1600
|
-
},
|
|
1601
|
-
{
|
|
1602
|
-
title: 'zone',
|
|
1603
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01',
|
|
1604
|
-
source: '/zone/:id/:title',
|
|
1605
|
-
target: '/hk01/zone/:id',
|
|
1606
|
-
},
|
|
1607
|
-
{
|
|
1608
|
-
title: 'channel',
|
|
1609
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01',
|
|
1610
|
-
source: '/channel/:id/:title',
|
|
1611
|
-
target: '/hk01/channel/:id',
|
|
1612
|
-
},
|
|
1613
|
-
{
|
|
1614
|
-
title: 'issue',
|
|
1615
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01',
|
|
1616
|
-
source: '/issue/:id/:title',
|
|
1617
|
-
target: '/hk01/issue/:id',
|
|
1618
|
-
},
|
|
1619
|
-
{
|
|
1620
|
-
title: 'tag',
|
|
1621
|
-
docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01',
|
|
1622
|
-
source: '/tag/:id/:title',
|
|
1623
|
-
target: '/hk01/tag/:id',
|
|
1624
|
-
},
|
|
1625
|
-
],
|
|
1626
|
-
},
|
|
1627
1581
|
'popiapp.cn': {
|
|
1628
1582
|
_name: 'Popi 提问箱',
|
|
1629
1583
|
www: [
|
|
@@ -1656,23 +1610,6 @@ module.exports = {
|
|
|
1656
1610
|
},
|
|
1657
1611
|
],
|
|
1658
1612
|
},
|
|
1659
|
-
'acfun.cn': {
|
|
1660
|
-
_name: 'AcFun',
|
|
1661
|
-
www: [
|
|
1662
|
-
{
|
|
1663
|
-
tilte: '番剧',
|
|
1664
|
-
docs: 'https://docs.rsshub.app/anime.html#acfun-fan-ju',
|
|
1665
|
-
source: '/bangumi/:id',
|
|
1666
|
-
target: (params) => `/acfun/bangumi/${params.id.replace('aa', '')}`,
|
|
1667
|
-
},
|
|
1668
|
-
{
|
|
1669
|
-
title: '用户投稿',
|
|
1670
|
-
docs: 'https://docs.rsshub.app/anime.html#acfun-yong-hu-tou-gao',
|
|
1671
|
-
source: '/u/:id',
|
|
1672
|
-
target: '/acfun/user/video/:id',
|
|
1673
|
-
},
|
|
1674
|
-
],
|
|
1675
|
-
},
|
|
1676
1613
|
'jjmhw.cc': {
|
|
1677
1614
|
_name: '漫小肆',
|
|
1678
1615
|
www: [
|
|
@@ -1981,35 +1918,6 @@ module.exports = {
|
|
|
1981
1918
|
},
|
|
1982
1919
|
],
|
|
1983
1920
|
},
|
|
1984
|
-
'gcores.com': {
|
|
1985
|
-
_name: '机核网',
|
|
1986
|
-
www: [
|
|
1987
|
-
{
|
|
1988
|
-
title: '资讯',
|
|
1989
|
-
docs: 'https://docs.rsshub.app/program-update.html#eagle',
|
|
1990
|
-
source: '/news',
|
|
1991
|
-
target: '/gcores/category/news',
|
|
1992
|
-
},
|
|
1993
|
-
{
|
|
1994
|
-
title: '视频',
|
|
1995
|
-
docs: 'https://docs.rsshub.app/program-update.html#eagle',
|
|
1996
|
-
source: '/videos',
|
|
1997
|
-
target: '/gcores/category/videos',
|
|
1998
|
-
},
|
|
1999
|
-
{
|
|
2000
|
-
title: '电台',
|
|
2001
|
-
docs: 'https://docs.rsshub.app/program-update.html#eagle',
|
|
2002
|
-
source: '/radios',
|
|
2003
|
-
target: '/gcores/category/radios',
|
|
2004
|
-
},
|
|
2005
|
-
{
|
|
2006
|
-
title: '文章',
|
|
2007
|
-
docs: 'https://docs.rsshub.app/program-update.html#eagle',
|
|
2008
|
-
source: '/articles',
|
|
2009
|
-
target: '/gcores/category/articles',
|
|
2010
|
-
},
|
|
2011
|
-
],
|
|
2012
|
-
},
|
|
2013
1921
|
'bgm.tv': {
|
|
2014
1922
|
_name: 'Bangumi',
|
|
2015
1923
|
'.': [
|
package/lib/router.js
CHANGED
|
@@ -228,8 +228,8 @@ router.get('/pornhub/:language?/users/:username', lazyloadRouteHandler('./routes
|
|
|
228
228
|
router.get('/pornhub/:language?/model/:username/:sort?', lazyloadRouteHandler('./routes/pornhub/model'));
|
|
229
229
|
router.get('/pornhub/:language?/pornstar/:username/:sort?', lazyloadRouteHandler('./routes/pornhub/pornstar'));
|
|
230
230
|
|
|
231
|
-
// Prestige
|
|
232
|
-
router.get('/prestige-av/series/:mid/:sort?', lazyloadRouteHandler('./routes/prestige-av/series'));
|
|
231
|
+
// Prestige migrated to v2
|
|
232
|
+
// router.get('/prestige-av/series/:mid/:sort?', lazyloadRouteHandler('./routes/prestige-av/series'));
|
|
233
233
|
|
|
234
234
|
// yande.re
|
|
235
235
|
router.get('/yande.re/post/popular_recent', lazyloadRouteHandler('./routes/yande.re/post_popular_recent'));
|
|
@@ -336,7 +336,7 @@ router.get('/miui/:device/:type?/:region?', lazyloadRouteHandler('./routes/mi/mi
|
|
|
336
336
|
router.get('/mi/bbs/board/:boardId', lazyloadRouteHandler('./routes/mi/board'));
|
|
337
337
|
|
|
338
338
|
// Keep
|
|
339
|
-
router.get('/keep/user/:id', lazyloadRouteHandler('./routes/keep/user'));
|
|
339
|
+
// router.get('/keep/user/:id', lazyloadRouteHandler('./routes/keep/user'));
|
|
340
340
|
|
|
341
341
|
// 起点
|
|
342
342
|
router.get('/qidian/chapter/:id', lazyloadRouteHandler('./routes/qidian/chapter'));
|
|
@@ -759,7 +759,7 @@ router.get('/upc/main/:type?', lazyloadRouteHandler('./routes/universities/upc/m
|
|
|
759
759
|
router.get('/upc/jsj/:type?', lazyloadRouteHandler('./routes/universities/upc/jsj'));
|
|
760
760
|
|
|
761
761
|
// 华北水利水电大学
|
|
762
|
-
router.get('/ncwu/notice', lazyloadRouteHandler('./routes/universities/ncwu/notice'));
|
|
762
|
+
// router.get('/ncwu/notice', lazyloadRouteHandler('./routes/universities/ncwu/notice'));
|
|
763
763
|
|
|
764
764
|
// 太原师范学院
|
|
765
765
|
router.get('/tynu', lazyloadRouteHandler('./routes/universities/tynu/tynu'));
|
|
@@ -939,9 +939,9 @@ router.get('/nhentai/:key/:keyword/:mode?', lazyloadRouteHandler('./routes/nhent
|
|
|
939
939
|
// 龙腾网
|
|
940
940
|
router.get('/ltaaa/:category?', lazyloadRouteHandler('./routes/ltaaa/index'));
|
|
941
941
|
|
|
942
|
-
// AcFun
|
|
943
|
-
router.get('/acfun/bangumi/:id', lazyloadRouteHandler('./routes/acfun/bangumi'));
|
|
944
|
-
router.get('/acfun/user/video/:uid', lazyloadRouteHandler('./routes/acfun/video'));
|
|
942
|
+
// AcFun migrated to v2
|
|
943
|
+
// router.get('/acfun/bangumi/:id', lazyloadRouteHandler('./routes/acfun/bangumi'));
|
|
944
|
+
// router.get('/acfun/user/video/:uid', lazyloadRouteHandler('./routes/acfun/video'));
|
|
945
945
|
|
|
946
946
|
// Auto Trader
|
|
947
947
|
router.get('/autotrader/:query', lazyloadRouteHandler('./routes/autotrader'));
|
|
@@ -2201,11 +2201,11 @@ router.get('/mcbbs/post/:tid/:authorid?', lazyloadRouteHandler('./routes/mcbbs/p
|
|
|
2201
2201
|
router.get('/pocket/trending', lazyloadRouteHandler('./routes/pocket/trending'));
|
|
2202
2202
|
|
|
2203
2203
|
// HK01
|
|
2204
|
-
router.get('/hk01/zone/:id', lazyloadRouteHandler('./routes/hk01/zone'));
|
|
2205
|
-
router.get('/hk01/channel/:id', lazyloadRouteHandler('./routes/hk01/channel'));
|
|
2206
|
-
router.get('/hk01/issue/:id', lazyloadRouteHandler('./routes/hk01/issue'));
|
|
2207
|
-
router.get('/hk01/tag/:id', lazyloadRouteHandler('./routes/hk01/tag'));
|
|
2208
|
-
router.get('/hk01/hot', lazyloadRouteHandler('./routes/hk01/hot'));
|
|
2204
|
+
// router.get('/hk01/zone/:id', lazyloadRouteHandler('./routes/hk01/zone'));
|
|
2205
|
+
// router.get('/hk01/channel/:id', lazyloadRouteHandler('./routes/hk01/channel'));
|
|
2206
|
+
// router.get('/hk01/issue/:id', lazyloadRouteHandler('./routes/hk01/issue'));
|
|
2207
|
+
// router.get('/hk01/tag/:id', lazyloadRouteHandler('./routes/hk01/tag'));
|
|
2208
|
+
// router.get('/hk01/hot', lazyloadRouteHandler('./routes/hk01/hot'));
|
|
2209
2209
|
|
|
2210
2210
|
// 码农周刊
|
|
2211
2211
|
router.get('/manong-weekly', lazyloadRouteHandler('./routes/manong-weekly/issues'));
|
|
@@ -2265,8 +2265,8 @@ router.get('/transferwise/pair/:source/:target', lazyloadRouteHandler('./routes/
|
|
|
2265
2265
|
// chocolatey
|
|
2266
2266
|
router.get('/chocolatey/software/:name?', lazyloadRouteHandler('./routes/chocolatey/software'));
|
|
2267
2267
|
|
|
2268
|
-
// Nyaa
|
|
2269
|
-
router.get('/nyaa/search/:query?', lazyloadRouteHandler('./routes/nyaa/search'));
|
|
2268
|
+
// Nyaa migrated to v2
|
|
2269
|
+
// router.get('/nyaa/search/:query?', lazyloadRouteHandler('./routes/nyaa/search'));
|
|
2270
2270
|
|
|
2271
2271
|
// 片源网 migrated to v2
|
|
2272
2272
|
// router.get('/pianyuan/index/:media?', lazyloadRouteHandler('./routes/pianyuan/app'));
|
|
@@ -2364,7 +2364,7 @@ router.get('/xinquji/today/internal', lazyloadRouteHandler('./routes/xinquji/int
|
|
|
2364
2364
|
router.get('/gbcc/trust', lazyloadRouteHandler('./routes/gbcc/trust'));
|
|
2365
2365
|
|
|
2366
2366
|
// Associated Press
|
|
2367
|
-
router.get('/apnews/topics/:topic', lazyloadRouteHandler('./routes/apnews/topics'));
|
|
2367
|
+
// router.get('/apnews/topics/:topic', lazyloadRouteHandler('./routes/apnews/topics'));
|
|
2368
2368
|
|
|
2369
2369
|
// CBC
|
|
2370
2370
|
router.get('/cbc/topics/:topic?', lazyloadRouteHandler('./routes/cbc/topics'));
|
|
@@ -2492,11 +2492,11 @@ router.get('/wolley/user/:id', lazyloadRouteHandler('./routes/wolley/user'));
|
|
|
2492
2492
|
router.get('/wolley/host/:host', lazyloadRouteHandler('./routes/wolley/host'));
|
|
2493
2493
|
|
|
2494
2494
|
// 西安交大
|
|
2495
|
-
router.get('/xjtu/gs/tzgg', lazyloadRouteHandler('./routes/universities/xjtu/gs/tzgg'));
|
|
2496
|
-
router.get('/xjtu/dean/:subpath+', lazyloadRouteHandler('./routes/universities/xjtu/dean'));
|
|
2497
|
-
router.get('/xjtu/international/:subpath+', lazyloadRouteHandler('./routes/universities/xjtu/international'));
|
|
2498
|
-
router.get('/xjtu/job/:subpath?', lazyloadRouteHandler('./routes/universities/xjtu/job'));
|
|
2499
|
-
router.get('/xjtu/ee/:id?', lazyloadRouteHandler('./routes/universities/xjtu/ee'));
|
|
2495
|
+
// router.get('/xjtu/gs/tzgg', lazyloadRouteHandler('./routes/universities/xjtu/gs/tzgg'));
|
|
2496
|
+
// router.get('/xjtu/dean/:subpath+', lazyloadRouteHandler('./routes/universities/xjtu/dean'));
|
|
2497
|
+
// router.get('/xjtu/international/:subpath+', lazyloadRouteHandler('./routes/universities/xjtu/international'));
|
|
2498
|
+
// router.get('/xjtu/job/:subpath?', lazyloadRouteHandler('./routes/universities/xjtu/job'));
|
|
2499
|
+
// router.get('/xjtu/ee/:id?', lazyloadRouteHandler('./routes/universities/xjtu/ee'));
|
|
2500
2500
|
|
|
2501
2501
|
// booksource
|
|
2502
2502
|
router.get('/booksource', lazyloadRouteHandler('./routes/booksource/index'));
|
|
@@ -2863,7 +2863,7 @@ router.get('/law/jctd', lazyloadRouteHandler('./routes/law/jctd'));
|
|
|
2863
2863
|
router.get('/samsungmembers/latest', lazyloadRouteHandler('./routes/samsungmembers/latest'));
|
|
2864
2864
|
|
|
2865
2865
|
// 东莞教研网
|
|
2866
|
-
router.get('/dgjyw/:type', lazyloadRouteHandler('./routes/dgjyw/index'));
|
|
2866
|
+
// router.get('/dgjyw/:type', lazyloadRouteHandler('./routes/dgjyw/index'));
|
|
2867
2867
|
|
|
2868
2868
|
// 中国信息通信研究院
|
|
2869
2869
|
router.get('/gov/caict/bps', lazyloadRouteHandler('./routes/gov/caict/bps'));
|
|
@@ -4065,7 +4065,7 @@ router.get('/secrss/author/:author?', lazyloadRouteHandler('./routes/secrss/auth
|
|
|
4065
4065
|
router.get('/fashionnetwork/headline/:country?', lazyloadRouteHandler('./routes/fashionnetwork/headline.js'));
|
|
4066
4066
|
|
|
4067
4067
|
// mirror.xyz
|
|
4068
|
-
router.get('/mirror/:id', lazyloadRouteHandler('./routes/mirror/entries'));
|
|
4068
|
+
// router.get('/mirror/:id', lazyloadRouteHandler('./routes/mirror/entries'));
|
|
4069
4069
|
|
|
4070
4070
|
// KBS migrated to v2
|
|
4071
4071
|
// router.get('/kbs/today/:language?', lazyloadRouteHandler('./routes/kbs/today'));
|
|
@@ -2,7 +2,7 @@ const got = require('@/utils/got');
|
|
|
2
2
|
const cheerio = require('cheerio');
|
|
3
3
|
|
|
4
4
|
module.exports = async (ctx) => {
|
|
5
|
-
const rootUrl = 'https://www.
|
|
5
|
+
const rootUrl = 'https://www.agemys.com';
|
|
6
6
|
const currentUrl = `${rootUrl}/update`;
|
|
7
7
|
const response = await got({
|
|
8
8
|
method: 'get',
|
|
@@ -35,7 +35,7 @@ module.exports = async (ctx) => {
|
|
|
35
35
|
|
|
36
36
|
const items = [];
|
|
37
37
|
for await (const item of asyncPool(3, chapter_item, (item) =>
|
|
38
|
-
ctx.cache.tryGet(item, async () => {
|
|
38
|
+
ctx.cache.tryGet(item.link.href, async () => {
|
|
39
39
|
const response = await got({
|
|
40
40
|
method: 'get',
|
|
41
41
|
url: item.link,
|
|
@@ -61,7 +61,7 @@ module.exports = async (ctx) => {
|
|
|
61
61
|
|
|
62
62
|
ctx.state.data = {
|
|
63
63
|
title: `笔趣阁 ${title}`,
|
|
64
|
-
link: pageUrl,
|
|
64
|
+
link: pageUrl.href,
|
|
65
65
|
image: cover_url,
|
|
66
66
|
description,
|
|
67
67
|
item: items,
|
|
@@ -1,40 +1,18 @@
|
|
|
1
1
|
const cheerio = require('cheerio');
|
|
2
|
+
const { parseDate } = require('@/utils/parse-date');
|
|
3
|
+
const dayjs = require('dayjs');
|
|
2
4
|
|
|
3
5
|
module.exports = async (ctx) => {
|
|
4
6
|
const baseIndexUrl = 'https://www.sice.uestc.edu.cn/index.htm';
|
|
5
7
|
const host = 'https://www.sice.uestc.edu.cn/';
|
|
6
|
-
const browser = await require('@/utils/puppeteer')();
|
|
8
|
+
const browser = await require('@/utils/puppeteer')({ stealth: true });
|
|
7
9
|
const page = await browser.newPage();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// 在每个新页面打开前执行以下脚本
|
|
12
|
-
const newProto = navigator.__proto__;
|
|
13
|
-
delete newProto.webdriver; // 删除navigator.webdriver字段
|
|
14
|
-
navigator.__proto__ = newProto;
|
|
15
|
-
window.chrome = {}; // 添加window.chrome字段,为增加真实性还需向内部填充一些值
|
|
16
|
-
window.chrome.app = { InstallState: 'hehe', RunningState: 'haha', getDetails: 'xixi', getIsInstalled: 'ohno' };
|
|
17
|
-
window.chrome.csi = function () {};
|
|
18
|
-
window.chrome.loadTimes = function () {};
|
|
19
|
-
window.chrome.runtime = function () {};
|
|
20
|
-
Object.defineProperty(navigator, 'userAgent', {
|
|
21
|
-
// userAgent在无头模式下有headless字样,所以需覆写
|
|
22
|
-
get: () => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36',
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(navigator, 'plugins', {
|
|
25
|
-
// 伪装真实的插件信息
|
|
26
|
-
get: () => [{ description: 'Portable Document Format', filename: 'internal-pdf-viewer', length: 1, name: 'Chrome PDF Plugin' }],
|
|
27
|
-
});
|
|
28
|
-
Object.defineProperty(navigator, 'languages', {
|
|
29
|
-
// 添加语言
|
|
30
|
-
get: () => ['zh-CN', 'zh', 'en'],
|
|
31
|
-
});
|
|
32
|
-
const originalQuery = window.navigator.permissions.query; // notification伪装
|
|
33
|
-
window.navigator.permissions.query = (parameters) => (parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters));
|
|
10
|
+
await page.setRequestInterception(true);
|
|
11
|
+
page.on('request', (request) => {
|
|
12
|
+
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
|
|
34
13
|
});
|
|
35
|
-
|
|
36
14
|
await page.goto(baseIndexUrl, {
|
|
37
|
-
waitUntil: '
|
|
15
|
+
waitUntil: 'networkidle2',
|
|
38
16
|
});
|
|
39
17
|
const content = await page.content();
|
|
40
18
|
await browser.close();
|
|
@@ -43,14 +21,15 @@ module.exports = async (ctx) => {
|
|
|
43
21
|
const out = $('.notice p')
|
|
44
22
|
.map((index, item) => {
|
|
45
23
|
item = $(item);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
24
|
+
const now = dayjs();
|
|
25
|
+
let date = dayjs(now.year() + '-' + item.find('a.date').text());
|
|
26
|
+
if (now < date) {
|
|
27
|
+
date = dayjs(now.year() - 1 + '-' + item.find('a.date').text());
|
|
49
28
|
}
|
|
50
29
|
return {
|
|
51
30
|
title: item.find('a[href]').text(),
|
|
52
31
|
link: host + item.find('a[href]').attr('href'),
|
|
53
|
-
pubDate: date,
|
|
32
|
+
pubDate: parseDate(date),
|
|
54
33
|
};
|
|
55
34
|
})
|
|
56
35
|
.get();
|