Skip to content

Commit

Permalink
なんとか完成、これから動作確認
Browse files Browse the repository at this point in the history
  • Loading branch information
kmycode committed Feb 22, 2024
1 parent 608d5f8 commit 37c67c7
Show file tree
Hide file tree
Showing 29 changed files with 237 additions and 60 deletions.
3 changes: 2 additions & 1 deletion app/controllers/admin/ng_rules_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ def resource_params
:account_include_local, :status_spoiler_text, :status_text, :status_tag,
:status_sensitive_state, :status_cw_state, :status_media_state, :status_poll_state,
:status_quote_state, :status_reply_state, :status_media_threshold, :status_poll_threshold,
:status_mention_threshold, :status_mention_allow_follower, :rule_violation_threshold_per_account,
:status_mention_threshold, :status_allow_follower_mention, :rule_violation_threshold_per_account,
:reaction_allow_follower, :emoji_reaction_name, :emoji_reaction_origin_domain,
:status_reference_threshold, :account_action, :status_action, :reaction_action,
:account_allow_followed_by_local,
status_visibility: [], status_searchability: [], reaction_type: [])
end

Expand Down
2 changes: 1 addition & 1 deletion app/lib/activitypub/activity/announce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def perform

return reject_payload! if original_status.nil? || !announceable?(original_status)
return if requested_through_relay?
return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'reblog', recipient: original_status.account
return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'reblog', recipient: original_status.account, target_status: original_status

@status = Status.find_by(account: @account, reblog: original_status)

Expand Down
6 changes: 4 additions & 2 deletions app/lib/activitypub/activity/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ def valid_status?

def valid_status_for_ng_rule?
check_invalid_status_for_ng_rule! @account,
uri: @status_parser.uri,
reaction_type: 'create',
uri: @params[:uri],
url: @params[:url],
spoiler_text: @params[:spoiler_text],
text: @params[:text],
tag_names: @tags.map(&:name),
Expand Down Expand Up @@ -373,7 +375,7 @@ def process_poll
def poll_vote?
return false if replied_to_status.nil? || replied_to_status.preloadable_poll.nil? || !replied_to_status.local? || !replied_to_status.preloadable_poll.options.include?(@object['name'])

return true unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'vote', recipient: replied_to_status.account
return true unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'vote', recipient: replied_to_status.account, target_status: replied_to_status

poll_vote! unless replied_to_status.preloadable_poll.expired?

Expand Down
4 changes: 2 additions & 2 deletions app/lib/activitypub/activity/like.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def reject_favourite?

def process_favourite
return if @account.favourited?(@original_status)
return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'favourite', recipient: @original_status.account
return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'favourite', recipient: @original_status.account, target_status: @original_status

favourite = @original_status.favourites.create!(account: @account, uri: @json['id'])

Expand All @@ -45,7 +45,7 @@ def process_emoji_reaction
return if emoji.nil?
end

return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'emoji_reaction', emoji_reaction_name: emoji&.shortcode || shortcode, emoji_reaction_origin_domain: emoji&.domain, recipient: @original_status.account
return unless check_invalid_reaction_for_ng_rule! @account, uri: @json['id'], reaction_type: 'emoji_reaction', emoji_reaction_name: emoji&.shortcode || shortcode, emoji_reaction_origin_domain: emoji&.domain, recipient: @original_status.account, target_status: @original_status

reaction = nil

Expand Down
17 changes: 17 additions & 0 deletions app/lib/vacuum/ng_histories_vacuum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Vacuum::NgHistoriesVacuum
include Redisable

HISTORY_LIFE_DURATION = 7.days.freeze

def perform
vacuum_histories!
end

private

def vacuum_histories!
NgRuleHistory.where('created_at < ?', HISTORY_LIFE_DURATION.ago).in_batches.destroy_all
end
end
35 changes: 30 additions & 5 deletions app/models/admin/ng_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def initialize(ng_rule, account, **options)

def account_match?
return false if @account.local? && !@ng_rule.account_include_local
return false if !@account.local? && @ng_rule.account_allow_followed_by_local && followed_by_local_accounts?

if @account.local?
return false unless @ng_rule.account_include_local
Expand All @@ -27,7 +28,7 @@ def account_match?
end

def status_match?
return false if @ng_rule.status_mention_allow_follower && @options[:mention_to_following]
return false if @ng_rule.status_allow_follower_mention && @options[:mention_to_following]

has_media = @options[:media_count].is_a?(Integer) && @options[:media_count].positive?
has_poll = @options[:poll_count].is_a?(Integer) && @options[:poll_count].positive?
Expand Down Expand Up @@ -68,27 +69,44 @@ def reaction_match?
def check_account_or_record!
return true unless account_match?

record!('account', @account.uri) if !@account.local? || @ng_rule.record_history_also_local
record!('account', @account.uri, 'account_create') if !@account.local? || @ng_rule.record_history_also_local

!violation?
end

def check_status_or_record!
return true unless account_match? && status_match?

record!('status', @options[:uri], text: "#{@options[:spoiler_text]}\n\n#{@options[:text]}") if (!@options.key?(:visibility) || %i(public public_unlisted login unlsited).include?(@options[:visibility].to_sym)) && (!@account.local? || @ng_rule.record_history_also_local)
text = [@options[:spoiler_text], @options[:text]].compact_blank.join("\n\n")
data = {
media_count: @options[:media_count],
poll_count: @options[:poll_count],
url: @options[:url],
}
record!('status', @options[:uri], "status_#{@options[:reaction_type]}", text: text, data: data) if loggable_visibility? && (!@account.local? || @ng_rule.record_history_also_local)

!violation?
end

def check_reaction_or_record!
return true unless account_match? && reaction_match?

record!('reaction', @options[:uri]) if !@account.local? || @ng_rule.record_history_also_local
text = @options[:target_status].present? ? [@options[:target_status].spoiler_text, @options[:target_status].text].compact_blank.join("\n\n") : nil
data = {
url: @options[:target_status].present? ? @options[:target_status].url : nil,
}
record!('reaction', @options[:uri], "reaction_#{@options[:reaction_type]}", text: text, data: data) if loggable_visibility? && (!@account.local? || @ng_rule.record_history_also_local)

!violation?
end

def loggable_visibility?
visibility = @options[:target_status]&.visibility || @options[:visibility]
return true unless visibility

%i(public public_unlisted login unlsited).include?(visibility.to_sym)
end

def account_action
@ng_rule.account_action.to_sym
end
Expand All @@ -107,6 +125,10 @@ def self.extract_test!(custom_ng_words)

private

def followed_by_local_accounts?
Follow.exists?(account: Account.local, target_account: @account)
end

def already_did_count
return @already_did_count if defined?(@already_did_count)

Expand All @@ -123,14 +145,17 @@ def violation?
already_did_count >= limit
end

def record!(reason, uri, **options)
def record!(reason, uri, reason_action, **options)
opts = options.merge({
ng_rule: @ng_rule,
account: @account,
local: @account.local?,
reason: reason,
reason_action: reason_action,
uri: uri,
})
opts = opts.merge({ skip_count: already_did_count, skip: true }) unless violation?

NgRuleHistory.create!(**opts)
end

Expand Down
3 changes: 2 additions & 1 deletion app/models/ng_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# account_avatar_state :integer default("optional"), not null
# account_header_state :integer default("optional"), not null
# account_include_local :boolean default(TRUE), not null
# account_allow_followed_by_local :boolean default(FALSE), not null
# status_spoiler_text :string default(""), not null
# status_text :string default(""), not null
# status_tag :string default(""), not null
Expand All @@ -32,7 +33,7 @@
# status_media_threshold :integer default(-1), not null
# status_poll_threshold :integer default(-1), not null
# status_mention_threshold :integer default(-1), not null
# status_mention_allow_follower :boolean default(TRUE), not null
# status_allow_follower_mention :boolean default(TRUE), not null
# status_reference_threshold :integer default(-1), not null
# reaction_type :string default([]), not null, is an Array
# reaction_allow_follower :boolean default(TRUE), not null
Expand Down
35 changes: 25 additions & 10 deletions app/models/ng_rule_history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,33 @@
#
# Table name: ng_rule_histories
#
# id :bigint(8) not null, primary key
# ng_rule_id :bigint(8) not null
# account_id :bigint(8) not null
# text :string
# uri :string
# reason :string not null
# skip :boolean default(FALSE), not null
# skip_count :integer
# created_at :datetime not null
# updated_at :datetime not null
# id :bigint(8) not null, primary key
# ng_rule_id :bigint(8) not null
# account_id :bigint(8)
# text :string
# uri :string
# reason :integer not null
# reason_action :integer not null
# skip :boolean default(FALSE), not null
# skip_count :integer
# local :boolean default(TRUE), not null
# data :jsonb
# created_at :datetime not null
# updated_at :datetime not null
#
class NgRuleHistory < ApplicationRecord
enum :reason, { account: 0, status: 1, reaction: 2 }, prefix: :reason
enum :reason_action, {
account_create: 0,
status_create: 10,
status_edit: 11,
reaction_favourite: 20,
reaction_emoji_reaction: 21,
reaction_follow: 22,
reaction_reblog: 23,
reaction_vote: 24,
}, prefix: :reason_action

belongs_to :ng_rule
belongs_to :account
end
4 changes: 3 additions & 1 deletion app/services/activitypub/process_status_update_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ def validate_status_mentions!

def valid_status_for_ng_rule?
check_invalid_status_for_ng_rule! @account,
uri: @status_parser.uri,
reaction_type: 'edit',
uri: @status.uri,
url: @status_parser.url || @status.url,
spoiler_text: @status.spoiler_text,
text: @status.text,
tag_names: @raw_tags,
Expand Down
2 changes: 1 addition & 1 deletion app/services/emoji_react_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def call(account, status, name)
shortcode, domain = name.split('@')
domain = nil if TagManager.instance.local_domain?(domain)

raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'emoji_reaction', emoji_reaction_name: shortcode, emoji_reaction_origin_domain: domain, recipient: status.account
raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'emoji_reaction', emoji_reaction_name: shortcode, emoji_reaction_origin_domain: domain, recipient: status.account, target_status: status

with_redis_lock("emoji_reaction:#{status.id}") do
custom_emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain)
Expand Down
2 changes: 1 addition & 1 deletion app/services/favourite_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class FavouriteService < BaseService
def call(account, status)
authorize_with account, status, :favourite?

raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'favourite', recipient: status.account
raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'favourite', recipient: status.account, target_status: status

favourite = Favourite.find_by(account: account, status: status)

Expand Down
1 change: 1 addition & 0 deletions app/services/post_status_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def validate_status_mentions!

def validate_status_ng_rules!
result = check_invalid_status_for_ng_rule! @account,
reaction_type: 'create',
spoiler_text: @options[:spoiler_text] || '',
text: @text,
tag_names: Extractor.extract_hashtags(@text) || [],
Expand Down
2 changes: 1 addition & 1 deletion app/services/reblog_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def call(account, reblogged_status, options = {})

authorize_with account, reblogged_status, :reblog?

raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'reblog', recipient: reblogged_status.account
raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! account, reaction_type: 'reblog', recipient: reblogged_status.account, target_status: reblogged_status

reblog = account.statuses.find_by(reblog: reblogged_status)

Expand Down
1 change: 1 addition & 0 deletions app/services/update_status_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def validate_status_mentions!

def validate_status_ng_rules!
result = check_invalid_status_for_ng_rule! @status.account,
reaction_type: 'edit',
spoiler_text: @options.key?(:spoiler_text) ? (@options[:spoiler_text] || '') : @status.spoiler_text,
text: text,
tag_names: Extractor.extract_hashtags(text) || [],
Expand Down
2 changes: 1 addition & 1 deletion app/services/vote_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def call(account, poll, choices)
@choices = choices
@votes = []

raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! @account, reaction_type: 'vote', recipient: @poll.status.account
raise Mastodon::ValidationError, I18n.t('statuses.violate_rules') unless check_invalid_reaction_for_ng_rule! @account, reaction_type: 'vote', recipient: @poll.status.account, target_status: @poll.status

already_voted = true

Expand Down
25 changes: 23 additions & 2 deletions app/views/admin/ng_rule_histories/_history.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,32 @@
-# = f.check_box :history_ids, { multiple: true, include_hidden: false }, history.id
.batch-table__row__content
.status__content><
= html_aware_format(history.text, false)
= html_aware_format(history.text, history.local)

.detailed-status__meta
= t("admin.ng_rule_histories.reason_actions.#{history.reason_action}")
- if history.skip
·
= t('admin.ng_rule_histories.skipped', count: history.skip_count)
- if history.data.present?
- if history.data['media_count'].present? && history.data['media_count'].positive?
·
= t('admin.ng_rule_histories.data.media_count', count: history.data['media_count'])
- if history.data['poll_count'].present? && history.data['poll_count'].positive?
·
= t('admin.ng_rule_histories.data.poll_count', count: history.data['poll_count'])

%br/

- if history.account.present?
= link_to t('admin.ng_rule_histories.moderate_account'), admin_account_path(history.account.id)
·

%time.formatted{ datetime: history.created_at.iso8601, title: l(history.created_at) }= l(history.created_at)

- if history.uri.present?
·
= history.uri
- if history.data.present? && history.data['url'].present?
= link_to history.uri, history.data['url'] || history.uri, target: '_blank', rel: 'noopener'
- else
= link_to history.uri, target: '_blank', rel: 'noopener'
2 changes: 1 addition & 1 deletion app/views/admin/ng_rule_histories/show.html.haml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- content_for :page_title do
= t('admin.ng_rule_histories.title')
= t('admin.ng_rule_histories.title', title: @ng_rule.title)

.filters
.back-link
Expand Down
10 changes: 5 additions & 5 deletions app/views/admin/ng_rules/_ng_rule.html.haml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
.filters-list__item{ class: [ng_rule.expired? && 'expired'] }
= link_to edit_admin_ng_rule_path(ng_rule), class: 'filters-list__item__title' do
%h3= ng_rule.title.presence || t('ng_rules.index.empty_title')
%h3= ng_rule.title.presence || t('admin.ng_rules.index.empty_title')

- if ng_rule.expires?
.expiration{ title: t('ng_rules.index.expires_on', date: l(ng_rule.expires_at)) }
.expiration{ title: t('filters.index.expires_on', date: l(ng_rule.expires_at)) }
- if ng_rule.expired?
= t('invites.expired')
- else
= t('ng_rules.index.expires_in', distance: distance_of_time_in_words_to_now(ng_rule.expires_at))
= t('filters.index.expires_in', distance: distance_of_time_in_words_to_now(ng_rule.expires_at))

%div
= table_link_to 'pencil', t('ng_rules.edit.title'), edit_admin_ng_rule_path(ng_rule)
= table_link_to 'times', t('ng_rules.index.delete'), admin_ng_rule_path(ng_rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
= table_link_to 'pencil', t('admin.ng_rules.index.edit.title'), edit_admin_ng_rule_path(ng_rule)
= table_link_to 'times', t('admin.ng_rules.index.delete'), admin_ng_rule_path(ng_rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
Loading

0 comments on commit 37c67c7

Please sign in to comment.