about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-01-05 12:43:28 +0100
committerGitHub <noreply@github.com>2019-01-05 12:43:28 +0100
commita49d43d1121ac10f96d5a9cbf78112c707e7a59e (patch)
treeee311cf3d68d695f6cc6c69ce9e1b01c6ad4aeb4 /app/models
parentb17b2f25acc4d0cd4284835f28364451cb2fcd88 (diff)
Add scheduled statuses (#9706)
Fix #340
Diffstat (limited to 'app/models')
-rw-r--r--app/models/concerns/account_associations.rb1
-rw-r--r--app/models/media_attachment.rb38
-rw-r--r--app/models/scheduled_status.rb39
3 files changed, 60 insertions, 18 deletions
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index a894b5eed..7dafeee34 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -14,6 +14,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/media_attachment.rb b/app/models/media_attachment.rb
index 62a11185a..6b939124f 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
@@ -76,8 +77,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 },
@@ -94,8 +96,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/scheduled_status.rb b/app/models/scheduled_status.rb
new file mode 100644
index 000000000..c95470fc8
--- /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: :destroy
+
+  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