diff options
author | Thibaut Girka <thib@sitedethib.com> | 2018-07-09 07:05:29 +0200 |
---|---|---|
committer | Thibaut Girka <thib@sitedethib.com> | 2018-07-09 07:13:59 +0200 |
commit | d392020da6ff4511a2925b327de23933f374bea3 (patch) | |
tree | e86a590276a96ef72d5ed49f79998e7680969cb6 /app/models | |
parent | c699b2d141d7aa910bd81ae5fe881ecec7039395 (diff) | |
parent | 1ca4e51eb38de6de81cedf3ddcdaa626f1d1c569 (diff) |
Merge branch 'master' into glitch-soc/tentative-merge
Conflicts: README.md app/controllers/statuses_controller.rb app/lib/feed_manager.rb config/navigation.rb spec/lib/feed_manager_spec.rb Conflicts were resolved by taking both versions for each change. This means the two filter systems (glitch-soc's keyword mutes and tootsuite's custom filters) are in place, which will be changed in a follow-up commit.
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/account.rb | 30 | ||||
-rw-r--r-- | app/models/concerns/account_interactions.rb | 13 | ||||
-rw-r--r-- | app/models/concerns/attachmentable.rb | 2 | ||||
-rw-r--r-- | app/models/concerns/expireable.rb | 24 | ||||
-rw-r--r-- | app/models/custom_filter.rb | 56 | ||||
-rw-r--r-- | app/models/form/admin_settings.rb | 2 | ||||
-rw-r--r-- | app/models/invite.rb | 18 |
7 files changed, 100 insertions, 45 deletions
diff --git a/app/models/account.rb b/app/models/account.rb index 5099e4953..4abcd438a 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -102,6 +102,7 @@ class Account < ApplicationRecord has_many :targeted_reports, class_name: 'Report', foreign_key: :target_account_id has_many :report_notes, dependent: :destroy + has_many :custom_filters, inverse_of: :account, dependent: :destroy # Moderation notes has_many :account_moderation_notes, dependent: :destroy @@ -129,6 +130,7 @@ class Account < ApplicationRecord scope :matches_username, ->(value) { where(arel_table[:username].matches("#{value}%")) } scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) } scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) } + scope :searchable, -> { where(suspended: false).where(moved_to_account_id: nil) } delegate :email, :unconfirmed_email, @@ -311,34 +313,6 @@ class Account < ApplicationRecord DeliveryFailureTracker.filter(urls) end - def triadic_closures(account, limit: 5, offset: 0) - sql = <<-SQL.squish - WITH first_degree AS ( - SELECT target_account_id - FROM follows - WHERE account_id = :account_id - ) - SELECT accounts.* - FROM follows - INNER JOIN accounts ON follows.target_account_id = accounts.id - WHERE - account_id IN (SELECT * FROM first_degree) - AND target_account_id NOT IN (SELECT * FROM first_degree) - AND target_account_id NOT IN (:excluded_account_ids) - AND accounts.suspended = false - GROUP BY target_account_id, accounts.id - ORDER BY count(account_id) DESC - OFFSET :offset - LIMIT :limit - SQL - - excluded_account_ids = account.excluded_from_timeline_account_ids + [account.id] - - find_by_sql( - [sql, { account_id: account.id, excluded_account_ids: excluded_account_ids, limit: limit, offset: offset }] - ) - end - def search_for(terms, limit = 10) textsearch, query = generate_query_for_search(terms) diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index d067415fd..cacee54e0 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -89,10 +89,13 @@ module AccountInteractions .find_or_create_by!(target_account: other_account) rel.update!(show_reblogs: reblogs) + remove_potential_friendship(other_account) + rel end def block!(other_account, uri: nil) + remove_potential_friendship(other_account) block_relationships.create_with(uri: uri) .find_or_create_by!(target_account: other_account) end @@ -100,10 +103,13 @@ module AccountInteractions def mute!(other_account, notifications: nil) notifications = true if notifications.nil? mute = mute_relationships.create_with(hide_notifications: notifications).find_or_create_by!(target_account: other_account) + remove_potential_friendship(other_account) + # When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't. if mute.hide_notifications? != notifications mute.update!(hide_notifications: notifications) end + mute end @@ -198,4 +204,11 @@ module AccountInteractions lists.joins(account: :user) .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) end + + private + + def remove_potential_friendship(other_account, mutual = false) + PotentialFriendshipTracker.remove(id, other_account.id) + PotentialFriendshipTracker.remove(other_account.id, id) if mutual + end end diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 44bdfa39a..de4cf8775 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -28,7 +28,7 @@ module Attachmentable self.class.attachment_definitions.each_key do |attachment_name| attachment = send(attachment_name) - next if attachment.blank? || !attachment.content_type.match?(/image.*/) || attachment.queued_for_write[:original].blank? + next if attachment.blank? || !/image.*/.match?(attachment.content_type) || attachment.queued_for_write[:original].blank? width, height = FastImage.size(attachment.queued_for_write[:original].path) diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb new file mode 100644 index 000000000..444ccdfdb --- /dev/null +++ b/app/models/concerns/expireable.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Expireable + extend ActiveSupport::Concern + + included do + scope :expired, -> { where.not(expires_at: nil).where('expires_at < ?', Time.now.utc) } + + attr_reader :expires_in + + def expires_in=(interval) + self.expires_at = interval.to_i.seconds.from_now unless interval.blank? + @expires_in = interval + end + + def expire! + touch(:expires_at) + end + + def expired? + !expires_at.nil? && expires_at < Time.now.utc + end + end +end diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb new file mode 100644 index 000000000..342207a55 --- /dev/null +++ b/app/models/custom_filter.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true +# == Schema Information +# +# Table name: custom_filters +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) +# expires_at :datetime +# phrase :text default(""), not null +# context :string default([]), not null, is an Array +# whole_word :boolean default(TRUE), not null +# irreversible :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class CustomFilter < ApplicationRecord + VALID_CONTEXTS = %w( + home + notifications + public + thread + ).freeze + + include Expireable + + belongs_to :account + + validates :phrase, :context, presence: true + validate :context_must_be_valid + validate :irreversible_must_be_within_context + + scope :active_irreversible, -> { where(irreversible: true).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) } + + before_validation :clean_up_contexts + after_commit :remove_cache + + private + + def clean_up_contexts + self.context = Array(context).map(&:strip).map(&:presence).compact + end + + def remove_cache + Rails.cache.delete("filters:#{account_id}") + Redis.current.publish("timeline:#{account_id}", Oj.dump(event: :filters_changed)) + end + + def context_must_be_valid + errors.add(:context, I18n.t('filters.errors.invalid_context')) if context.empty? || context.any? { |c| !VALID_CONTEXTS.include?(c) } + end + + def irreversible_must_be_within_context + errors.add(:irreversible, I18n.t('filters.errors.invalid_irreversible')) if irreversible? && !context.include?('home') && !context.include?('notifications') + end +end diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 32922e7f1..723480bdd 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -36,6 +36,8 @@ class Form::AdminSettings :peers_api_enabled=, :show_known_fediverse_at_about_page, :show_known_fediverse_at_about_page=, + :preview_sensitive_media, + :preview_sensitive_media=, to: Setting ) end diff --git a/app/models/invite.rb b/app/models/invite.rb index d0cc427c4..fe2322462 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -15,33 +15,19 @@ # class Invite < ApplicationRecord + include Expireable + belongs_to :user has_many :users, inverse_of: :invite scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) } - scope :expired, -> { where.not(expires_at: nil).where('expires_at < ?', Time.now.utc) } before_validation :set_code - attr_reader :expires_in - - def expires_in=(interval) - self.expires_at = interval.to_i.seconds.from_now unless interval.blank? - @expires_in = interval - end - def valid_for_use? (max_uses.nil? || uses < max_uses) && !expired? end - def expire! - touch(:expires_at) - end - - def expired? - !expires_at.nil? && expires_at < Time.now.utc - end - private def set_code |