eBooru/app/models/note.rb

192 lines
5.0 KiB
Ruby
Raw Permalink Normal View History

# frozen_string_literal: true
class Note < ApplicationRecord
class RevertError < Exception ; end
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
attr_accessor :html_id
2010-02-24 15:40:55 -05:00
belongs_to :post
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
belongs_to_creator
has_many :versions, -> {order("note_versions.id ASC")}, :class_name => "NoteVersion", :dependent => :destroy
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
2019-09-05 08:59:51 -04:00
validates :post_id, :creator_id, :x, :y, :width, :height, :body, presence: true
2019-06-27 11:33:02 -04:00
validate :user_not_limited
2013-05-06 20:01:34 -04:00
validate :post_must_exist
2015-08-18 20:37:07 -04:00
validate :note_within_image
validates :body, length: { minimum: 1, maximum: Danbooru.config.note_max_size }, if: :body_changed?
2010-02-24 15:40:55 -05:00
after_save :update_post
after_save :create_version
validate :post_must_not_be_note_locked
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
module SearchMethods
def active
where("is_active = TRUE")
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
def post_tags_match(query)
where(post_id: Post.tag_match_sql(query))
2013-01-10 17:45:52 -05:00
end
2013-03-19 08:10:10 -04:00
def for_creator(user_id)
where("creator_id = ?", user_id)
end
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(:body, params[:body_matches])
q = q.attribute_matches(:is_active, params[:is_active])
2015-01-15 13:15:56 -05:00
2013-03-08 17:01:32 -05:00
if params[:post_id].present?
q = q.where(post_id: params[:post_id].split(",").map(&:to_i))
2013-03-08 17:01:32 -05:00
end
2013-03-19 08:10:10 -04:00
2013-02-19 12:27:17 -05:00
if params[:post_tags_match].present?
2013-01-10 17:45:52 -05:00
q = q.post_tags_match(params[:post_tags_match])
end
2013-03-19 08:10:10 -04:00
with_resolved_user_ids(:post_note_updater, params) do |user_ids|
q = q.where(post_id: NoteVersion.select(:post_id).where(updater_id: user_ids))
end
q = q.where_user(:creator_id, :creator, params)
2013-03-19 08:10:10 -04:00
2023-07-07 08:32:57 -04:00
q.apply_basic_order(params)
2013-01-10 17:45:52 -05:00
end
end
2013-03-19 08:10:10 -04:00
2013-03-11 13:14:25 -04:00
module ApiMethods
def method_attributes
super + [:creator_name]
2013-03-11 13:14:25 -04:00
end
end
2013-03-19 08:10:10 -04:00
2013-01-10 17:45:52 -05:00
extend SearchMethods
2013-03-11 13:14:25 -04:00
include ApiMethods
2013-03-19 08:10:10 -04:00
2019-06-27 11:33:02 -04:00
def user_not_limited
allowed = CurrentUser.can_note_edit_with_reason
2019-06-27 11:33:02 -04:00
if allowed != true
errors.add(:base, "User #{User.throttle_reason(allowed)}.")
false
end
true
end
2013-05-06 20:01:34 -04:00
def post_must_exist
if !Post.exists?(post_id)
errors.add :post, "must exist"
2013-05-03 20:29:41 -04:00
return false
end
end
2010-02-24 15:40:55 -05:00
def post_must_not_be_note_locked
if is_locked?
errors.add :post, "is note locked"
return false
end
end
2013-03-19 08:10:10 -04:00
2013-05-06 20:01:34 -04:00
def note_within_image
return false unless post.present?
if x < 0 || y < 0 || (x > post.image_width) || (y > post.image_height) || width < 0 || height < 0 || (x + width > post.image_width) || (y + height > post.image_height)
2013-05-06 20:01:34 -04:00
self.errors.add(:note, "must be inside the image")
return false
end
end
2010-02-24 15:40:55 -05:00
def is_locked?
Post.exists?(["id = ? AND is_note_locked = ?", post_id, true])
end
2013-03-19 08:10:10 -04:00
2017-05-17 01:14:20 -04:00
def rescale!(x_scale, y_scale)
self.x *= x_scale
self.y *= y_scale
self.width *= x_scale
self.height *= y_scale
save!
end
2010-02-24 15:40:55 -05:00
def update_post
if saved_changes?
post_noted_at = Note.where(is_active: true, post_id: post_id).exists? ? updated_at : nil
Post.where(id: post_id).update_all(last_noted_at: post_noted_at)
2021-01-23 13:19:27 -05:00
post.reload.update_index
2010-02-24 15:40:55 -05:00
end
end
2013-03-19 08:10:10 -04:00
def create_version(updater: CurrentUser.user, updater_ip_addr: CurrentUser.ip_addr)
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
return unless saved_change_to_versioned_attributes?
2013-03-19 08:10:10 -04:00
2019-12-28 03:45:53 -05:00
Note.where(:id => id).update_all("version = coalesce(version, 0) + 1")
reload
create_new_version(updater.id, updater_ip_addr)
2014-03-18 15:56:36 -04:00
end
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
def saved_change_to_versioned_attributes?
new_record? || saved_change_to_x? || saved_change_to_y? || saved_change_to_width? || saved_change_to_height? || saved_change_to_is_active? || saved_change_to_body?
end
def create_new_version(updater_id, updater_ip_addr)
2010-02-24 15:40:55 -05:00
versions.create(
:updater_id => updater_id,
:updater_ip_addr => updater_ip_addr,
2011-07-09 03:32:18 -04:00
:post_id => post_id,
2010-02-24 15:40:55 -05:00
:x => x,
:y => y,
:width => width,
:height => height,
:is_active => is_active,
2013-03-22 13:47:24 -04:00
:body => body,
:version => version
2010-02-24 15:40:55 -05:00
)
end
2013-03-19 08:10:10 -04:00
2011-01-19 14:28:22 -05:00
def revert_to(version)
if id != version.note_id
raise RevertError.new("You cannot revert to a previous version of another note.")
end
2010-02-24 15:40:55 -05:00
self.x = version.x
self.y = version.y
2011-07-09 03:32:18 -04:00
self.post_id = version.post_id
2010-02-24 15:40:55 -05:00
self.body = version.body
self.width = version.width
self.height = version.height
self.is_active = version.is_active
end
2013-03-19 08:10:10 -04:00
2011-01-19 14:28:22 -05:00
def revert_to!(version)
revert_to(version)
2010-02-24 15:40:55 -05:00
save!
end
2013-05-18 16:25:46 -04:00
def copy_to(new_post)
new_note = dup
new_note.post_id = new_post.id
2013-05-23 23:19:39 -04:00
new_note.version = 0
2013-05-18 16:25:46 -04:00
width_ratio = new_post.image_width.to_f / post.image_width
height_ratio = new_post.image_height.to_f / post.image_height
new_note.x = x * width_ratio
new_note.y = y * height_ratio
new_note.width = width * width_ratio
new_note.height = height * height_ratio
new_note.save
end
2014-04-14 17:32:01 -04:00
def self.undo_changes_by_user(vandal_id)
2010-02-24 15:40:55 -05:00
transaction do
2023-12-03 09:36:37 -05:00
note_ids = NoteVersion.where(updater_id: vandal_id).distinct.pluck(:note_id)
2014-04-14 17:32:01 -04:00
NoteVersion.where(["updater_id = ?", vandal_id]).delete_all
note_ids.each do |note_id|
note = Note.find(note_id)
most_recent = note.versions.last
if most_recent
note.revert_to!(most_recent)
2010-02-24 15:40:55 -05:00
end
end
end
end
end