censor_bear 0.1.6 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/censor_bear/logs_controller.rb +17 -14
- data/app/controllers/censor_bear/mod_logs_controller.rb +30 -11
- data/app/models/censor_bear/log.rb +1 -0
- data/app/views/censor_bear/logs/_log.html.haml +36 -0
- data/app/views/censor_bear/logs/destroy.turbo_stream.haml +1 -0
- data/app/views/censor_bear/logs/index.html.haml +18 -0
- data/app/views/censor_bear/mod_logs/_mod_log.html.haml +45 -0
- data/app/views/censor_bear/mod_logs/destroy.turbo_stream.haml +1 -0
- data/app/views/censor_bear/mod_logs/index.html.haml +18 -0
- data/app/views/censor_bear/stop_words/_stop_word.html.haml +1 -1
- data/config/locales/censor_bear.yml +23 -1
- data/db/migrate/20211206092626_add_ip_to_censor_bear_logs.rb +6 -0
- data/db/migrate/20211208041114_add_labels_to_censor_bear_logs.rb +6 -0
- data/lib/censor_bear/censor.rb +89 -18
- data/lib/censor_bear/configuration.rb +4 -0
- data/lib/censor_bear/engine.rb +8 -0
- data/lib/censor_bear/version.rb +1 -1
- data/lib/censor_bear.rb +15 -5
- metadata +34 -14
- data/app/views/censor_bear/logs/index.html.erb +0 -42
- data/app/views/censor_bear/mod_logs/index.html.erb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0727b29e168a3f9a2fc4abb8979db9979bbfaf351e88738585bd667b3be7856a
|
4
|
+
data.tar.gz: 1d2c67774a6d20a4ad0b907c43115ea0cedfdb6410cbad16b60addc4a4a6ec2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93b0e0d47cfe57651d59aa23689c54de9003f3ef1494545834f0c4708f95fafc50abd4f68906d96a73320f5e45d6d5bb846b8f316e1d27abfcd2701b3f0c0ea8
|
7
|
+
data.tar.gz: 3c9e731f73a57075cf9ea868d75c9d707a2be4ba6666a7671d20b0306a169dc2d9e616e64670d614d4ceb72dc08719196cc97e35779ee555430f72879cf71899
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@ require_dependency "censor_bear/application_controller"
|
|
2
2
|
|
3
3
|
module CensorBear
|
4
4
|
class LogsController < ApplicationController
|
5
|
-
before_action :set_log, only: [
|
5
|
+
before_action :set_log, only: %i[show edit update destroy]
|
6
6
|
|
7
7
|
# GET /logs
|
8
8
|
def index
|
@@ -45,7 +45,11 @@ module CensorBear
|
|
45
45
|
# DELETE /logs/1
|
46
46
|
def destroy
|
47
47
|
@log.destroy
|
48
|
-
|
48
|
+
|
49
|
+
respond_to do |format|
|
50
|
+
format.turbo_stream
|
51
|
+
format.html { redirect_to logs_url, notice: 'Log was successfully destroyed.' }
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
51
55
|
def load_logs
|
@@ -56,21 +60,20 @@ module CensorBear
|
|
56
60
|
@pagy, @logs = pagy(builder)
|
57
61
|
end
|
58
62
|
|
59
|
-
|
60
63
|
private
|
61
64
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
65
|
+
# Use callbacks to share common setup or constraints between actions.
|
66
|
+
def set_log
|
67
|
+
@log = Log.find(params[:id])
|
68
|
+
end
|
66
69
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
def log_scope
|
71
|
+
Log
|
72
|
+
end
|
70
73
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
# Only allow a list of trusted parameters through.
|
75
|
+
def log_params
|
76
|
+
params.require(:log).permit(:original_content, :action, :filtered_content, :mod_words)
|
77
|
+
end
|
75
78
|
end
|
76
79
|
end
|
@@ -2,11 +2,11 @@ require_dependency "censor_bear/application_controller"
|
|
2
2
|
|
3
3
|
module CensorBear
|
4
4
|
class ModLogsController < ApplicationController
|
5
|
-
before_action :set_mod_log, only: [
|
5
|
+
before_action :set_mod_log, only: %i[show edit update destroy ignore approve ban delete]
|
6
6
|
|
7
7
|
# GET /mod_logs
|
8
8
|
def index
|
9
|
-
|
9
|
+
load_mod_logs
|
10
10
|
end
|
11
11
|
|
12
12
|
# GET /mod_logs/1
|
@@ -45,9 +45,14 @@ module CensorBear
|
|
45
45
|
# DELETE /mod_logs/1
|
46
46
|
def destroy
|
47
47
|
@mod_log.destroy
|
48
|
-
|
48
|
+
|
49
|
+
respond_to do |format|
|
50
|
+
format.turbo_stream
|
51
|
+
format.html { redirect_to mod_logs_url, notice: 'Mod log was successfully destroyed.' }
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
55
|
+
|
51
56
|
def ignore
|
52
57
|
@mod_log.suspend!
|
53
58
|
|
@@ -73,15 +78,29 @@ module CensorBear
|
|
73
78
|
redirect_to mod_logs_url, notice: 'successfully baned.'
|
74
79
|
end
|
75
80
|
|
81
|
+
def load_mod_logs
|
82
|
+
builder ||= mod_log_scope
|
83
|
+
builder = builder.where("content ilike ?", "%#{params[:q]}%") if params[:q].present?
|
84
|
+
|
85
|
+
builder = builder.order(id: :desc)
|
86
|
+
|
87
|
+
@pagy, @mod_logs = pagy(builder)
|
88
|
+
end
|
89
|
+
|
76
90
|
private
|
77
|
-
# Use callbacks to share common setup or constraints between actions.
|
78
|
-
def set_mod_log
|
79
|
-
@mod_log = ModLog.find(params[:id] || params[:mod_log_id])
|
80
|
-
end
|
81
91
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
92
|
+
# Use callbacks to share common setup or constraints between actions.
|
93
|
+
def set_mod_log
|
94
|
+
@mod_log = ModLog.find(params[:id] || params[:mod_log_id])
|
95
|
+
end
|
96
|
+
|
97
|
+
def mod_log_scope
|
98
|
+
ModLog
|
99
|
+
end
|
100
|
+
|
101
|
+
# Only allow a list of trusted parameters through.
|
102
|
+
def mod_log_params
|
103
|
+
params.require(:mod_log).permit(:record_id, :record_type, :mod_words, :user_id, :reason)
|
104
|
+
end
|
86
105
|
end
|
87
106
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
= turbo_frame_tag dom_id(log) do
|
2
|
+
%div{class: "flex flex-col"}
|
3
|
+
%div{class: "border rounded-md mb-2 p-2 flex flex-col space-y-1"}
|
4
|
+
%div{class: "flex justify-between"}
|
5
|
+
%div{class: ""}
|
6
|
+
- unless log.scenario.blank?
|
7
|
+
%span{class: "text-sm bg-blue-100 text-blue-600 py-1 px-2 rounded-lg"}= log.scenario.upcase
|
8
|
+
- unless log.stage.blank?
|
9
|
+
%span{class: "text-sm bg-pink-100 text-pink-600 py-1 px-2 rounded-lg"}=t("censor_log.stage.#{log.stage}")
|
10
|
+
- unless log.action.blank?
|
11
|
+
%span{class: "text-sm bg-yellow-100 text-yellow-600 py-1 px-2 rounded-lg"}=t("censor_log.action.#{log.action.downcase}")
|
12
|
+
- unless log.user_id.blank?
|
13
|
+
%span{class: "text-sm bg-gray-100 text-gray-600 py-1 px-2 rounded-lg font-bold"}="##{log.user_id}"
|
14
|
+
- unless log.ip.blank?
|
15
|
+
%span{class: "text-sm bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}=log.ip
|
16
|
+
- unless log.labels.blank?
|
17
|
+
- log.labels.each do |label|
|
18
|
+
%span{class: "text-sm bg-red-100 text-red-600 py-1 px-2 rounded-lg"}=t("censor_log.label.#{label}")
|
19
|
+
%span{class: "text-sm bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}= log.created_at
|
20
|
+
%div{class: "flex space-x-2 items-center"}
|
21
|
+
%span
|
22
|
+
= link_to '详情', log
|
23
|
+
%span
|
24
|
+
= button_to '删除', log, method: :delete, data: { confirm: 'Are you sure?' }, class: "text-red-600 rounded-md px-2 py-0.5"
|
25
|
+
%div{class: "flex justify-between items-center"}
|
26
|
+
%div{class: "flex flex-col"}
|
27
|
+
%div{class: ""}
|
28
|
+
%div= log.original_content
|
29
|
+
- if log.filtered_content
|
30
|
+
%div{class: "border-t"}
|
31
|
+
%div= log.filtered_content
|
32
|
+
%div{class: "text-yellow-500 font-meidum text-xl"}
|
33
|
+
- log.mod_words.each do |word|
|
34
|
+
%span [
|
35
|
+
%span= link_to word, stop_words_path(q: word), data: { turbo: false }, target: "_blank"
|
36
|
+
%span ]
|
@@ -0,0 +1 @@
|
|
1
|
+
= turbo_stream.remove(@log)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%div{class: "flex flex-col space-y-2 justify-center"}
|
2
|
+
%div{class: "flex justify-between"}
|
3
|
+
%div
|
4
|
+
= form_with(url: logs_path, method: :get, class: "flex items-center") do |f|
|
5
|
+
%div{class: "space-x-0.5"}
|
6
|
+
= f.text_field :q, value: params[:q], placeholder: "关键词", class: "border rounded-md m py-0.5 px-1"
|
7
|
+
= f.submit "检索", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
|
8
|
+
= link_to "重置", logs_path, class: "text-sm"
|
9
|
+
|
10
|
+
%div="共 #{@pagy.count} 条"
|
11
|
+
%div
|
12
|
+
- if @logs.blank?
|
13
|
+
%div{class: "flex justify-center text-gray-500 p-8 border rounded-md"} 空空如也
|
14
|
+
- else
|
15
|
+
- @logs.each do |log|
|
16
|
+
= render log
|
17
|
+
%div{class: "flex justify-center"}
|
18
|
+
= raw pagy_nav(@pagy)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
= turbo_frame_tag dom_id(mod_log) do
|
2
|
+
%div{class: "flex flex-col"}
|
3
|
+
%div{class: "border rounded-md mb-2 p-2 flex flex-col space-y-1"}
|
4
|
+
%div{class: "flex justify-between"}
|
5
|
+
%div{class: ""}
|
6
|
+
= link_to mod_log.record_path, data: { turbo: false }, target: "_blank" do
|
7
|
+
%span{class: "text-sm bg-indigo-100 text-indigo-600 py-1 px-2 rounded-lg"}="#{mod_log.record_type.upcase}##{mod_log.record_id}"
|
8
|
+
- unless mod_log.labels.blank?
|
9
|
+
- mod_log.labels.each do |label|
|
10
|
+
%span{class: "text-sm bg-red-100 text-red-600 py-1 px-2 rounded-lg"}=t("censor_log.label.#{label}")
|
11
|
+
- unless mod_log.mod_words.blank?
|
12
|
+
- mod_log.mod_words.each do |word|
|
13
|
+
%span{class: "text-sm bg-yellow-100 text-yellow-600 py-1 px-2 rounded-lg"}="##{word}"
|
14
|
+
%span{class: "text-sm bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}= mod_log.created_at
|
15
|
+
%div{class: "flex space-x-2 items-center"}
|
16
|
+
- if mod_log.reason
|
17
|
+
%span{class: "bg-red-100 text-red-600 p-1 rounded-lg"}
|
18
|
+
= mod_log.reason
|
19
|
+
%span{class: "bg-green-100 text-green-600 rounded-md p-1"}
|
20
|
+
- if mod_log.status == 0
|
21
|
+
= "待审"
|
22
|
+
- if mod_log.status == 1
|
23
|
+
= "已处理"
|
24
|
+
- if mod_log.status == 2
|
25
|
+
= "暂缓"
|
26
|
+
%span
|
27
|
+
= link_to "详情", mod_log, data: { turbo: false }, target: "_blank"
|
28
|
+
%span
|
29
|
+
= button_to '删除', mod_log, method: :delete, data: { confirm: 'Are you sure?'}, class: "text-red-600 rounded-md px-2 py-0.5"
|
30
|
+
%div{class: "flex justify-between items-center"}
|
31
|
+
%div{class: "flex flex-col"}
|
32
|
+
%div{class: "text-sm border rounded-lg border-black p-2"}
|
33
|
+
%div= mod_log.content
|
34
|
+
%div
|
35
|
+
%div{class: "flex space-x-2"}
|
36
|
+
%span{class: "text-yellow-600"}
|
37
|
+
= link_to "忽略", mod_log_ignore_path(mod_log)
|
38
|
+
%span{class: "text-green-600"}
|
39
|
+
= link_to "通过", mod_log_approve_path(mod_log)
|
40
|
+
%div
|
41
|
+
= form_with(url: mod_log_delete_path(mod_log), method: :get, class: "space-x-1 flex items-center") do |f|
|
42
|
+
= f.submit "删除", class: "rounded-md px-2 py-1 text-sm bg-red-600 text-white cursor-pointer"
|
43
|
+
= f.text_field :reason, value: mod_log.reason, placeholder: "不通过原因", class: "border rounded-md m py-0.5 px-1"
|
44
|
+
-#%span{class: "text-red-600 font-bold"}
|
45
|
+
-# = link_to "封禁用户!", mod_log_ban_path(mod_log)
|
@@ -0,0 +1 @@
|
|
1
|
+
= turbo_stream.remove(@mod_log)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%div{class: "flex flex-col space-y-2 justify-center"}
|
2
|
+
%div{class: "flex justify-between"}
|
3
|
+
%div
|
4
|
+
= form_with(url: mod_logs_path, method: :get, class: "flex items-center") do |f|
|
5
|
+
%div{class: "space-x-0.5"}
|
6
|
+
= f.text_field :q, value: params[:q], placeholder: "关键词", class: "border rounded-md m py-0.5 px-1"
|
7
|
+
= f.submit "检索", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
|
8
|
+
= link_to "重置", mod_logs_path, class: "text-sm"
|
9
|
+
|
10
|
+
%div="共 #{@pagy.count} 条"
|
11
|
+
%div
|
12
|
+
- if @mod_logs.blank?
|
13
|
+
%div{class: "flex justify-center text-gray-500 p-8 border rounded-md"} 空空如也
|
14
|
+
- else
|
15
|
+
- @mod_logs.each do |log|
|
16
|
+
= render log
|
17
|
+
%div{class: "flex justify-center"}
|
18
|
+
= raw pagy_nav(@pagy)
|
@@ -24,7 +24,7 @@
|
|
24
24
|
%div{class: "text-center"}=I18n.t("censor_log.action.#{stop_word.dialog}")
|
25
25
|
%div{class: "text-gray-500 text-xs text-center"} 私信处理
|
26
26
|
%div{class: "flex flex-col justify-center border rounded-md p-1"}
|
27
|
-
%div{class: "text-center"}=stop_word.replacement
|
27
|
+
%div{class: "text-center"}=stop_word.replacement || "**"
|
28
28
|
%div{class: "text-gray-500 text-xs text-center"} 过滤词替换
|
29
29
|
%div{class: "flex justify-end space-x-2 text-sm text-blue-600"}
|
30
30
|
%span
|
@@ -4,4 +4,26 @@ en:
|
|
4
4
|
mod: 审核
|
5
5
|
banned: 禁用
|
6
6
|
ignore: 忽略
|
7
|
-
replace: 替换
|
7
|
+
replace: 替换
|
8
|
+
block: 禁用
|
9
|
+
pass: 忽略
|
10
|
+
review: 审核
|
11
|
+
stage:
|
12
|
+
aliyun_check: 阿里云检查
|
13
|
+
tencent_check: 腾讯云检查
|
14
|
+
local_check: 本地检查
|
15
|
+
qq_regex: QQ正则检查
|
16
|
+
wechat_regex: 微信正则检查
|
17
|
+
label:
|
18
|
+
normal: 正常文本
|
19
|
+
spam: 含垃圾信息
|
20
|
+
ad: 广告
|
21
|
+
politics: 涉政
|
22
|
+
terrorism: 暴恐
|
23
|
+
abuse: 辱骂
|
24
|
+
porn: 色情
|
25
|
+
flood: 灌水
|
26
|
+
contraband: 违禁
|
27
|
+
meaningless: 无意义
|
28
|
+
harmful: 不良场景
|
29
|
+
customized: 自定义
|
data/lib/censor_bear/censor.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module CensorBear
|
2
2
|
class Result
|
3
|
-
attr_accessor :is_mod, :mod_words, :content
|
3
|
+
attr_accessor :is_mod, :mod_words, :content, :labels
|
4
4
|
|
5
|
-
def initialize(content, is_mod = false, mod_words = [])
|
5
|
+
def initialize(content, is_mod = false, mod_words = [], labels = [])
|
6
6
|
@is_mod = is_mod
|
7
7
|
@mod_words = mod_words
|
8
|
+
@labels = labels
|
8
9
|
@content = content || ''
|
9
10
|
end
|
10
11
|
end
|
@@ -13,49 +14,57 @@ module CensorBear
|
|
13
14
|
QQ_REG = /(?:[加茄qQ企鹅号码\s]{1,}|[群号]{1,}|[叩叩]{1,}|[抠抠]{1,}|[扣扣]{1,})(?:[\u4e00-\u9eff]*)(?:[:,:]?)([\d\s]{6,})/
|
14
15
|
WX_REG = /(?:[加+微++➕薇?vV威卫星♥❤姓xX信]{2,}|weixin|weix)(?:[,❤️.\s]?)(?:[\u4e00-\u9eff]?)(?:[:,:]?)([\w\s]{6,})/
|
15
16
|
|
16
|
-
def initialize(content, type = 'ugc')
|
17
|
+
def initialize(content, type = 'ugc', options = {})
|
17
18
|
@is_mod = false
|
18
19
|
@mod_words = []
|
20
|
+
@labels = []
|
19
21
|
@content = content
|
20
22
|
@type = type.to_s
|
23
|
+
@options = options
|
24
|
+
@ip = options[:ip] || nil
|
25
|
+
@user_id = options[:user_id] || nil
|
21
26
|
end
|
22
27
|
|
23
28
|
def check_text
|
24
29
|
return Result.new(@content) if @content.blank?
|
25
30
|
return Result.new(@content) unless CensorBear::StopWord::FIELDS.include?(@type)
|
26
31
|
|
32
|
+
# 正则过滤
|
27
33
|
if @content.match(QQ_REG)
|
28
|
-
CensorBear.info(@content, @type, 'BANNED', 'qq_regex')
|
34
|
+
CensorBear.info(@content, @type, 'BANNED', 'qq_regex', ip: @ip, user_id: @user_id)
|
29
35
|
raise NotPassedException
|
30
36
|
end
|
31
37
|
|
32
38
|
if @content.match(WX_REG)
|
33
|
-
CensorBear.info(@content, @type, 'BANNED', 'wx_regex')
|
39
|
+
CensorBear.info(@content, @type, 'BANNED', 'wx_regex', ip: @ip, user_id: @user_id)
|
34
40
|
raise NotPassedException
|
35
41
|
end
|
36
42
|
|
43
|
+
# 本地自定义词库粗查
|
37
44
|
local_check
|
45
|
+
# 第三方云端复查
|
46
|
+
aliyun_check unless @is_mod
|
38
47
|
|
39
48
|
# 用户相关类型直接禁止创建
|
40
49
|
raise NotPassedException if @is_mod && %w[username signature dialog nickname].include?(@type)
|
41
50
|
|
42
|
-
Result.new(@content, @is_mod, @mod_words.uniq)
|
51
|
+
Result.new(@content, @is_mod, @mod_words.uniq, @labels.uniq)
|
43
52
|
end
|
44
53
|
|
45
54
|
# default type = :ugc
|
46
55
|
def check_search
|
47
|
-
|
56
|
+
flag = false
|
48
57
|
stop_words = CensorBear::StopWord.where("#{@type} != 'IGNORE'")
|
49
58
|
stop_words.each do |word|
|
50
59
|
finder = Regexp.new(Regexp.escape(word.key))
|
51
60
|
action = word.send(@type.to_sym).upcase
|
52
61
|
if finder.match(@content)
|
53
|
-
|
54
|
-
CensorBear.info(@content, @type, action, 'check_search', mod_words: [word.key])
|
62
|
+
flag = true
|
63
|
+
CensorBear.info(@content, @type, action, 'check_search', mod_words: [word.key], ip: @ip, user_id: @user_id)
|
55
64
|
break
|
56
65
|
end
|
57
66
|
end
|
58
|
-
|
67
|
+
flag
|
59
68
|
end
|
60
69
|
|
61
70
|
def local_check
|
@@ -65,41 +74,103 @@ module CensorBear
|
|
65
74
|
finder = Regexp.new(Regexp.escape(word.key))
|
66
75
|
action = word.send(@type.to_sym).upcase
|
67
76
|
next unless finder.match(@content)
|
77
|
+
|
68
78
|
@mod_words.push(word.key)
|
69
79
|
case action
|
70
80
|
when 'REPLACE'
|
71
|
-
|
81
|
+
replacement = word.replacement.blank? ? '**' : word.replacement
|
82
|
+
@content = @content.gsub(finder, replacement)
|
72
83
|
CensorBear.info(
|
73
84
|
original_content, @type, action, 'local_check',
|
74
85
|
filtered_content: @content,
|
75
|
-
mod_words: [word.key]
|
86
|
+
mod_words: [word.key],
|
87
|
+
ip: @ip, user_id: @user_id
|
76
88
|
)
|
77
89
|
when 'MOD'
|
78
90
|
@is_mod = true
|
79
91
|
CensorBear.info(
|
80
92
|
original_content, @type, action, 'local_check',
|
81
93
|
filtered_content: nil,
|
82
|
-
mod_words: [word.key]
|
94
|
+
mod_words: [word.key],
|
95
|
+
ip: @ip, user_id: @user_id
|
83
96
|
)
|
84
97
|
when 'BANNED'
|
85
|
-
@is_mod = true
|
86
98
|
# 禁止的直接抛出异常
|
87
99
|
CensorBear.info(
|
88
100
|
original_content, @type, action, 'local_check',
|
89
101
|
filtered_content: nil,
|
90
|
-
mod_words: [word.key]
|
102
|
+
mod_words: [word.key],
|
103
|
+
ip: @ip, user_id: @user_id
|
91
104
|
)
|
92
105
|
raise NotPassedException
|
93
106
|
end
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
97
|
-
def
|
110
|
+
def aliyun_check
|
111
|
+
response = AliyunGreen::Text.scan(@content)
|
112
|
+
d = response['data'].first
|
113
|
+
r = d['results'].first
|
114
|
+
action = r['suggestion']
|
115
|
+
rate = r['rate']
|
116
|
+
@mod_words = concat_words(r['details'])
|
117
|
+
@labels = concat_labels(r['details'])
|
118
|
+
if action == 'block' && rate >= 70 && %w[politics terrorism abuse].include?(r['label'])
|
119
|
+
CensorBear.info(
|
120
|
+
d['content'], @type, action, 'aliyun_check',
|
121
|
+
filtered_content: d['filteredContent'],
|
122
|
+
mod_words: @mod_words,
|
123
|
+
labels: @labels,
|
124
|
+
ip: @ip, user_id: @user_id
|
125
|
+
)
|
126
|
+
raise NotPassedException
|
127
|
+
elsif action == 'block'
|
128
|
+
@is_mod = true
|
129
|
+
CensorBear.info(
|
130
|
+
d['content'], @type, action, 'aliyun_check',
|
131
|
+
filtered_content: d['filteredContent'],
|
132
|
+
mod_words: @mod_words,
|
133
|
+
labels: @labels,
|
134
|
+
ip: @ip, user_id: @user_id
|
135
|
+
)
|
136
|
+
elsif action == 'review'
|
137
|
+
@is_mod = true
|
138
|
+
CensorBear.info(
|
139
|
+
d['content'], @type, action, 'aliyun_check',
|
140
|
+
filtered_content: d['filteredContent'],
|
141
|
+
mod_words: @mod_words,
|
142
|
+
labels: @labels,
|
143
|
+
ip: @ip, user_id: @user_id
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
98
147
|
|
99
148
|
private
|
100
149
|
|
101
|
-
def
|
150
|
+
def concat_labels(data)
|
151
|
+
return [] if data.blank?
|
152
|
+
labels = []
|
153
|
+
data.map do |d|
|
154
|
+
next if d['label'].blank?
|
155
|
+
|
156
|
+
labels.push(d['label'])
|
157
|
+
end
|
158
|
+
labels
|
159
|
+
end
|
160
|
+
|
161
|
+
def concat_words(data)
|
162
|
+
return [] if data.blank?
|
163
|
+
words = []
|
164
|
+
data.each do |d|
|
165
|
+
next if d['contexts'].blank?
|
166
|
+
|
167
|
+
d['contexts'].each do |c|
|
168
|
+
words.push(c['context'])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
words
|
172
|
+
end
|
102
173
|
|
103
|
-
def
|
174
|
+
def tencent_check; end
|
104
175
|
end
|
105
176
|
end
|
@@ -13,5 +13,9 @@ module CensorBear
|
|
13
13
|
attr_accessor :import_file_path
|
14
14
|
attr_accessor :format_from_file_path
|
15
15
|
attr_accessor :format_dest_file_path
|
16
|
+
|
17
|
+
attr_accessor :aliyun_green_access_key_id
|
18
|
+
attr_accessor :aliyun_green_access_key_secret
|
19
|
+
attr_accessor :aliyun_green_enable_internal
|
16
20
|
end
|
17
21
|
end
|
data/lib/censor_bear/engine.rb
CHANGED
@@ -7,5 +7,13 @@ module CensorBear
|
|
7
7
|
initializer "censor_bear.assets.precompile" do |app|
|
8
8
|
app.config.assets.precompile += %w( censor_bear/application.css )
|
9
9
|
end
|
10
|
+
|
11
|
+
config.after_initialize do
|
12
|
+
AliyunGreen.configure do |config|
|
13
|
+
config.access_key_id = CensorBear.config.aliyun_green_access_key_id
|
14
|
+
config.access_key_secret = CensorBear.config.aliyun_green_access_key_secret
|
15
|
+
config.enable_internal = CensorBear.config.aliyun_green_enable_internal
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
data/lib/censor_bear/version.rb
CHANGED
data/lib/censor_bear.rb
CHANGED
@@ -5,6 +5,7 @@ require 'censor_bear/configuration'
|
|
5
5
|
|
6
6
|
require 'hamlit'
|
7
7
|
require 'pagy'
|
8
|
+
require 'aliyun_green'
|
8
9
|
|
9
10
|
module CensorBear
|
10
11
|
class NotPassedException < StandardError; end
|
@@ -20,6 +21,9 @@ module CensorBear
|
|
20
21
|
@config.import_file_path = "#{Rails.root}/tmp/dest_sensitives.txt"
|
21
22
|
@config.format_from_file_path = "#{Rails.root}/tmp/from_sensitives.txt"
|
22
23
|
@config.format_dest_file_path = "#{Rails.root}/tmp/dest_sensitives.txt"
|
24
|
+
@config.aliyun_green_access_key_id = ''
|
25
|
+
@config.aliyun_green_access_key_secret = ''
|
26
|
+
@config.aliyun_green_enable_internal = false
|
23
27
|
@config
|
24
28
|
end
|
25
29
|
|
@@ -27,17 +31,20 @@ module CensorBear
|
|
27
31
|
yield(config)
|
28
32
|
end
|
29
33
|
|
30
|
-
def check_text(content, type = 'ugc')
|
31
|
-
Censor.new(content, type).check_text
|
34
|
+
def check_text(content, type = 'ugc', options = {})
|
35
|
+
Censor.new(content, type, options).check_text
|
32
36
|
end
|
33
37
|
|
34
|
-
def check_search(content)
|
35
|
-
Censor.new(content,
|
38
|
+
def check_search(content, options = {})
|
39
|
+
Censor.new(content, 'ugc', options).check_search
|
36
40
|
end
|
37
41
|
|
38
42
|
def info(content, scenario, action, stage, options = {})
|
39
43
|
filtered_content = options[:filtered_content] || nil
|
40
44
|
mod_words = options[:mod_words] || []
|
45
|
+
labels = options[:labels] || []
|
46
|
+
ip = options[:ip] || nil
|
47
|
+
user_id = options[:user_id] || nil
|
41
48
|
|
42
49
|
CensorBear::Log.create(
|
43
50
|
original_content: content,
|
@@ -45,7 +52,10 @@ module CensorBear
|
|
45
52
|
action: action,
|
46
53
|
stage: stage,
|
47
54
|
filtered_content: filtered_content,
|
48
|
-
mod_words: mod_words
|
55
|
+
mod_words: mod_words,
|
56
|
+
labels: labels,
|
57
|
+
ip: ip,
|
58
|
+
user_id: user_id,
|
49
59
|
)
|
50
60
|
end
|
51
61
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: censor_bear
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 42up
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 6.0.4.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: aliyun_green
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.1.1
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.1.1
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: hamlit
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,33 +73,33 @@ dependencies:
|
|
59
73
|
- !ruby/object:Gem::Version
|
60
74
|
version: '2.0'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
76
|
+
name: pagy
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
|
-
- - "
|
79
|
+
- - "~>"
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
81
|
+
version: '5.6'
|
68
82
|
type: :runtime
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
|
-
- - "
|
86
|
+
- - "~>"
|
73
87
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
88
|
+
version: '5.6'
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
90
|
+
name: turbo-rails
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
78
92
|
requirements:
|
79
|
-
- - "
|
93
|
+
- - ">="
|
80
94
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
95
|
+
version: '0'
|
82
96
|
type: :runtime
|
83
97
|
prerelease: false
|
84
98
|
version_requirements: !ruby/object:Gem::Requirement
|
85
99
|
requirements:
|
86
|
-
- - "
|
100
|
+
- - ">="
|
87
101
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
102
|
+
version: '0'
|
89
103
|
description: Description of CensorBear.
|
90
104
|
email:
|
91
105
|
- foobar@v2up.com
|
@@ -118,13 +132,17 @@ files:
|
|
118
132
|
- app/models/censor_bear/mod_log.rb
|
119
133
|
- app/models/censor_bear/stop_word.rb
|
120
134
|
- app/views/censor_bear/logs/_form.html.erb
|
135
|
+
- app/views/censor_bear/logs/_log.html.haml
|
136
|
+
- app/views/censor_bear/logs/destroy.turbo_stream.haml
|
121
137
|
- app/views/censor_bear/logs/edit.html.erb
|
122
|
-
- app/views/censor_bear/logs/index.html.
|
138
|
+
- app/views/censor_bear/logs/index.html.haml
|
123
139
|
- app/views/censor_bear/logs/new.html.erb
|
124
140
|
- app/views/censor_bear/logs/show.html.erb
|
125
141
|
- app/views/censor_bear/mod_logs/_form.html.erb
|
142
|
+
- app/views/censor_bear/mod_logs/_mod_log.html.haml
|
143
|
+
- app/views/censor_bear/mod_logs/destroy.turbo_stream.haml
|
126
144
|
- app/views/censor_bear/mod_logs/edit.html.erb
|
127
|
-
- app/views/censor_bear/mod_logs/index.html.
|
145
|
+
- app/views/censor_bear/mod_logs/index.html.haml
|
128
146
|
- app/views/censor_bear/mod_logs/new.html.erb
|
129
147
|
- app/views/censor_bear/mod_logs/show.html.erb
|
130
148
|
- app/views/censor_bear/stop_words/_form.html.haml
|
@@ -142,6 +160,8 @@ files:
|
|
142
160
|
- db/migrate/20211126133758_create_censor_bear_stop_words.rb
|
143
161
|
- db/migrate/20211129093508_create_censor_bear_logs.rb
|
144
162
|
- db/migrate/20211129110218_create_censor_bear_mod_logs.rb
|
163
|
+
- db/migrate/20211206092626_add_ip_to_censor_bear_logs.rb
|
164
|
+
- db/migrate/20211208041114_add_labels_to_censor_bear_logs.rb
|
145
165
|
- lib/censor_bear.rb
|
146
166
|
- lib/censor_bear/censor.rb
|
147
167
|
- lib/censor_bear/configuration.rb
|
@@ -1,42 +0,0 @@
|
|
1
|
-
<p id="notice"><%= notice %></p>
|
2
|
-
|
3
|
-
<h1>Logs</h1>
|
4
|
-
|
5
|
-
<table>
|
6
|
-
<thead>
|
7
|
-
<tr>
|
8
|
-
<th>Orginal content</th>
|
9
|
-
<th>Action</th>
|
10
|
-
<th>Filtered content</th>
|
11
|
-
<th>Mod words</th>
|
12
|
-
<th colspan="3"></th>
|
13
|
-
</tr>
|
14
|
-
</thead>
|
15
|
-
|
16
|
-
<tbody>
|
17
|
-
<% @logs.each do |log| %>
|
18
|
-
<tr>
|
19
|
-
<td><%= log.original_content %></td>
|
20
|
-
<td><%= log.scenario %></td>
|
21
|
-
<td><%= log.stage %></td>
|
22
|
-
<td><%= log.action %></td>
|
23
|
-
<td><%= log.filtered_content %></td>
|
24
|
-
<td><%= log.mod_words %></td>
|
25
|
-
<td><%= link_to 'Show', log %></td>
|
26
|
-
<td><%= link_to 'Edit', edit_log_path(log) %></td>
|
27
|
-
<td><%= button_to 'Destroy', log, method: :delete, data: { confirm: 'Are you sure?', turbo: false } %></td>
|
28
|
-
</tr>
|
29
|
-
<% end %>
|
30
|
-
</tbody>
|
31
|
-
</table>
|
32
|
-
|
33
|
-
|
34
|
-
<br>
|
35
|
-
|
36
|
-
<%= raw pagy_nav(@pagy) %>
|
37
|
-
|
38
|
-
<br>
|
39
|
-
|
40
|
-
<%= link_to 'New Log', new_log_path %>
|
41
|
-
|
42
|
-
|
@@ -1,44 +0,0 @@
|
|
1
|
-
<p id="notice"><%= notice %></p>
|
2
|
-
|
3
|
-
<h1>Mod Logs</h1>
|
4
|
-
|
5
|
-
<table>
|
6
|
-
<thead>
|
7
|
-
<tr>
|
8
|
-
<th>Record</th>
|
9
|
-
<th>Record type</th>
|
10
|
-
<th>Mod words</th>
|
11
|
-
<th>User</th>
|
12
|
-
<th colspan="3"></th>
|
13
|
-
</tr>
|
14
|
-
</thead>
|
15
|
-
|
16
|
-
<tbody>
|
17
|
-
<% @mod_logs.each do |mod_log| %>
|
18
|
-
<tr>
|
19
|
-
<td><%= mod_log.record_id %></td>
|
20
|
-
<td><%= mod_log.record_type %></td>
|
21
|
-
<td><%= mod_log.mod_words %></td>
|
22
|
-
<td><%= mod_log.user_id %></td>
|
23
|
-
<td><%= link_to 'Show', mod_log %></td>
|
24
|
-
<td><%= link_to 'Show', mod_log %></td>
|
25
|
-
<td><%= link_to 'Edit', edit_mod_log_path(mod_log) %></td>
|
26
|
-
<td><%= link_to 'Destroy', mod_log, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
27
|
-
<td><%= link_to "查看详情", mod_log.record_path %></td>
|
28
|
-
<td><%= link_to "忽略内容", mod_log_ignore_path(mod_log) %></td>
|
29
|
-
<td><%= link_to "通过内容", mod_log_approve_path(mod_log) %></td>
|
30
|
-
<td><%= link_to "封禁用户", mod_log_ban_path(mod_log) %></td>
|
31
|
-
<td>
|
32
|
-
<%= form_with(url: mod_log_delete_path(mod_log), method: :get, class: "flex items-center") do |f| %>
|
33
|
-
<%= f.text_field :reason, value: mod_log.reason, placeholder: "原因", class: "border rounded-md m py-0.5 px-1" %>
|
34
|
-
<td><%= f.submit "删除内容", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer" %></td>
|
35
|
-
<% end %>
|
36
|
-
</td>
|
37
|
-
</tr>
|
38
|
-
<% end %>
|
39
|
-
</tbody>
|
40
|
-
</table>
|
41
|
-
|
42
|
-
<br>
|
43
|
-
|
44
|
-
<%= link_to 'New Mod Log', new_mod_log_path %>
|