Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add filter_case_sensitive url parameter #3910

Merged
merged 2 commits into from
Feb 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/en/parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Set `filterout` to exclude unwanted content.

For example: [https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black](https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black)

Set `filter_case_sensitive` to determine whether the filtering keywords should be case sensitive. The parameter would apply to both `filter` and `filterout`.

Default: `true`

Example: [https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false](https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false)

### Limit Entries

Set `limit` to limit the number of articles in the feed.
Expand Down
6 changes: 6 additions & 0 deletions docs/parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ filterout 去掉不要的内容

举例: <https://rsshub.app/bilibili/user/coin/2267573?filterout=微小微|赤九玖|暴走大事件>

filter_case_sensitive 过滤是否区分大小写,filter 和 filterout 同时适用

默认为 true,区分大小写

举例 1: <https://rsshub.app/bilibili/user/coin/2267573?filter=diyGOD|RSShub&filter_case_sensitive=false>

## 条数限制

可以使用 limit 参数限制最大条数, 主要用于排行榜类 RSS
Expand Down
21 changes: 15 additions & 6 deletions lib/middleware/parameter.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ module.exports = async (ctx, next) => {
}

// filter
const makeRegex = (string) => {
// default: case_senstivie = true
if (ctx.query.filter_case_sensitive === 'false') {
return new RegExp(string, 'i');
} else {
return new RegExp(string);
}
};

if (ctx.query.filter || ctx.query.filter_title || ctx.query.filter_description || ctx.query.filter_author) {
if (ctx.query.filter) {
ctx.query.filter_title = ctx.query.filter;
Expand All @@ -131,9 +140,9 @@ module.exports = async (ctx, next) => {
const description = item.description || title;
const author = item.author || '';
let isFilter = true;
ctx.query.filter_title && (isFilter = isFilter && !title.match(ctx.query.filter_title));
ctx.query.filter_description && (isFilter = isFilter && !description.match(ctx.query.filter_description));
ctx.query.filter_author && (isFilter = isFilter && !author.match(ctx.query.filter_author));
ctx.query.filter_title && (isFilter = isFilter && !title.match(makeRegex(ctx.query.filter_title)));
ctx.query.filter_description && (isFilter = isFilter && !description.match(makeRegex(ctx.query.filter_description)));
ctx.query.filter_author && (isFilter = isFilter && !author.match(makeRegex(ctx.query.filter_author)));
return !isFilter;
});
}
Expand All @@ -148,9 +157,9 @@ module.exports = async (ctx, next) => {
const description = item.description || title;
const author = item.author || '';
let isFilter = true;
ctx.query.filterout_title && (isFilter = isFilter && !title.match(ctx.query.filterout_title));
ctx.query.filterout_description && (isFilter = isFilter && !description.match(ctx.query.filterout_description));
ctx.query.filterout_author && (isFilter = isFilter && !author.match(ctx.query.filterout_author));
ctx.query.filterout_title && (isFilter = isFilter && !title.match(makeRegex(ctx.query.filterout_title)));
ctx.query.filterout_description && (isFilter = isFilter && !description.match(makeRegex(ctx.query.filterout_description)));
ctx.query.filterout_author && (isFilter = isFilter && !author.match(makeRegex(ctx.query.filterout_author)));
return isFilter;
});
}
Expand Down
98 changes: 98 additions & 0 deletions test/middleware/parameter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,48 @@ describe('filter', () => {
expect(parsed.items[1].title).toBe('Title5');
});

it(`filter filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filter=description4|title5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(0);
});

it(`filter filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});

it(`filter_title`, async () => {
const response = await request.get('/test/1?filter_title=Description4|Title5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title5');
});

it(`filter_title filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title5');
});

it(`filter_description`, async () => {
const response = await request.get('/test/1?filter_description=Description4|Title5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title4');
});

it(`filter_description filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(1);
expect(parsed.items[0].title).toBe('Title4');
});

it(`filter_author`, async () => {
const response = await request.get('/test/1?filter_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(response.text);
Expand All @@ -41,6 +69,20 @@ describe('filter', () => {
expect(parsed.items[1].title).toBe('Title5');
});

it(`filter_author filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filter_author=diygod4|diygod5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(0);
});

it(`filter_author filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filter_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(2);
expect(parsed.items[0].title).toBe('Title4');
expect(parsed.items[1].title).toBe('Title5');
});

it(`filter_time`, async () => {
const response = await request.get('/test/current_time?filter_time=25');
const parsed = await parser.parseString(response.text);
Expand All @@ -58,6 +100,24 @@ describe('filter', () => {
expect(parsed.items[2].title).toBe('Title3');
});

it(`filterout filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filterout=description4|title5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(5);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
});

it(`filterout filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
});

it(`filterout_title`, async () => {
const response = await request.get('/test/1?filterout_title=Description4|Title5');
const parsed = await parser.parseString(response.text);
Expand All @@ -68,6 +128,16 @@ describe('filter', () => {
expect(parsed.items[3].title).toBe('Title4');
});

it(`filterout_title filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_title=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
expect(parsed.items[3].title).toBe('Title4');
});

it(`filterout_description`, async () => {
const response = await request.get('/test/1?filterout_description=Description4|Title5');
const parsed = await parser.parseString(response.text);
Expand All @@ -78,6 +148,16 @@ describe('filter', () => {
expect(parsed.items[3].title).toBe('Title5');
});

it(`filterout_description filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_description=description4|title5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(4);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
expect(parsed.items[3].title).toBe('Title5');
});

it(`filterout_author`, async () => {
const response = await request.get('/test/1?filterout_author=DIYgod4|DIYgod5');
const parsed = await parser.parseString(response.text);
Expand All @@ -86,6 +166,24 @@ describe('filter', () => {
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
});

it(`filterout_author filter_case_sensitive default`, async () => {
const response = await request.get('/test/1?filterout_author=diygod4|diygod5');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(5);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
});

it(`filterout_author filter_case_sensitive=false`, async () => {
const response = await request.get('/test/1?filterout_author=diygod4|diygod5&filter_case_sensitive=false');
const parsed = await parser.parseString(response.text);
expect(parsed.items.length).toBe(3);
expect(parsed.items[0].title).toBe('Title1');
expect(parsed.items[1].title).toBe('Title2');
expect(parsed.items[2].title).toBe('Title3');
});
});

describe('limit', () => {
Expand Down