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

merge dev to main, v3.9.2 #109

Merged
merged 6 commits into from
Jul 21, 2024
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CHANGELOG

## 3.9.2

- 优化:播放页 弹窗净化
- 新增:播放页 强制隐藏播放器内所有弹窗
- 新增:播放页 评论过滤 支持过滤新版评论区AI相关、@相关评论
- 新增:评论过滤器 按用户等级过滤

## 3.9.1

- 新增:空间页 动态列表净化
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

- **视频过滤**:根据视频时长、UP 主黑白名单、标题关键词黑白名单、BV 号筛选视频推荐

- **评论过滤**:根据用户名、评论内容关键词筛选评论
- **评论过滤**:根据用户名、关键词、评论类型、用户等级筛选评论

![](images/preview.jpg)

Expand Down
8 changes: 6 additions & 2 deletions src/components/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,18 @@ export class CheckboxItem implements IItem {
if (['complete', 'interactive'].includes(document.readyState)) {
this.option.enableFunc()?.then().catch()
} else {
document.addEventListener('DOMContentLoaded', this.option.enableFunc)
document.addEventListener('DOMContentLoaded', () => {
this.option.enableFunc && this.option.enableFunc()?.then().catch()
})
}
break
case 'document-idle':
if (document.readyState === 'complete') {
this.option.enableFunc()?.then().catch()
} else {
document.addEventListener('load', this.option.enableFunc)
window.addEventListener('load', () => {
this.option.enableFunc && this.option.enableFunc()?.then().catch()
})
}
break
default:
Expand Down
49 changes: 49 additions & 0 deletions src/filters/commentFilter/agency/agency.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import botFilterInstance from '../filters/subfilters/bot'
import callBotFilterInstance from '../filters/subfilters/callBot'
import callUserFilterInstance from '../filters/subfilters/callUser'
import contentFilterInstance from '../filters/subfilters/content'
import levelFilterInstance from '../filters/subfilters/level'
import usernameFilterInstance from '../filters/subfilters/username'

// 代理, 接收页面操作通知, 更新子过滤器的参数
Expand Down Expand Up @@ -45,6 +49,51 @@ class CommentFilterAgency {
break
}
}
notifyBot(event: string) {
switch (event) {
case 'disable':
botFilterInstance.setStatus(false)
break
case 'enable':
botFilterInstance.setStatus(true)
break
}
}
notifyCallBot(event: string) {
switch (event) {
case 'disable':
callBotFilterInstance.setStatus(false)
break
case 'enable':
callBotFilterInstance.setStatus(true)
break
}
}
notifyCallUser(event: string) {
switch (event) {
case 'disable':
callUserFilterInstance.setStatus(false)
break
case 'enable':
callUserFilterInstance.setStatus(true)
break
}
}
notifyLevel(event: string, value?: number) {
switch (event) {
case 'disable':
levelFilterInstance.setStatus(false)
break
case 'enable':
levelFilterInstance.setStatus(true)
break
case 'change':
if (typeof value === 'number') {
levelFilterInstance.setParams(value)
}
break
}
}
}

// 单例
Expand Down
48 changes: 45 additions & 3 deletions src/filters/commentFilter/filters/core.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import settings from '../../../settings'
import { error, log } from '../../../utils/logger'
import { hideEle, isEleHide, showEle } from '../../../utils/tool'
import botFilterInstance from './subfilters/bot'
import callBotFilterInstance from './subfilters/callBot'
import callUserFilterInstance from './subfilters/callUser'
import contentFilterInstance from './subfilters/content'
import levelFilterInstance from './subfilters/level'
import usernameFilterInstance from './subfilters/username'

export interface ICommentSubFilter {
isEnable: boolean
setStatus(status: boolean): void
setParams(value: string[]): void
setParams?(value: string[] | number): void
addParam?(value: string): void
check(value: string): Promise<string>
check(value: string | number): Promise<string>
}

export type CommentSelectorFunc = {
username?: (comment: HTMLElement) => string | null
content?: (comment: HTMLElement) => string | null
callUser?: (comment: HTMLElement) => string | null
level?: (comment: HTMLElement) => number | null
}

interface CommentInfo {
username?: string | undefined
content?: string | undefined
callUser?: string | undefined
level?: number | undefined
}

class CoreCommentFilter {
Expand All @@ -34,8 +42,12 @@ class CoreCommentFilter {
try {
const checkContent = contentFilterInstance.isEnable && selectorFunc.content !== undefined
const checkUsername = usernameFilterInstance.isEnable && selectorFunc.username !== undefined
const checkBot = botFilterInstance.isEnable && selectorFunc.username !== undefined
const checkCallBot = callBotFilterInstance.isEnable && selectorFunc.callUser !== undefined
const checkCallUser = callUserFilterInstance.isEnable && selectorFunc.callUser !== undefined
const checkLevel = levelFilterInstance.isEnable && selectorFunc.level !== undefined

if (!checkContent && !checkUsername) {
if (!checkContent && !checkUsername && !checkBot && !checkCallBot && !checkCallUser && !checkLevel) {
// 黑名单全部关闭时 恢复全部评论
comments.forEach((comment) => showEle(comment))
return
Expand All @@ -61,6 +73,36 @@ class CoreCommentFilter {
info.username = username
}
}
if (checkBot) {
const username = selectorFunc.username!(comment)
if (username) {
blackTasks.push(botFilterInstance.check(username))
info.username = username
}
}
if (checkCallBot) {
const callUser = selectorFunc.callUser!(comment)
if (callUser) {
blackTasks.push(callBotFilterInstance.check(callUser))
info.callUser = callUser
}
}
if (checkCallUser) {
const callUser = selectorFunc.callUser!(comment)
if (callUser) {
blackTasks.push(callUserFilterInstance.check(callUser))
info.callUser = callUser
}
}
if (checkLevel) {
const level = selectorFunc.level!(comment)
if (level) {
blackTasks.push(levelFilterInstance.check(level))
info.level = level
}
}

// debug(info)

// 执行检测
Promise.all(blackTasks)
Expand Down
72 changes: 72 additions & 0 deletions src/filters/commentFilter/filters/subfilters/bot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { error } from '../../../../utils/logger'
import { ICommentSubFilter } from '../core'

class BotFilter implements ICommentSubFilter {
isEnable = false
// 8455326 @机器工具人
// 234978716 @有趣的程序员
// 1141159409 @AI视频小助理
// 437175450 @AI视频小助理总结一下 (误伤)
// 1692825065 @AI笔记侠
// 690155730 @AI视频助手
// 689670224 @哔哩哔理点赞姬
// 3494380876859618 @课代表猫
// 1168527940 @AI课代表呀
// 439438614 @木几萌Moe
// 1358327273 @星崽丨StarZai
// 3546376048741135 @AI沈阳美食家
// 1835753760 @AI识片酱
// 9868463 @AI头脑风暴
// 358243654 @GPT_5
// 393788832 @Juice_AI
// 91394217 @AI全文总结
// 473018527 @AI视频总结
// 3546639035795567 @AI总结视频
private botSet = new Set<string>([
'机器工具人',
'有趣的程序员',
'AI视频小助理',
'AI视频小助理总结一下 (误伤)',
'AI笔记侠',
'AI视频助手',
'哔哩哔理点赞姬',
'课代表猫',
'AI课代表呀',
'木几萌Moe',
'星崽丨StarZai',
'AI沈阳美食家',
'AI识片酱',
'AI头脑风暴',
'GPT_5',
'Juice_AI',
'AI全文总结',
'AI视频总结',
'AI总结视频',
])

setStatus(status: boolean) {
this.isEnable = status
}

check(username: string): Promise<string> {
username = username.trim()
return new Promise<string>((resolve, reject) => {
try {
if (!this.isEnable || username.length === 0 || this.botSet.size === 0) {
resolve('bot resolve, disable or empty')
} else if (this.botSet.has(username)) {
reject(`bot reject, ${username} in blacklist`)
} else {
resolve('bot resolve')
}
} catch (err) {
error(err)
resolve(`bot resolve, error`)
}
})
}
}

// 单例
const botFilterInstance = new BotFilter()
export default botFilterInstance
72 changes: 72 additions & 0 deletions src/filters/commentFilter/filters/subfilters/callBot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { error } from '../../../../utils/logger'
import { ICommentSubFilter } from '../core'

class CallBotFilter implements ICommentSubFilter {
isEnable = false
// 8455326 @机器工具人
// 234978716 @有趣的程序员
// 1141159409 @AI视频小助理
// 437175450 @AI视频小助理总结一下 (误伤)
// 1692825065 @AI笔记侠
// 690155730 @AI视频助手
// 689670224 @哔哩哔理点赞姬
// 3494380876859618 @课代表猫
// 1168527940 @AI课代表呀
// 439438614 @木几萌Moe
// 1358327273 @星崽丨StarZai
// 3546376048741135 @AI沈阳美食家
// 1835753760 @AI识片酱
// 9868463 @AI头脑风暴
// 358243654 @GPT_5
// 393788832 @Juice_AI
// 91394217 @AI全文总结
// 473018527 @AI视频总结
// 3546639035795567 @AI总结视频
private botSet = new Set<string>([
'机器工具人',
'有趣的程序员',
'AI视频小助理',
'AI视频小助理总结一下 (误伤)',
'AI笔记侠',
'AI视频助手',
'哔哩哔理点赞姬',
'课代表猫',
'AI课代表呀',
'木几萌Moe',
'星崽丨StarZai',
'AI沈阳美食家',
'AI识片酱',
'AI头脑风暴',
'GPT_5',
'Juice_AI',
'AI全文总结',
'AI视频总结',
'AI总结视频',
])

setStatus(status: boolean) {
this.isEnable = status
}

check(callUser: string): Promise<string> {
callUser = callUser.trim()
return new Promise<string>((resolve, reject) => {
try {
if (!this.isEnable || callUser.length === 0 || this.botSet.size === 0) {
resolve('callBot resolve, disable or empty')
} else if (this.botSet.has(callUser)) {
reject(`callBot reject, ${callUser} in blacklist`)
} else {
resolve('callBot resolve')
}
} catch (err) {
error(err)
resolve(`callBot resolve, error`)
}
})
}
}

// 单例
const callBotFilterInstance = new CallBotFilter()
export default callBotFilterInstance
30 changes: 30 additions & 0 deletions src/filters/commentFilter/filters/subfilters/callUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { error } from '../../../../utils/logger'
import { ICommentSubFilter } from '../core'

class CallUserFilter implements ICommentSubFilter {
isEnable = false

setStatus(status: boolean) {
this.isEnable = status
}

check(callUser: string): Promise<string> {
callUser = callUser.trim()
return new Promise<string>((resolve, reject) => {
try {
if (this.isEnable && callUser.length) {
reject(`is callUser`)
} else {
resolve(`not callUser`)
}
} catch (err) {
error(err)
resolve(`callUser resolve, error`)
}
})
}
}

// 单例
const callUserFilterInstance = new CallUserFilter()
export default callUserFilterInstance
Loading