censor_bear 0.1.14 → 0.1.15

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8f5e80bfe3be4dc22e9c8fc14932f6c830a87efc0ee15d5588bd258f0311e0e
4
- data.tar.gz: bc47827fb4f09f2cd875d20db1c4593168917709b0174d0780237c503c156e5e
3
+ metadata.gz: 775cd9c238b951f9b9d5ce8564ae76e3e4b5d38fb3e9b71dc599d6a75bc04f5e
4
+ data.tar.gz: f8daa1001d2682697143aec92e6098d1e291d3c4d8cb7c9d28f60455fee7e6b4
5
5
  SHA512:
6
- metadata.gz: fc58e6353da8c5697b92f2c4857a7dcaa948a6e03c367d14aed8960b015c0809cc33094628efc1983f07865f270ae646bbf05c942dda7a58b425db54f3434f00
7
- data.tar.gz: d080b530b575ece289451d58079a40e3a85ad0f7721e8707cac299d141ea066047f5b36c13a9a5a7a133edf0e70707d28b85ea622ea4fe20f5309cc5be132462
6
+ metadata.gz: 3bd8ea39fb05994a01083fdaf574501657bf085238a1c9a24b883bddadf374a8a441f910a95594f7a42081d981a2800b9b2b02c9b3cc578e200536faa52ed4b8
7
+ data.tar.gz: 6ee79015b14bf37b4f070e041c91738d906bb3d1f8c39b215a94ccf6fbe89ccc0816a9d919e1436ee3689b3bb62bd9be2df1a025afbe1090e09ee9bf0be1022d
data/README.md CHANGED
@@ -50,10 +50,12 @@ rails censor_bear:install:migrations
50
50
 
51
51
  ## 🦆 Methods
52
52
  ```ruby
53
- censor_delete # 删除内容
53
+ censor_remove # 删除内容
54
+ censor_cancel # 撤销删除
54
55
  censor_approve # 通过审核
55
56
  censor_show_path # 详情路由
56
57
  censor_ban_user # 封禁用户
58
+
57
59
  ```
58
60
 
59
61
  ## Exceptions
@@ -63,6 +65,22 @@ censor_ban_user # 封禁用户
63
65
  class NotPassedException < StandardError; end
64
66
  ```
65
67
 
68
+ ## 初始化配置
69
+ 详细配置项可在`lib/censor_bear/configuration.rb`中查看。
70
+
71
+ ```ruby
72
+ CensorBear.configure do |config|
73
+ config.user_class = 'User'
74
+ config.user_name_method = 'nickname'
75
+
76
+ config.aliyun_green_access_key_id = 'access key id'
77
+ config.aliyun_green_access_key_secret = 'access key secret'
78
+ config.aliyun_green_enable_internal = false
79
+
80
+ config.main_app_root_path_method = 'root_path'
81
+ end
82
+ ```
83
+
66
84
  ## 注意事项
67
85
  1. 为 MOD 时,表示需要人工审核,需要被审查对象(UGC内容)支持`is_approved`字段(默认为`true`),此时内容自己能看到,别人暂时看不到,需审核通过后可见。
68
86
  2. 被审查对象可以通过软删实现,隐藏(目的是防止错判,撤销),删除的内容对自己和别人都是不可见的。
@@ -1,28 +1,23 @@
1
- require_dependency "censor_bear/application_controller"
1
+ require_dependency 'censor_bear/application_controller'
2
2
 
3
3
  module CensorBear
4
4
  class ModLogsController < ApplicationController
5
- before_action :set_mod_log, only: %i[show edit update destroy ignore approve ban delete]
5
+ before_action :set_mod_log, only: %i[show edit update destroy suspend ban pass undo reject]
6
6
 
7
- # GET /mod_logs
8
7
  def index
9
8
  load_mod_logs
10
9
  end
11
10
 
12
- # GET /mod_logs/1
13
11
  def show
14
12
  end
15
13
 
16
- # GET /mod_logs/new
17
14
  def new
18
15
  @mod_log = ModLog.new
19
16
  end
20
17
 
21
- # GET /mod_logs/1/edit
22
18
  def edit
23
19
  end
24
20
 
25
- # POST /mod_logs
26
21
  def create
27
22
  @mod_log = ModLog.new(mod_log_params)
28
23
 
@@ -33,7 +28,6 @@ module CensorBear
33
28
  end
34
29
  end
35
30
 
36
- # PATCH/PUT /mod_logs/1
37
31
  def update
38
32
  if @mod_log.update(mod_log_params)
39
33
  redirect_to @mod_log, notice: 'Mod log was successfully updated.'
@@ -42,7 +36,6 @@ module CensorBear
42
36
  end
43
37
  end
44
38
 
45
- # DELETE /mod_logs/1
46
39
  def destroy
47
40
  @mod_log.destroy
48
41
 
@@ -53,23 +46,29 @@ module CensorBear
53
46
  end
54
47
 
55
48
 
56
- def ignore
49
+ def suspend
57
50
  @mod_log.suspend!
58
51
 
59
52
  redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
60
53
  end
61
54
 
62
- def delete
63
- # TODO: 判断参数不能为空
64
- @mod_log.delete(params[:reason])
55
+ def pass
56
+ @mod_log.approve
65
57
 
66
- redirect_to mod_logs_url, notice: 'Mod log was successfully deleted.'
58
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
67
59
  end
68
60
 
69
- def approve
70
- @mod_log.approve
61
+ def undo
62
+ # TODO: 判断状态,确定是撤销通过呢还是撤销删除
63
+ @mod_log.cancel
64
+
65
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
66
+ end
67
+
68
+ def reject
69
+ @mod_log.remove(params[:reason])
71
70
 
72
- redirect_to mod_logs_url, notice: 'Mod log was successfully approved.'
71
+ redirect_to mod_logs_url, notice: 'Mod log was successfully ignored.'
73
72
  end
74
73
 
75
74
  def ban
@@ -80,8 +79,11 @@ module CensorBear
80
79
 
81
80
  def load_mod_logs
82
81
  builder ||= mod_log_scope.includes(:record)
83
- builder = builder.where("content ilike ?", "%#{params[:q]}%") if params[:q].present?
84
-
82
+ builder = builder.where('content ilike ?', "%#{params[:q]}%") if params[:q].present?
83
+ if params[:filter] != 'all'
84
+ builder = builder.pending
85
+ builder = builder.unscope(where: :aasm_state).where(aasm_state: params[:state]) if params[:state].present?
86
+ end
85
87
  builder = builder.order(id: :desc)
86
88
 
87
89
  @pagy, @mod_logs = pagy(builder)
@@ -89,7 +91,6 @@ module CensorBear
89
91
 
90
92
  private
91
93
 
92
- # Use callbacks to share common setup or constraints between actions.
93
94
  def set_mod_log
94
95
  @mod_log = ModLog.find(params[:id] || params[:mod_log_id])
95
96
  end
@@ -98,7 +99,6 @@ module CensorBear
98
99
  ModLog
99
100
  end
100
101
 
101
- # Only allow a list of trusted parameters through.
102
102
  def mod_log_params
103
103
  params.require(:mod_log).permit(:record_id, :record_type, :mod_words, :user_id, :reason)
104
104
  end
@@ -1,6 +1,8 @@
1
1
  module CensorBear
2
2
  class ModLog < ApplicationRecord
3
- REASONS = %w(无 广告/SPAM 恶意灌水 违规内容 文不对题 重复发布 其它)
3
+ include AASM
4
+
5
+ REASONS = %w(无 广告/SPAM 恶意灌水 违规内容 文不对题 重复发布 其它).freeze
4
6
  belongs_to :record, polymorphic: true, required: false
5
7
 
6
8
  def record_path
@@ -9,14 +11,14 @@ module CensorBear
9
11
  record.censor_show_path
10
12
  end
11
13
 
12
- def delete(reason)
14
+ def remove(reason)
13
15
  return if record.blank?
14
16
  return if record.discarded?
15
17
  # ugc内容需要开软删,便于撤销&查看统计,可以定时删除统计并删除软删内容,类似回收站机制
16
- raise NoMethodError.new("undefined censor_delete for record") unless record.respond_to?(:censor_delete)
18
+ raise NoMethodError, 'undefined censor_remove for record' unless record.respond_to?(:censor_remove)
17
19
 
18
- ret = record.censor_delete
19
- handled!(reason) if ret
20
+ ret = record.censor_remove
21
+ reject!(reason) if ret
20
22
  end
21
23
 
22
24
  def approve
@@ -24,7 +26,15 @@ module CensorBear
24
26
  raise NoMethodError unless record.respond_to?(:censor_approve)
25
27
 
26
28
  ret = record.censor_approve
27
- handled! if ret
29
+ pass! if ret
30
+ end
31
+
32
+ def cancel
33
+ return if record.blank?
34
+ raise NoMethodError unless record.respond_to?(:censor_cancel)
35
+
36
+ ret = record.censor_cancel
37
+ undo! if ret
28
38
  end
29
39
 
30
40
  def ban_user
@@ -32,23 +42,36 @@ module CensorBear
32
42
  raise NoMethodError unless record.respond_to?(:censor_ban_user)
33
43
 
34
44
  ret = record.censor_ban_user
35
- delete if ret
45
+ reject!('已被封禁该用户') if ret
36
46
  end
37
47
 
38
- scope :pending, -> { where(status: 0) }
39
- scope :handled, -> { where(status: 1) }
40
- scope :suspended, -> { where(status: 2) }
48
+ aasm do
49
+ state :pending, initial: true
50
+ state :rejected, :passed, :suspended
51
+
52
+ event :reject do
53
+ transitions from: %i[pending suspended], to: :rejected, after: Proc.new {|*args| set_reason(*args) }
54
+ end
55
+
56
+ event :pass do
57
+ transitions from: %i[pending suspended], to: :passed
58
+ end
59
+
60
+ event :suspend do
61
+ transitions from: :pending, to: :suspended, after: :unset_reason
62
+ end
41
63
 
42
- def handled!(reason = nil)
43
- update_columns(status: 1, reason: reason)
64
+ event :undo do
65
+ transitions from: %i[passed rejected], to: :pending, after: :unset_reason
66
+ end
44
67
  end
45
68
 
46
- def pend!
47
- update_columns(status: 0)
69
+ def unset_reason
70
+ update_columns(reason: nil)
48
71
  end
49
72
 
50
- def suspend!
51
- update_columns(status: 2)
73
+ def set_reason(reason)
74
+ update_columns(reason: reason)
52
75
  end
53
76
  end
54
77
  end
@@ -2,44 +2,49 @@
2
2
  %div{class: "flex flex-col"}
3
3
  %div{class: "border rounded-md mb-2 p-2 flex flex-col space-y-1"}
4
4
  %div{class: "flex justify-between"}
5
- %div{class: ""}
5
+ %div{class: "text-sm"}
6
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"}
7
+ %span{class: "bg-indigo-100 text-indigo-600 py-1 px-2 rounded-lg"}="#{mod_log.record_type.upcase}##{mod_log.record_id}"
8
+ %span{class: "bg-yellow-100 text-yellow-600 rounded-md p-1"}=t("censor_log.aasm_state.#{mod_log.aasm_state}")
9
+ %div{class: "flex space-x-2 items-center text-sm"}
16
10
  - if mod_log.reason
17
11
  %span{class: "bg-red-100 text-red-600 p-1 rounded-lg"}
18
12
  = 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)
13
+ %span{class: "bg-gray-100 text-gray-600 py-1 px-2 rounded-lg"}= mod_log.created_at
14
+ - if current_user.admin?
15
+ = button_to '删除', mod_log, method: :delete, data: { confirm: 'Are you sure?'}, class: "bg-red-600 text-white rounded-md px-2 py-0.5 cursor-pointer"
16
+ %div{class: "flex justify-between items-center py-2 w-full"}
17
+ %div{class: "flex flex-col rounded-lg bg-gray-50 p-3 text-sm space-y-4 w-full"}
18
+ -unless mod_log.record
19
+ %h3{class: "text-2xl text-red-600"} 对应条目已被永久删除,当前审核请求已无效,请删除
20
+ - else
21
+ %div
22
+ %span{class: "border border-pink-600 text-pink-600 rounded-lg text-xs p-0.5"}=mod_log.record.is_private ? "隐私" : "公开"
23
+ %span{class: "border border-blue-600 text-blue-600 rounded-lg text-xs p-0.5"}=mod_log.record.is_approved ? "审核通过" : "审核中..."
24
+ - if mod_log.record.discarded?
25
+ %div{class: "text-gray-900 leading-relaxed"}
26
+ %del= mod_log.record.content
27
+ - else
28
+ %div{class: "text-gray-900 leading-relaxed"}= mod_log.record.content
29
+ %div
30
+ - mod_log.record.pictures.each do |pic|
31
+ = image_tag pic.full_url, class: "w-16 rounded-md"
32
+ %div
33
+ - unless mod_log.labels.blank?
34
+ - mod_log.labels.each do |label|
35
+ %span{class: "text-xs bg-gray-200 text-gray-600 py-0.5 px-1 rounded-lg"}=t("censor_log.label.#{label}")
36
+ - unless mod_log.mod_words.blank?
37
+ - mod_log.mod_words.each do |word|
38
+ %span{class: "text-sm bg-gray-100 text-gray-600 py-0.5 px-1 rounded-lg"}="##{word}"
39
+ %div{class: "flex space-x-2 items-center justify-end"}
40
+ - if mod_log.may_suspend?
41
+ = link_to "忽略", mod_log_suspend_path(mod_log), class: "text-yellow-600 cursor-pointer"
42
+ - if mod_log.may_pass?
43
+ = link_to "通过", mod_log_pass_path(mod_log), class: "text-green-600 cursor-pointer"
44
+ - if mod_log.may_undo?
45
+ = link_to "撤销", mod_log_undo_path(mod_log), class: "text-red-600 cursor-pointer"
46
+ - if mod_log.may_reject?
47
+ = form_with(url: mod_log_reject_path(mod_log), method: :get, class: "space-x-1 flex items-center") do |f|
48
+ = f.submit "拒绝", class: "text-red-600 bg-transparent cursor-pointer"
49
+ = f.text_field :reason, value: mod_log.reason, placeholder: "不通过原因", class: "border rounded-md m py-0.5 px-1 text-sm"
50
+
@@ -6,8 +6,18 @@
6
6
  = f.text_field :q, value: params[:q], placeholder: "关键词", class: "border rounded-md m py-0.5 px-1"
7
7
  = f.submit "检索", class: "rounded-md px-2 py-1 text-sm bg-black text-white cursor-pointer"
8
8
  = link_to "重置", mod_logs_path, class: "text-sm"
9
-
10
- %div{class: "text-sm text-gray-600"}="共 #{@pagy.count} 条"
9
+ %div{class: "flex items-center space-x-2"}
10
+ %div{class: "text-sm text-gray-600"}="共 #{@pagy.count} 条"
11
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:filter] == "all" ? 'font-bold' : ''}"}
12
+ = link_to "全部", request.params.merge(filter: "all", state: "")
13
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state].blank? && params[:filter].blank? ? 'font-bold' : ''}"}
14
+ = link_to "待处理", request.params.merge(state: "", filter: "")
15
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'rejected' ? 'font-bold' : ''}"}
16
+ = link_to "被驳回", request.params.merge(state: "rejected", filter: "")
17
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'passed' ? 'font-bold' : ''}"}
18
+ = link_to "通过", request.params.merge(state: "passed", filter: "")
19
+ %div{class: "bg-gray-200 rounded-full px-3 py-1 text-xs #{params[:state] == 'suspended' ? 'font-bold' : ''}"}
20
+ = link_to "暂缓处理", request.params.merge(state: "suspended", filter: "")
11
21
  %div
12
22
  - if @mod_logs.blank?
13
23
  %div{class: "flex justify-center text-gray-500 p-8 border rounded-md"} 空空如也
@@ -8,6 +8,10 @@ en:
8
8
  block: 禁用
9
9
  pass: 忽略
10
10
  review: 审核
11
+ aasm_state:
12
+ pending: 待审
13
+ handled: 已处理
14
+ suspended: 暂缓处理
11
15
  stage:
12
16
  check_search: 搜索检查
13
17
  aliyun_check: 阿里云检查
data/config/routes.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  CensorBear::Engine.routes.draw do
2
2
  resources :mod_logs do
3
- get :ignore
4
- get :approve
5
- get :delete
3
+ get :suspend
4
+ get :reject
5
+ get :pass
6
+ get :undo
6
7
  get :ban
7
8
  end
8
9
  resources :logs
@@ -0,0 +1,5 @@
1
+ class AddAasmStateToCensorBearModLogs < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :censor_bear_mod_logs, :aasm_state, :string
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module CensorBear
2
- VERSION = '0.1.14'.freeze
2
+ VERSION = '0.1.15'.freeze
3
3
  end
data/lib/censor_bear.rb CHANGED
@@ -3,6 +3,7 @@ require 'censor_bear/engine'
3
3
  require 'censor_bear/censor'
4
4
  require 'censor_bear/configuration'
5
5
 
6
+ require 'aasm'
6
7
  require 'hamlit'
7
8
  require 'pagy'
8
9
  require 'aliyun_green'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: censor_bear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - 42up
@@ -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: aasm
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: aliyun_green
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +183,7 @@ files:
169
183
  - db/migrate/20211206092626_add_ip_to_censor_bear_logs.rb
170
184
  - db/migrate/20211208041114_add_labels_to_censor_bear_logs.rb
171
185
  - db/migrate/20211209093050_add_response_to_censor_bear_logs.rb
186
+ - db/migrate/20211209113710_add_aasm_state_to_censor_bear_mod_logs.rb
172
187
  - lib/censor_bear.rb
173
188
  - lib/censor_bear/censor.rb
174
189
  - lib/censor_bear/configuration.rb