about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2019-01-10 19:12:10 +0100
committerThibaut Girka <thib@sitedethib.com>2019-01-10 21:00:30 +0100
commita2a64ecd3e3551707412c47f0d16e484dea25632 (patch)
treebc4e0b8e0ca2a2735f527bff8bd73421c0ff72dd /app/models
parentfb0c906c717f2b21bb63610742a357850142b522 (diff)
parent70801b850c78d7879182eeba4eae509af42fafeb (diff)
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts:
- .eslintrc.yml
  Removed, as upstream removed it.
- app/controllers/admin/statuses_controller.rb
  Minor code cleanup when porting one of our features.
- app/models/account.rb
  Note length validation has changed upstream.
  We now use upstream's validation (dropped legacy glitch-soc
  account metadata stuff) but with configurable limit.
- app/services/post_status_service.rb
  Upstream has added support for scheduled toots, refactoring
  the code a bit. Adapted our changes to this refactoring.
- app/views/stream_entries/_detailed_status.html.haml
  Not a real conflict, changes too close.
- app/views/stream_entries/_simple_status.html.haml
  Not a real conflict, changes too close.
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb18
-rw-r--r--app/models/concerns/account_associations.rb1
-rw-r--r--app/models/concerns/account_finder_concern.rb4
-rw-r--r--app/models/instance.rb21
-rw-r--r--app/models/instance_filter.rb17
-rw-r--r--app/models/media_attachment.rb38
-rw-r--r--app/models/relay.rb2
-rw-r--r--app/models/scheduled_status.rb39
8 files changed, 86 insertions, 54 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index 67d9a583e..1ee63c738 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -79,7 +79,7 @@ class Account < ApplicationRecord
   validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates :display_name, length: { maximum: MAX_DISPLAY_NAME_LENGTH }, if: -> { local? && will_save_change_to_display_name? }
-  validate :note_length_does_not_exceed_length_limit, if: -> { local? && will_save_change_to_note? }
+  validates :note, note_length: { maximum: MAX_NOTE_LENGTH }, if: -> { local? && will_save_change_to_note? }
   validates :fields, length: { maximum: MAX_FIELDS }, if: -> { local? && will_save_change_to_fields? }
 
   scope :remote, -> { where.not(domain: nil) }
@@ -488,22 +488,6 @@ class Account < ApplicationRecord
     self.public_key  = keypair.public_key.to_pem
   end
 
-  YAML_START = "---\r\n"
-  YAML_END = "\r\n...\r\n"
-
-  def note_length_does_not_exceed_length_limit
-    note_without_metadata = note
-    if note.start_with? YAML_START
-      idx = note.index YAML_END
-      unless idx.nil?
-        note_without_metadata = note[(idx + YAML_END.length) .. -1]
-      end
-    end
-    if note_without_metadata.mb_chars.grapheme_length > MAX_NOTE_LENGTH
-      errors.add(:note, "can't be longer than 500 graphemes")
-    end
-  end
-
   def normalize_domain
     return if local?
 
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index de7f3d525..4e730451a 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -15,6 +15,7 @@ module AccountAssociations
     has_many :mentions, inverse_of: :account, dependent: :destroy
     has_many :notifications, inverse_of: :account, dependent: :destroy
     has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
+    has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
 
     # Pinned statuses
     has_many :status_pins, inverse_of: :account, dependent: :destroy
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
index 6b7237e89..7e3bbde09 100644
--- a/app/models/concerns/account_finder_concern.rb
+++ b/app/models/concerns/account_finder_concern.rb
@@ -12,6 +12,10 @@ module AccountFinderConcern
       find_remote(username, domain) || raise(ActiveRecord::RecordNotFound)
     end
 
+    def representative
+      find_local(Setting.site_contact_username.gsub(/\A@/, '')) || Account.local.find_by(suspended: false)
+    end
+
     def find_local(username)
       find_remote(username, nil)
     end
diff --git a/app/models/instance.rb b/app/models/instance.rb
index 6d5c9c2ab..7448d465c 100644
--- a/app/models/instance.rb
+++ b/app/models/instance.rb
@@ -3,10 +3,23 @@
 class Instance
   include ActiveModel::Model
 
-  attr_accessor :domain, :accounts_count
+  attr_accessor :domain, :accounts_count, :domain_block
 
-  def initialize(account)
-    @domain = account.domain
-    @accounts_count = account.accounts_count
+  def initialize(resource)
+    @domain         = resource.domain
+    @accounts_count = resource.accounts_count
+    @domain_block   = resource.is_a?(DomainBlock) ? resource : DomainBlock.find_by(domain: domain)
+  end
+
+  def cached_sample_accounts
+    Rails.cache.fetch("#{cache_key}/sample_accounts", expires_in: 12.hours) { Account.where(domain: domain).searchable.joins(:account_stat).popular.limit(3) }
+  end
+
+  def to_param
+    domain
+  end
+
+  def cache_key
+    domain
   end
 end
diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb
index 5073cf1fa..3483d8cd6 100644
--- a/app/models/instance_filter.rb
+++ b/app/models/instance_filter.rb
@@ -8,21 +8,10 @@ class InstanceFilter
   end
 
   def results
-    scope = Account.remote.by_domain_accounts
-    params.each do |key, value|
-      scope.merge!(scope_for(key, value)) if value.present?
-    end
-    scope
-  end
-
-  private
-
-  def scope_for(key, value)
-    case key.to_s
-    when 'domain_name'
-      Account.matches_domain(value)
+    if params[:limited].present?
+      DomainBlock.order(id: :desc)
     else
-      raise "Unknown filter: #{key}"
+      Account.remote.by_domain_accounts
     end
   end
 end
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index a034b55fd..601b14223 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -3,20 +3,21 @@
 #
 # Table name: media_attachments
 #
-#  id                :bigint(8)        not null, primary key
-#  status_id         :bigint(8)
-#  file_file_name    :string
-#  file_content_type :string
-#  file_file_size    :integer
-#  file_updated_at   :datetime
-#  remote_url        :string           default(""), not null
-#  created_at        :datetime         not null
-#  updated_at        :datetime         not null
-#  shortcode         :string
-#  type              :integer          default("image"), not null
-#  file_meta         :json
-#  account_id        :bigint(8)
-#  description       :text
+#  id                  :bigint(8)        not null, primary key
+#  status_id           :bigint(8)
+#  file_file_name      :string
+#  file_content_type   :string
+#  file_file_size      :integer
+#  file_updated_at     :datetime
+#  remote_url          :string           default(""), not null
+#  created_at          :datetime         not null
+#  updated_at          :datetime         not null
+#  shortcode           :string
+#  type                :integer          default("image"), not null
+#  file_meta           :json
+#  account_id          :bigint(8)
+#  description         :text
+#  scheduled_status_id :bigint(8)
 #
 
 class MediaAttachment < ApplicationRecord
@@ -94,8 +95,9 @@ class MediaAttachment < ApplicationRecord
   IMAGE_LIMIT = 8.megabytes
   VIDEO_LIMIT = 40.megabytes
 
-  belongs_to :account, inverse_of: :media_attachments, optional: true
-  belongs_to :status,  inverse_of: :media_attachments, optional: true
+  belongs_to :account,          inverse_of: :media_attachments, optional: true
+  belongs_to :status,           inverse_of: :media_attachments, optional: true
+  belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true
 
   has_attached_file :file,
                     styles: ->(f) { file_styles f },
@@ -112,8 +114,8 @@ class MediaAttachment < ApplicationRecord
   validates :account, presence: true
   validates :description, length: { maximum: 420 }, if: :local?
 
-  scope :attached,   -> { where.not(status_id: nil) }
-  scope :unattached, -> { where(status_id: nil) }
+  scope :attached,   -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
+  scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
   scope :local,      -> { where(remote_url: '') }
   scope :remote,     -> { where.not(remote_url: '') }
 
diff --git a/app/models/relay.rb b/app/models/relay.rb
index 75cb060b2..7478c110d 100644
--- a/app/models/relay.rb
+++ b/app/models/relay.rb
@@ -68,7 +68,7 @@ class Relay < ApplicationRecord
   end
 
   def some_local_account
-    @some_local_account ||= Account.local.find_by(suspended: false)
+    @some_local_account ||= Account.representative
   end
 
   def ensure_disabled
diff --git a/app/models/scheduled_status.rb b/app/models/scheduled_status.rb
new file mode 100644
index 000000000..27f0cbd28
--- /dev/null
+++ b/app/models/scheduled_status.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: scheduled_statuses
+#
+#  id           :bigint(8)        not null, primary key
+#  account_id   :bigint(8)
+#  scheduled_at :datetime
+#  params       :jsonb
+#
+
+class ScheduledStatus < ApplicationRecord
+  include Paginable
+
+  TOTAL_LIMIT = 300
+  DAILY_LIMIT = 25
+
+  belongs_to :account, inverse_of: :scheduled_statuses
+  has_many :media_attachments, inverse_of: :scheduled_status, dependent: :nullify
+
+  validate :validate_future_date
+  validate :validate_total_limit
+  validate :validate_daily_limit
+
+  private
+
+  def validate_future_date
+    errors.add(:scheduled_at, I18n.t('scheduled_statuses.too_soon')) if scheduled_at.present? && scheduled_at <= Time.now.utc + PostStatusService::MIN_SCHEDULE_OFFSET
+  end
+
+  def validate_total_limit
+    errors.add(:base, I18n.t('scheduled_statuses.over_total_limit', limit: TOTAL_LIMIT)) if account.scheduled_statuses.count >= TOTAL_LIMIT
+  end
+
+  def validate_daily_limit
+    errors.add(:base, I18n.t('scheduled_statuses.over_daily_limit', limit: DAILY_LIMIT)) if account.scheduled_statuses.where('scheduled_at::date = ?::date', scheduled_at).count >= DAILY_LIMIT
+  end
+end