Skip to content

Commit 9adf291

Browse files
committed
feat(test-url): auto detect feed url
1 parent 75fb8fb commit 9adf291

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

i18n/en.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ NO: NO
4040
CANCEL: Canceled
4141
PAGE_PRE: Previous page
4242
PAGE_NEXT: Next page
43+
FOUND_FEED_MORE_THAN_ONE: Found feed more than 1

i18n/zh-cn.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ NO: 否
4040
CANCEL: 取消操作
4141
PAGE_PRE: 上一页
4242
PAGE_NEXT: 下一页
43+
FOUND_FEED_MORE_THAN_ONE: 找到不止一个订阅地址

middlewares/test-url.js

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,55 @@
11
const got = require('../utils/got');
2+
const feedUtil = require('../utils/feed');
23
const Parser = require('rss-parser');
34
const RSS = require('../proxies/rssFeed');
5+
const i18n = require('../i18n');
46

7+
// eslint-disable-next-line max-lines-per-function
58
module.exports = async (ctx, next) => {
69
const url = encodeURI(ctx.state.feedUrl);
7-
const feed = await RSS.getFeedByUrl(url);
10+
let feed = await RSS.getFeedByUrl(url);
811
if (feed) {
912
ctx.state.feed = feed;
1013
ctx.state.feed.title = feed.feed_title;
1114
await next();
1215
} else {
1316
try {
1417
const res = await got.get(url);
15-
// handle redirect
16-
ctx.state.feedUrl = decodeURI(res.url);
17-
const parser = new Parser();
18-
let feed = await parser.parseString(res.body);
19-
delete feed.items;
20-
ctx.state.feed = feed;
18+
ctx.state.feedUrl = decodeURI(res.url); // handle redirect
19+
feed = await feedUtil.isFeedValid(res.body);
20+
if (!feed) {
21+
// check feedUrl
22+
ctx.state.feedUrl = await feedUtil.findFeed(res.body, res.url);
23+
ctx.state.feedUrl = ctx.state.feedUrl.map(decodeURI);
24+
const parser = new Parser();
25+
switch (ctx.state.feedUrl.length) {
26+
case 0:
27+
throw new Error('FETCH_ERROR');
28+
case 1:
29+
// eslint-disable-next-line no-case-declarations
30+
const res = await got(encodeURI(ctx.state.feedUrl[0]));
31+
feed = await parser.parseString(res.body);
32+
delete feed.items;
33+
ctx.state.feed = feed;
34+
await next(); // next
35+
break;
36+
default:
37+
// eslint-disable-next-line no-case-declarations
38+
const builder = [];
39+
builder.push(
40+
`**${i18n['FOUND_FEED_MORE_THAN_ONE']}:**`
41+
);
42+
builder.push(...ctx.state.feedUrl);
43+
ctx.replyWithMarkdown(builder.join('\n'));
44+
break;
45+
}
46+
} else {
47+
delete feed.items;
48+
ctx.state.feed = feed;
49+
await next();
50+
}
2151
} catch (e) {
52+
if (e instanceof Error) throw e;
2253
if (e.response) {
2354
switch (e.response.status) {
2455
case 404:
@@ -31,6 +62,5 @@ module.exports = async (ctx, next) => {
3162
throw new Error('FETCH_ERROR');
3263
}
3364
}
34-
await next();
3565
}
3666
};

utils/feed.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
const cheerio = require('cheerio');
22
const RSSParser = require('rss-parser');
3-
exports.isFeedValid = async function (feedStr) {
3+
4+
exports.isFeedValid = async function(feedStr) {
45
const parser = new RSSParser();
6+
let feed;
57
try {
6-
await parser.parseString(feedStr)
8+
feed = await parser.parseString(feedStr);
79
} catch (e) {
810
return false;
911
}
10-
return true;
11-
}
12+
return feed;
13+
};
1214

13-
exports.findFedd = async function (html) {
15+
exports.findFeed = async function(html, reqUrl) {
16+
reqUrl = new URL(reqUrl);
1417
const $ = cheerio.load(html);
15-
return $('[rel=alternate]')
18+
const urls = $('head')
19+
.find('[rel=alternate]')
1620
.get()
1721
.map((i) => {
1822
i = $(i);
19-
return i.attr('href');
23+
const url = i.attr('href');
24+
try {
25+
return new URL(url).toString();
26+
} catch (e) {
27+
reqUrl.pathname = url;
28+
return reqUrl.toString();
29+
}
2030
});
21-
}
31+
return urls;
32+
};

0 commit comments

Comments
 (0)