about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-10-30 18:15:28 +0100
committerClaire <claire.github-309c@sitedethib.com>2022-10-30 18:15:28 +0100
commiteee36267d627ae08898d2b3301f56ce729055e82 (patch)
treedae581a9867b8dcdd2c3ab0154794a1ff10ad98e /app/models
parent26ff48ee48a5c03a2a4b0bd03fd322529e6bd960 (diff)
parentac9fb0d654440ce1179bab4071941450aa994d2c (diff)
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts:
- `app/javascript/mastodon/locales/ja.json`:
  Upstream change too close to a glitch-soc-specific string.
  The glitch-soc-specific string should not have been in this file, so it
  has been moved to `app/javascript/flavours/glitch/locales/ja.js`.
- `app/javascript/packs/public.js`:
  Upstream refactored a part, that as usual is split and duplicated in various
  pack files. Updated those pack files accordingly.
- `app/views/layouts/application.html.haml`:
  Upstream fixed custom.css path in a different way than we did, went with
  upstream's change.
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb20
-rw-r--r--app/models/admin/account_action.rb9
-rw-r--r--app/models/featured_tag.rb8
-rw-r--r--app/models/form/redirect.rb2
4 files changed, 29 insertions, 10 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index 79939ad9e..8ff4e5951 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -443,7 +443,12 @@ class Account < ApplicationRecord
 
   class << self
     DISALLOWED_TSQUERY_CHARACTERS = /['?\\:‘’]/.freeze
-    TEXTSEARCH = "(setweight(to_tsvector('simple', accounts.display_name), 'A') || setweight(to_tsvector('simple', accounts.username), 'B') || setweight(to_tsvector('simple', coalesce(accounts.domain, '')), 'C'))"
+    TEXTSEARCH = "(setweight(to_tsvector('simple', accounts.display_name), 'A') || setweight(to_tsvector('simple', accounts.username), 'A') || setweight(to_tsvector('simple', coalesce(accounts.domain, '')), 'C'))"
+
+    REPUTATION_SCORE_FUNCTION = '(greatest(0, coalesce(s.followers_count, 0)) / (greatest(0, coalesce(s.following_count, 0)) + 1.0))'
+    FOLLOWERS_SCORE_FUNCTION  = 'log(greatest(0, coalesce(s.followers_count, 0)) + 2)'
+    TIME_DISTANCE_FUNCTION    = '(case when s.last_status_at is null then 0 else exp(-1.0 * ((greatest(0, abs(extract(DAY FROM age(s.last_status_at))) - 30.0)^2) / (2.0 * ((-1.0 * 30^2) / (2.0 * ln(0.3)))))) end)'
+    BOOST                     = "((#{REPUTATION_SCORE_FUNCTION} + #{FOLLOWERS_SCORE_FUNCTION} + #{TIME_DISTANCE_FUNCTION}) / 3.0)"
 
     def readonly_attributes
       super - %w(statuses_count following_count followers_count)
@@ -460,9 +465,10 @@ class Account < ApplicationRecord
       sql = <<-SQL.squish
         SELECT
           accounts.*,
-          ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
+          #{BOOST} * ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
         FROM accounts
         LEFT JOIN users ON accounts.id = users.account_id
+        LEFT JOIN account_stats AS s ON accounts.id = s.account_id
         WHERE to_tsquery('simple', :tsquery) @@ #{TEXTSEARCH}
           AND accounts.suspended_at IS NULL
           AND accounts.moved_to_account_id IS NULL
@@ -524,14 +530,15 @@ class Account < ApplicationRecord
           )
           SELECT
             accounts.*,
-            (count(f.id) + 1) * ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
+            (count(f.id) + 1) * #{BOOST} * ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
           FROM accounts
           LEFT OUTER JOIN follows AS f ON (accounts.id = f.account_id AND f.target_account_id = :id)
+          LEFT JOIN account_stats AS s ON accounts.id = s.account_id
           WHERE accounts.id IN (SELECT * FROM first_degree)
             AND to_tsquery('simple', :tsquery) @@ #{TEXTSEARCH}
             AND accounts.suspended_at IS NULL
             AND accounts.moved_to_account_id IS NULL
-          GROUP BY accounts.id
+          GROUP BY accounts.id, s.id
           ORDER BY rank DESC
           LIMIT :limit OFFSET :offset
         SQL
@@ -539,15 +546,16 @@ class Account < ApplicationRecord
         <<-SQL.squish
           SELECT
             accounts.*,
-            (count(f.id) + 1) * ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
+            (count(f.id) + 1) * #{BOOST} * ts_rank_cd(#{TEXTSEARCH}, to_tsquery('simple', :tsquery), 32) AS rank
           FROM accounts
           LEFT OUTER JOIN follows AS f ON (accounts.id = f.account_id AND f.target_account_id = :id) OR (accounts.id = f.target_account_id AND f.account_id = :id)
           LEFT JOIN users ON accounts.id = users.account_id
+          LEFT JOIN account_stats AS s ON accounts.id = s.account_id
           WHERE to_tsquery('simple', :tsquery) @@ #{TEXTSEARCH}
             AND accounts.suspended_at IS NULL
             AND accounts.moved_to_account_id IS NULL
             AND (accounts.domain IS NOT NULL OR (users.approved = TRUE AND users.confirmed_at IS NOT NULL))
-          GROUP BY accounts.id
+          GROUP BY accounts.id, s.id
           ORDER BY rank DESC
           LIMIT :limit OFFSET :offset
         SQL
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index aed3bc0c7..bce0d6e17 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -25,6 +25,8 @@ class Admin::AccountAction
   alias send_email_notification? send_email_notification
   alias include_statuses? include_statuses
 
+  validates :type, :target_account, :current_account, presence: true
+
   def initialize(attributes = {})
     @send_email_notification = true
     @include_statuses        = true
@@ -41,13 +43,15 @@ class Admin::AccountAction
   end
 
   def save!
+    raise ActiveRecord::RecordInvalid, self unless valid?
+
     ApplicationRecord.transaction do
       process_action!
       process_strike!
+      process_reports!
     end
 
     process_email!
-    process_reports!
     process_queue!
   end
 
@@ -106,9 +110,8 @@ class Admin::AccountAction
     # Otherwise, we will mark all unresolved reports about
     # the account as resolved.
 
-    reports.each { |report| authorize(report, :update?) }
-
     reports.each do |report|
+      authorize(report, :update?)
       log_action(:resolve, report)
       report.resolve!(current_account)
     end
diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb
index 3f5cddce6..d4ed74302 100644
--- a/app/models/featured_tag.rb
+++ b/app/models/featured_tag.rb
@@ -19,6 +19,8 @@ class FeaturedTag < ApplicationRecord
   validate :validate_tag_name, on: :create
   validate :validate_featured_tags_limit, on: :create
 
+  before_validation :strip_name
+
   before_create :set_tag
   before_create :reset_data
 
@@ -48,6 +50,12 @@ class FeaturedTag < ApplicationRecord
 
   private
 
+  def strip_name
+    return unless defined?(@name)
+
+    @name = @name&.strip&.gsub(/\A#/, '')
+  end
+
   def set_tag
     self.tag = Tag.find_or_create_by_names(@name)&.first
   end
diff --git a/app/models/form/redirect.rb b/app/models/form/redirect.rb
index 19ee9faed..795fdd057 100644
--- a/app/models/form/redirect.rb
+++ b/app/models/form/redirect.rb
@@ -31,7 +31,7 @@ class Form::Redirect
   private
 
   def set_target_account
-    @target_account = ResolveAccountService.new.call(acct)
+    @target_account = ResolveAccountService.new.call(acct, skip_cache: true)
   rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error
     # Validation will take care of it
   end