eBooru/app/models/dmail.rb

225 lines
5.9 KiB
Ruby
Raw Permalink Normal View History

# frozen_string_literal: true
class Dmail < ApplicationRecord
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
2019-09-05 08:59:51 -04:00
validates :title, :body, presence: { on: :create }
validates :title, length: { minimum: 1, maximum: 250 }
validates :body, length: { minimum: 1, maximum: Danbooru.config.dmail_max_size }
2019-10-03 10:29:49 -04:00
validate :recipient_accepts_dmails, on: :create
2019-06-27 11:33:02 -04:00
validate :user_not_limited, on: :create
2010-02-20 18:08:22 -05:00
belongs_to :owner, :class_name => "User"
belongs_to :to, :class_name => "User"
belongs_to :from, :class_name => "User"
after_initialize :initialize_attributes, if: :new_record?
before_create :auto_read_if_filtered
2010-02-20 18:08:22 -05:00
after_create :update_recipient
after_commit :send_email, on: :create, unless: :no_email_notification
2013-03-19 08:10:10 -04:00
attr_accessor :bypass_limits, :no_email_notification
2010-02-20 18:08:22 -05:00
module AddressMethods
def to_name=(name)
self.to_id = User.name_to_id(name)
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
def initialize_attributes
self.from_id ||= CurrentUser.id
self.creator_ip_addr ||= CurrentUser.ip_addr
2010-02-20 18:08:22 -05:00
end
end
2013-03-19 08:10:10 -04:00
2010-02-20 18:08:22 -05:00
module FactoryMethods
2010-11-19 16:24:17 -05:00
extend ActiveSupport::Concern
2013-03-19 08:10:10 -04:00
2010-02-20 18:08:22 -05:00
module ClassMethods
2010-11-19 16:24:17 -05:00
def create_split(params)
copy = nil
2013-03-19 08:10:10 -04:00
2010-11-19 16:24:17 -05:00
Dmail.transaction do
# recipient's copy
2010-11-19 16:24:17 -05:00
copy = Dmail.new(params)
copy.owner_id = copy.to_id
copy.save unless copy.to_id == copy.from_id
raise ActiveRecord::Rollback if copy.errors.any?
2010-02-20 18:08:22 -05:00
# sender's copy
2010-11-19 16:24:17 -05:00
copy = Dmail.new(params)
copy.bypass_limits = true
copy.owner_id = copy.from_id
2012-02-24 17:39:55 -05:00
copy.is_read = true
2012-01-20 17:19:08 -05:00
copy.save
2010-11-19 16:24:17 -05:00
end
2013-03-19 08:10:10 -04:00
copy
2010-11-19 16:24:17 -05:00
end
def create_automated(params)
CurrentUser.as_system do
dmail = Dmail.new(from: User.system, **params)
dmail.owner = dmail.to
dmail.save
2018-04-27 18:04:27 -04:00
dmail
end
end
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
def build_response(options = {})
2010-02-20 18:08:22 -05:00
Dmail.new do |dmail|
2013-03-03 16:05:47 -05:00
if title =~ /Re:/
dmail.title = title
else
dmail.title = "Re: #{title}"
end
2010-02-20 18:08:22 -05:00
dmail.owner_id = from_id
dmail.body = quoted_body
dmail.to_id = from_id unless options[:forward]
2010-02-20 18:08:22 -05:00
dmail.from_id = to_id
end
2010-11-19 16:24:17 -05:00
end
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
module SearchMethods
def sent_by_id(user_id)
where("dmails.from_id = ? AND dmails.owner_id != ?", user_id, user_id)
end
def sent_by(user)
where("dmails.from_id = ? AND dmails.owner_id != ?", user.id, user.id)
end
2013-01-10 17:45:52 -05:00
def active
where("is_deleted = ?", false)
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
def deleted
where("is_deleted = ?", true)
end
2013-03-19 08:10:10 -04:00
def read
where(is_read: true)
end
2013-01-10 17:45:52 -05:00
def unread
where("is_read = false and is_deleted = false")
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
def visible
where("owner_id = ?", CurrentUser.id)
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
def search(params)
q = super
2013-03-19 08:10:10 -04:00
q = q.attribute_matches(:title, params[:title_matches])
q = q.attribute_matches(:body, params[:message_matches])
2013-03-19 08:10:10 -04:00
q = q.where_user(:to_id, :to, params)
q = q.where_user(:from_id, :from, params)
2013-03-19 08:10:10 -04:00
q = q.attribute_matches(:is_read, params[:is_read])
q = q.attribute_matches(:is_deleted, params[:is_deleted])
2017-09-14 16:19:16 -04:00
q = q.read if params[:read].to_s.truthy?
q = q.unread if params[:read].to_s.falsy?
2014-03-29 16:28:55 -04:00
2020-03-07 15:13:12 -05:00
q.order(created_at: :desc)
2013-01-10 17:45:52 -05:00
end
end
2013-03-19 08:10:10 -04:00
2010-02-20 18:08:22 -05:00
include AddressMethods
include FactoryMethods
2013-01-10 17:45:52 -05:00
extend SearchMethods
2013-03-19 08:10:10 -04:00
2019-06-27 11:33:02 -04:00
def user_not_limited
# System user must be able to send dmails at a very high rate, do not rate limit the system user.
return true if bypass_limits == true
return true if from_id == User.system.id
return true if from.is_janitor?
2019-06-27 11:33:02 -04:00
allowed = CurrentUser.can_dmail_with_reason
if allowed != true
errors.add(:base, "Sender #{User.throttle_reason(allowed)}")
return
end
2019-06-27 11:33:02 -04:00
minute_allowed = CurrentUser.can_dmail_minute_with_reason
if minute_allowed != true
errors.add(:base, "Please wait a bit before trying to send again")
return
end
day_allowed = CurrentUser.can_dmail_day_with_reason
if day_allowed != true
errors.add(:base, "Sender #{User.throttle_reason(day_allowed, 'daily')}")
return
2019-06-27 11:33:02 -04:00
end
end
2019-10-03 10:29:49 -04:00
def recipient_accepts_dmails
unless to
errors.add(:to_name, "not found")
return false
end
2020-09-06 10:28:30 -04:00
return true if from_id == User.system.id
return true if from.is_janitor?
2019-10-03 10:29:49 -04:00
if to.disable_user_dmails
errors.add(:to_name, "has disabled DMails")
return false
end
if from.disable_user_dmails && !to.is_janitor?
errors.add(:to_name, "is not a valid recipient while blocking DMails from others. You may only message janitors and above")
return false
end
if to.is_blacklisting_user?(from)
errors.add(:to_name, "does not wish to receive DMails from you")
return false
end
end
2010-02-20 18:08:22 -05:00
def quoted_body
2019-08-18 04:50:43 -04:00
"[quote]\n#{from.pretty_name} said:\n\n#{body}\n[/quote]\n\n"
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
def send_email
if to.receive_email_notifications? && to.email =~ /@/ && owner_id == to.id
2015-08-18 20:37:07 -04:00
UserMailer.dmail_notice(self).deliver_now
2013-03-19 08:10:10 -04:00
end
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
2010-02-20 18:08:22 -05:00
def mark_as_read!
2018-05-09 14:56:01 -04:00
update_column(:is_read, true)
2024-02-23 11:18:22 -05:00
owner.update(unread_dmail_count: owner.dmails.unread.count)
2010-02-20 18:08:22 -05:00
end
2013-03-19 08:10:10 -04:00
def mark_as_unread!
update_column(:is_read, false)
2024-02-23 11:18:22 -05:00
owner.update(unread_dmail_count: owner.dmails.unread.count)
end
def is_automated?
from == User.system
end
def filtered?
CurrentUser.dmail_filter.try(:filtered?, self)
end
def auto_read_if_filtered
if owner_id != CurrentUser.id && to.dmail_filter.try(:filtered?, self)
2014-12-12 20:36:48 -05:00
self.is_read = true
2014-11-20 00:28:26 -05:00
end
end
2010-02-20 18:08:22 -05:00
def update_recipient
2015-09-23 15:13:14 -04:00
if owner_id != CurrentUser.user.id && !is_deleted? && !is_read?
2024-02-23 11:18:22 -05:00
to.update(unread_dmail_count: to.dmails.unread.count)
2014-11-20 00:28:26 -05:00
end
2010-02-20 18:08:22 -05:00
end
def visible_to?(user)
return true if user.is_moderator? && (from_id == User.system.id || Ticket.exists?(qtype: "dmail", disp_id: id))
return true if user.is_admin? && (to.is_admin? || from.is_admin?)
owner_id == user.id
end
2010-02-20 18:08:22 -05:00
end