rubocop: fix various Rubocop warnings.

This commit is contained in:
evazion
2021-06-16 18:24:42 -05:00
parent cfe471e0b5
commit 07e23204b6
99 changed files with 412 additions and 374 deletions

View File

@@ -18,6 +18,9 @@ Layout/CaseIndentation:
Layout/EmptyLineAfterGuardClause:
Enabled: false
Layout/EmptyLineBetweenDefs:
AllowAdjacentOneLineDefs: true
Layout/EndAlignment:
EnforcedStyleAlignWith: variable
@@ -44,7 +47,7 @@ Metrics/AbcSize:
Metrics/BlockLength:
Max: 50
ExcludedMethods:
IgnoredMethods:
- concerning
- context
- should
@@ -66,7 +69,7 @@ Metrics/ModuleLength:
Max: 500
Metrics/ParameterLists:
Max: 4
Max: 6
Metrics/PerceivedComplexity:
Max: 20
@@ -74,18 +77,43 @@ Metrics/PerceivedComplexity:
Lint/InheritException:
EnforcedStyle: standard_error
Naming/HeredocDelimiterNaming:
Enabled: false
Naming/MethodParameterName:
Enabled: false
Naming/PredicateName:
Enabled: false
Rails/Blank:
UnlessPresent: false
Rails/DynamicFindBy:
Enabled: false
Rails/HasManyOrHasOneDependent:
Enabled: false
Rails/HttpStatus:
EnforcedStyle: numeric
Rails/InverseOf:
Enabled: false
Style/Alias:
EnforcedStyle: prefer_alias_method
Style/AsciiComments:
Enabled: false
Style/CommentAnnotation:
Enabled: false
Style/ConditionalAssignment:
EnforcedStyle: assign_inside_condition
IncludeTernaryExpressions: false
Style/Documentation:
Enabled: false
@@ -104,6 +132,9 @@ Style/FloatDivision:
Style/FrozenStringLiteralComment:
Enabled: false
Style/GuardClause:
MinBodyLength: 20
Style/HashSyntax:
Enabled: false
@@ -113,12 +144,20 @@ Style/IfUnlessModifier:
Style/MutableConstant:
Enabled: false
Style/NegatedIf:
Enabled: false
Style/NumericPredicate:
Enabled: false
Style/PercentLiteralDelimiters:
PreferredDelimiters:
"default": "[]"
"default": "{}"
"%i": "[]"
"%I": "[]"
"%w": "[]"
"%W": "[]"
"%r": "{}"
Style/ParallelAssignment:
Enabled: false
@@ -134,7 +173,7 @@ Style/SpecialGlobalVars:
Enabled: false
Style/StringLiterals:
Enabled: false
EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
Enabled: false
@@ -142,8 +181,18 @@ Style/StringLiteralsInInterpolation:
Style/SymbolArray:
MinSize: 10
Style/SymbolProc:
IgnoredMethods:
- respond_with
Style/TernaryParentheses:
EnforcedStyle: require_parentheses_when_complex
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/WordArray:
MinSize: 10

View File

@@ -1,7 +1,6 @@
class ApplicationComponent < ViewComponent::Base
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :external_link_to, :tag_class, to: :helpers
delegate :edit_icon, :delete_icon, :undelete_icon, :flag_icon, :upvote_icon,
:downvote_icon, :link_icon, :sticky_icon, :unsticky_icon, to: :helpers
delegate :edit_icon, :delete_icon, :undelete_icon, :flag_icon, :upvote_icon, :downvote_icon, :link_icon, :sticky_icon, :unsticky_icon, to: :helpers
def policy(subject)
Pundit.policy!(current_user, subject)

View File

@@ -4,6 +4,7 @@ class CommentComponent < ApplicationComponent
attr_reader :comment, :context, :dtext_data, :current_user
def initialize(comment:, current_user:, context: nil, dtext_data: nil)
super
@comment = comment
@context = context
@dtext_data = dtext_data
@@ -11,7 +12,7 @@ class CommentComponent < ApplicationComponent
end
def dimmed?
comment.is_deleted? || (!comment.is_sticky? && comment.score <= current_user.comment_threshold/2.0)
comment.is_deleted? || (!comment.is_sticky? && comment.score <= current_user.comment_threshold / 2.0)
end
def thresholded?

View File

@@ -4,6 +4,7 @@ class CommentSectionComponent < ApplicationComponent
attr_reader :post, :comments, :current_user, :limit, :dtext_data
def initialize(post:, current_user:, limit: nil)
super
@post = post
@current_user = current_user
@limit = limit

View File

@@ -2,6 +2,7 @@
class ForumPostComponent < ApplicationComponent
attr_reader :forum_post, :original_forum_post_id, :dtext_data, :moderation_reports, :current_user
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :policy, to: :helpers
with_collection_parameter :forum_post
@@ -17,6 +18,7 @@ class ForumPostComponent < ApplicationComponent
end
def initialize(forum_post:, original_forum_post_id: nil, dtext_data: nil, current_user: User.anonymous)
super
@forum_post = forum_post
@original_forum_post_id = original_forum_post_id
@dtext_data = dtext_data

View File

@@ -23,6 +23,7 @@
<% if policy(forum_post).create? %>
<li><%= link_to "Reply", new_forum_post_path(post_id: forum_post.id), method: :get, remote: true %></li>
<% end %>
<% if policy(forum_post).destroy? && !forum_post.is_original_post?(original_forum_post_id) %>
<% if forum_post.is_deleted %>
<li><%= link_to "Undelete", undelete_forum_post_path(forum_post.id), method: :post, remote: true %></li>
@@ -30,6 +31,7 @@
<li><%= link_to "Delete", forum_post_path(forum_post.id), "data-confirm": "Are you sure you want to delete this forum post?", method: :delete, remote: true %></li>
<% end %>
<% end %>
<% if policy(forum_post).update? %>
<% if forum_post.is_original_post?(original_forum_post_id) %>
<li><%= link_to "Edit", edit_forum_topic_path(forum_post.topic), id: "edit_forum_topic_link_#{forum_post.topic.id}", class: "edit_forum_topic_link" %></li>
@@ -37,12 +39,15 @@
<li><%= link_to "Edit", edit_forum_post_path(forum_post.id), id: "edit_forum_post_link_#{forum_post.id}", class: "edit_forum_post_link" %></li>
<% end %>
<% end %>
<% if policy(forum_post).reportable? %>
<li><%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true, title: "Report this forum post to the moderators" %></li>
<% end %>
<% if has_moderation_reports? %>
<li class="moderation-report-notice">Reported (<%= link_to pluralize(forum_post.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "ForumPost", model_id: forum_post.id }) %>)</li>
<% end %>
<% if forum_post.bulk_update_request.present? %>
<menu class="votes" id="forum-post-votes-for-<%= forum_post.id %>">
<%= render "forum_post_votes/list", votes: forum_post.votes, forum_post: forum_post %>

View File

@@ -2,10 +2,12 @@
class PaginatorComponent < ApplicationComponent
attr_reader :records, :window, :params
delegate :current_page, :prev_page, :next_page, :total_pages, :paginator_mode, :paginator_page_limit, to: :records
delegate :ellipsis_icon, :chevron_left_icon, :chevron_right_icon, to: :helpers
def initialize(records:, params:, window: 4)
super
@records = records
@window = window
@params = params
@@ -25,7 +27,7 @@ class PaginatorComponent < ApplicationComponent
("..." unless left == 2),
(left..right).to_a,
("..." unless right == last_page - 1),
(last_page unless last_page == 1)
(last_page unless last_page == 1),
].flatten.compact
end

View File

@@ -4,6 +4,7 @@ class PostNavbarComponent < ApplicationComponent
attr_reader :post, :current_user, :search
def initialize(post:, current_user:, search: nil)
super
@post = post
@current_user = current_user
@search = search.presence || "status:any"

View File

@@ -4,9 +4,11 @@ class PostPreviewComponent < ApplicationComponent
with_collection_parameter :post
attr_reader :post, :tags, :show_deleted, :show_cropped, :link_target, :pool, :similarity, :recommended, :compact, :size, :current_user, :options
delegate :external_link_to, :time_ago_in_words_tagged, :empty_heart_icon, to: :helpers
def initialize(post:, tags: "", show_deleted: false, show_cropped: true, link_target: post, pool: nil, similarity: nil, recommended: nil, compact: nil, size: nil, current_user: CurrentUser.user, **options)
super
@post = post
@tags = tags.presence
@show_deleted = show_deleted
@@ -44,7 +46,7 @@ class PostPreviewComponent < ApplicationComponent
{
width: [(downscale_ratio * post.image_width).floor, post.image_width].min,
height: [(downscale_ratio * post.image_height).floor, post.image_height].min
height: [(downscale_ratio * post.image_height).floor, post.image_height].min,
}
else
{ width: 0, height: 0 }
@@ -70,7 +72,7 @@ class PostPreviewComponent < ApplicationComponent
def data_attributes
attributes = {
"data-id" => post.id,
"data-has-sound" => post.has_tag?('video_with_sound|flash_with_sound'),
"data-has-sound" => post.has_tag?("video_with_sound|flash_with_sound"),
"data-tags" => post.tag_string,
"data-pools" => post.pool_string,
"data-approver-id" => post.approver_id,

View File

@@ -5,6 +5,7 @@ class PostVotesComponent < ApplicationComponent
attr_reader :post, :current_user
def initialize(post:, current_user:)
super
@post = post
@current_user = current_user
end

View File

@@ -2,9 +2,11 @@
class SourceDataComponent < ApplicationComponent
attr_reader :source
delegate :spinner_icon, :external_site_icon, to: :helpers
def initialize(source:)
super
@source = source
end

View File

@@ -2,16 +2,18 @@
class TagListComponent < ApplicationComponent
attr_reader :tags, :current_query, :show_extra_links
delegate :humanized_number, to: :helpers
def initialize(tags: [], current_query: nil, show_extra_links: false)
super
@tags = tags
@current_query = current_query
@show_extra_links = show_extra_links
end
def self.tags_from_names(tag_names)
names_to_tags = Tag.where(name: tag_names).map { |tag| [tag.name, tag] }.to_h
names_to_tags = Tag.where(name: tag_names).index_by(&:name)
tag_names.map do |name|
names_to_tags.fetch(name) { Tag.new(name: name).freeze }

View File

@@ -90,9 +90,9 @@ class ApplicationController < ActionController::Base
render_error_page(401, exception, template: "sessions/new")
when ActionController::InvalidAuthenticityToken, ActionController::UnpermittedParameters, ActionController::InvalidCrossOriginRequest
render_error_page(403, exception)
when ActiveSupport::MessageVerifier::InvalidSignature # raised by `find_signed!`
render_error_page(403, exception, template: "static/access_denied", message: "Access denied")
when User::PrivilegeError, Pundit::NotAuthorizedError
when ActiveSupport::MessageVerifier::InvalidSignature, # raised by `find_signed!`
User::PrivilegeError,
Pundit::NotAuthorizedError
render_error_page(403, exception, template: "static/access_denied", message: "Access denied")
when ActiveRecord::RecordNotFound
render_error_page(404, exception, message: "That record was not found.")
@@ -183,7 +183,7 @@ class ApplicationController < ActionController::Base
return if CurrentUser.user.is_anonymous?
last_authenticated_at = session[:last_authenticated_at]
if last_authenticated_at.blank? || Time.parse(last_authenticated_at) < 60.minutes.ago
if last_authenticated_at.blank? || Time.zone.parse(last_authenticated_at) < 60.minutes.ago
redirect_to confirm_password_session_path(url: request.fullpath)
end
end
@@ -197,7 +197,7 @@ class ApplicationController < ActionController::Base
params[:search] ||= ActionController::Parameters.new
deep_reject_blank = lambda do |hash|
hash.reject { |k, v| v.blank? || (v.is_a?(Hash) && deep_reject_blank.call(v).blank?) }
hash.reject { |_k, v| v.blank? || (v.is_a?(Hash) && deep_reject_blank.call(v).blank?) }
end
nonblank_search_params = deep_reject_blank.call(params[:search])

View File

@@ -56,7 +56,7 @@ class ArtistsController < ApplicationController
def destroy
@artist = authorize Artist.find(params[:id])
@artist.update_attribute(:is_deleted, true)
@artist.update(is_deleted: true)
redirect_to(artist_path(@artist), :notice => "Artist deleted")
end

View File

@@ -3,7 +3,7 @@ class CommentVotesController < ApplicationController
def index
@comment_votes = authorize CommentVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@comment_votes = @comment_votes.includes(:user, comment: [:creator, post: [:uploader]]) if request.format.html?
@comment_votes = @comment_votes.includes(:user, comment: [:creator, { post: [:uploader] }]) if request.format.html?
respond_with(@comment_votes)
end

View File

@@ -82,7 +82,7 @@ class CommentsController < ApplicationController
def index_by_post
@limit = params.fetch(:limit, 20)
@posts = Post.where("last_comment_bumped_at IS NOT NULL").user_tag_match(params[:tags]).reorder("last_comment_bumped_at DESC NULLS LAST").paginate(params[:page], limit: @limit, search_count: params[:search])
@posts = Post.where.not(last_comment_bumped_at: nil).user_tag_match(params[:tags]).reorder("last_comment_bumped_at DESC NULLS LAST").paginate(params[:page], limit: @limit, search_count: params[:search])
if request.format.html?
@posts = @posts.includes(comments: [:creator])

View File

@@ -8,33 +8,25 @@ class DelayedJobsController < ApplicationController
def cancel
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
if !@job.locked_at?
@job.fail!
end
@job.fail! unless @job.locked_at?
respond_with(@job)
end
def retry
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
if !@job.locked_at?
@job.update(failed_at: nil, attempts: 0)
end
@job.update(failed_at: nil, attempts: 0) unless @job.locked_at?
respond_with(@job)
end
def run
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
if !@job.locked_at?
@job.update(run_at: Time.now)
end
@job.update(run_at: Time.zone.now) unless @job.locked_at?
respond_with(@job)
end
def destroy
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
if !@job.locked_at?
@job.destroy
end
@job.destroy unless @job.locked_at?
respond_with(@job)
end
end

View File

@@ -2,7 +2,8 @@ class DtextPreviewsController < ApplicationController
def create
@inline = params[:inline].to_s.truthy?
@disable_mentions = params[:disable_mentions].to_s.truthy?
@html = helpers.format_text(params[:body], inline: @inline, disable_mentions: @disable_mentions)
render inline: "<%= format_text(params[:body], inline: @inline, disable_mentions: @disable_mentions) %>"
render html: @html
end
end

View File

@@ -79,7 +79,7 @@ class ForumTopicsController < ApplicationController
def mark_all_as_read
authorize ForumTopic
CurrentUser.user.update_attribute(:last_forum_read_at, Time.now)
CurrentUser.user.update(last_forum_read_at: Time.zone.now)
ForumTopicVisit.prune!(CurrentUser.user)
redirect_to forum_topics_path, :notice => "All topics marked as read"
end

View File

@@ -4,9 +4,10 @@ class IpAddressesController < ApplicationController
def index
@ip_addresses = authorize IpAddress.visible(CurrentUser.user).paginated_search(params)
if search_params[:group_by] == "ip_addr"
case search_params[:group_by]
when "ip_addr"
@ip_addresses = @ip_addresses.group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen])
elsif search_params[:group_by] == "user"
when "user"
@ip_addresses = @ip_addresses.group_by_user.includes(:user)
else
@ip_addresses = @ip_addresses.includes(:user, :model)

View File

@@ -4,7 +4,7 @@ module Maintenance
class VerificationError < StandardError; end
before_action :validate_sig, :only => [:destroy]
rescue_from VerificationError, :with => :render_403
rescue_from VerificationError, with: :render_verification_error
def show
end
@@ -17,15 +17,15 @@ module Maintenance
private
def render_403
render plain: "", :status => 403
def render_verification_error
render plain: "", status: 403
end
def validate_sig
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, digest: "SHA256", serializer: JSON)
calculated_sig = verifier.generate(params[:user_id].to_s)
if calculated_sig != params[:sig]
raise VerificationError.new
raise VerificationError, "Invalid signature"
end
end
end

View File

@@ -35,8 +35,6 @@ class PoolVersionsController < ApplicationController
end
def check_availabililty
if !PoolVersion.enabled?
raise NotImplementedError.new("Archive service is not configured. Pool versions are not saved.")
end
raise NotImplementedError, "Archive service is not configured. Pool versions are not saved." unless PoolVersion.enabled?
end
end

View File

@@ -54,7 +54,7 @@ class PoolsController < ApplicationController
def destroy
@pool = authorize Pool.find(params[:id])
@pool.update_attribute(:is_deleted, true)
@pool.update(is_deleted: true)
@pool.create_mod_action_for_delete
flash[:notice] = "Pool deleted"
respond_with(@pool)
@@ -62,7 +62,7 @@ class PoolsController < ApplicationController
def undelete
@pool = authorize Pool.find(params[:id])
@pool.update_attribute(:is_deleted, false)
@pool.update(is_deleted: false)
@pool.create_mod_action_for_undelete
flash[:notice] = "Pool undeleted"
respond_with(@pool)

View File

@@ -37,8 +37,7 @@ class PostVersionsController < ApplicationController
end
def check_availabililty
if !PostVersion.enabled?
raise NotImplementedError.new("Archive service is not configured. Post versions are not saved.")
end
return if PostVersion.enabled?
raise NotImplementedError, "Archive service is not configured. Post versions are not saved."
end
end

View File

@@ -116,7 +116,7 @@ class PostsController < ApplicationController
render :template => "static/error", :status => 500
else
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], :favgroup_id => params[:favgroup_id]}
response_params.reject! {|key, value| value.blank?}
response_params.reject! {|_key, value| value.blank?}
redirect_to post_path(post, response_params)
end
end

View File

@@ -4,7 +4,7 @@ class RecommendedPostsController < ApplicationController
def index
limit = params.fetch(:limit, 100).to_i.clamp(0, 200)
@recs = RecommenderService.search(search_params).take(limit)
@posts = @recs.map { |rec| rec[:post] }
@posts = @recs.pluck(:post)
respond_with(@recs)
end

View File

@@ -33,7 +33,7 @@ class StaticController < ApplicationController
def sitemap_index
@sitemap = params[:sitemap]
@limit = params.fetch(:limit, 10000).to_i
@limit = params.fetch(:limit, 10_000).to_i
case @sitemap
when "artists"

View File

@@ -45,7 +45,7 @@ class UploadsController < ApplicationController
def preprocess
authorize Upload
@upload, @remote_size = UploadService::ControllerHelper.prepare(
url: params.dig(:upload, :source), file: params.dig(:upload, :file), ref: params.dig(:upload, :referer_url),
url: params.dig(:upload, :source), file: params.dig(:upload, :file), ref: params.dig(:upload, :referer_url)
)
render body: nil
end

View File

@@ -1,5 +1,3 @@
require 'dtext'
module ApplicationHelper
def listing_type(*fields, member_check: true, types: [:revert, :standard])
(fields.reduce(false) { |acc, field| acc || params.dig(:search, field).present? } && (!member_check || CurrentUser.is_member?) ? types[0] : types[1])
@@ -11,8 +9,7 @@ module ApplicationHelper
end
def diff_name_html(this_name, other_name)
pattern = Regexp.new('.')
DiffBuilder.new(this_name, other_name, pattern).build
DiffBuilder.new(this_name, other_name, /./).build
end
def diff_body_html(record, other, field)
@@ -21,7 +18,7 @@ module ApplicationHelper
return h(diff_record[field]).gsub(/\r?\n/, '<span class="paragraph-mark">¶</span><br>').html_safe
end
pattern = Regexp.new('(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)')
pattern = /(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)/
DiffBuilder.new(record[field], other[field], pattern).build
end
@@ -32,18 +29,17 @@ module ApplicationHelper
return type == "previous" ? "New" : ""
end
statuses = []
record.class.status_fields.each do |field, status|
if record.has_attribute?(field)
statuses += [status] if record[field] != other[field]
else
statuses += [status] if record.send(field, type)
end
changed_fields = record.class.status_fields.select do |field, status|
(record.has_attribute?(field) && record[field] != other[field]) ||
(!record.has_attribute?(field) && record.send(field, type))
end
statuses = changed_fields.map { |field, status| status }
altered = record.updater_id != other.updater_id
%(<div class="version-statuses" data-altered="#{altered}">#{statuses.join("<br>")}</div>).html_safe
tag.div(class: "version-statuses", "data-altered": altered) do
safe_join(statuses, tag.br)
end
end
def wordbreakify(string)

View File

@@ -4,7 +4,7 @@ module ForumTopicsHelper
end
def available_min_user_levels
ForumTopic::MIN_LEVELS.select { |name, level| level <= CurrentUser.level }.to_a
ForumTopic::MIN_LEVELS.select { |_name, level| level <= CurrentUser.level }.to_a
end
def new_forum_topic?(topic, read_forum_topics)

View File

@@ -22,11 +22,12 @@ module PopularPostsHelper
end
def date_range_description(date, scale, min_date, max_date)
if scale == "day"
case scale
when "day"
date.strftime("%B %d, %Y")
elsif scale == "week"
when "week"
"#{min_date.strftime("%B %d, %Y")} - #{max_date.strftime("%B %d, %Y")}"
elsif scale == "month"
when "month"
date.strftime("%B %Y")
end
end

View File

@@ -40,12 +40,12 @@ module PostVersionsHelper
def post_version_field(post_version, field)
value = post_version_value(post_version.send(field))
prefix = (field == :parent_id ? "parent" : field.to_s)
search = prefix + ":" + value.to_s
search = "#{prefix}:#{value}"
display = (field == :rating ? post_version.pretty_rating : value)
%(<b>#{field.to_s.titleize}:</b> #{link_to(display, posts_path(:tags => search))}).html_safe
end
def post_version_value(value)
return (value.present? ? value : "none")
value.presence || "none"
end
end

View File

@@ -1,6 +1,9 @@
module WikiPagesHelper
def wiki_page_other_names_list(wiki_page)
names_html = wiki_page.other_names.map {|name| link_to(name, "http://www.pixiv.net/search.php?s_mode=s_tag_full&word=#{u(name)}", :class => "wiki-other-name")}
names_html.join(" ").html_safe
names_html = wiki_page.other_names.map do |name|
link_to(name, "https://www.pixiv.net/tags/#{u(name)}/artworks", class: "wiki-other-name")
end
safe_join(names_html, " ")
end
end

View File

@@ -2,7 +2,7 @@ class ApplicationJob < ActiveJob::Base
queue_as :default
queue_with_priority 0
discard_on ActiveJob::DeserializationError do |job, error|
discard_on ActiveJob::DeserializationError do |_job, error|
DanbooruLogger.log(error)
end
end

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class Artist < ::Struct.new(:user, :count)
def self.all(min_date, max_level)
::ArtistVersion.joins(:updater)
::ArtistVersion
.joins(:updater)
.where("artist_versions.created_at > ?", min_date)
.where("users.level <= ?", max_level)
.group(:updater)

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class Comment < ::Struct.new(:comment, :count)
def self.all(min_date, max_level)
::CommentVote.joins(comment: [:creator])
::CommentVote
.joins(comment: [:creator])
.where("comments.score < 0")
.where("comment_votes.created_at > ?", min_date)
.where("users.level <= ?", max_level)

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class Note < ::Struct.new(:user, :count)
def self.all(min_date, max_level)
::NoteVersion.joins(:updater)
::NoteVersion
.joins(:updater)
.where("note_versions.created_at > ?", min_date)
.where("users.level <= ?", max_level)
.group(:updater)

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class PostAppeal
def self.all(min_date)
::Post.joins(:appeals).includes(:uploader, :flags, appeals: [:creator])
::Post
.joins(:appeals).includes(:uploader, :flags, appeals: [:creator])
.deleted
.where("post_appeals.created_at > ?", min_date)
.group(:id)

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class Upload < ::Struct.new(:user, :count)
def self.all(min_date, max_level)
::Post.joins(:uploader)
::Post
.joins(:uploader)
.where("posts.created_at > ?", min_date)
.where("users.level <= ?", max_level)
.group(:uploader)

View File

@@ -3,7 +3,8 @@ module Moderator
module Queries
class WikiPage < ::Struct.new(:user, :count)
def self.all(min_date, max_level)
::WikiPageVersion.joins(:updater)
::WikiPageVersion
.joins(:updater)
.where("wiki_page_versions.created_at > ?", min_date)
.where("users.level <= ?", max_level)
.group(:updater)

View File

@@ -62,7 +62,7 @@ module Moderator
end
def add_row(sums, counts)
sums.merge!(counts) { |key, oldcount, newcount| oldcount + newcount }
sums.merge!(counts) { |_key, oldcount, newcount| oldcount + newcount }
end
def add_row_id(sums, counts)

View File

@@ -11,9 +11,10 @@ class NicoSeigaApiClient
end
def image_ids
if @work_type == "illust"
case @work_type
when "illust"
[api_response["id"]]
elsif @work_type == "manga"
when "manga"
manga_api_response.map do |x|
case x["meta"]["source_url"]
when %r{/thumb/(\d+)\w}i then Regexp.last_match(1)
@@ -40,20 +41,22 @@ class NicoSeigaApiClient
end
def user_name
if @work_type == "illust"
case @work_type
when "illust"
api_response["nickname"]
elsif @work_type == "manga"
when "manga"
user_api_response(user_id)["nickname"]
end
end
def api_response
if @work_type == "illust"
case @work_type
when "illust"
resp = get("https://sp.seiga.nicovideo.jp/ajax/seiga/im#{@work_id}")
return {} if resp.blank? || resp.code.to_i == 404
api_response = JSON.parse(resp)["target_image"]
elsif @work_type == "manga"
when "manga"
resp = http.cache(1.minute).get("#{XML_API}/theme/info?id=#{@work_id}")
return {} if resp.blank? || resp.code.to_i == 404
api_response = Hash.from_xml(resp.to_s)["response"]["theme"]
@@ -86,16 +89,13 @@ class NicoSeigaApiClient
# XXX should fail gracefully instead of raising exception
resp = http.cache(1.hour).post("https://account.nicovideo.jp/login/redirector?site=seiga", form: form)
raise RuntimeError, "NicoSeiga login failed (status=#{resp.status} url=#{url})" if resp.status != 200
raise "NicoSeiga login failed (status=#{resp.status} url=#{url})" if resp.status != 200
http
end
def get(url)
resp = login.cache(1.minute).get(url)
#raise RuntimeError, "NicoSeiga get failed (status=#{resp.status} url=#{url})" if resp.status != 200
resp
login.cache(1.minute).get(url)
end
memoize :api_response, :manga_api_response, :user_api_response

View File

@@ -1,19 +1,19 @@
module NoteSanitizer
ALLOWED_ELEMENTS = %w(
ALLOWED_ELEMENTS = %w[
code center tn h1 h2 h3 h4 h5 h6 a span div blockquote br p ul li ol em
strong small big b i font u s pre ruby rb rt rp rtc sub sup hr wbr
)
]
ALLOWED_ATTRIBUTES = {
:all => %w(style title),
"a" => %w(href),
"span" => %w(class),
"div" => %w(class align),
"p" => %w(class align),
"font" => %w(color size)
:all => %w[style title],
"a" => %w[href],
"span" => %w[class],
"div" => %w[class align],
"p" => %w[class align],
"font" => %w[color size]
}
ALLOWED_PROPERTIES = %w(
ALLOWED_PROPERTIES = %w[
align-items
background background-color
border border-color border-image border-radius border-style border-width
@@ -48,7 +48,7 @@ module NoteSanitizer
word-wrap overflow-wrap
writing-mode
vertical-align
)
]
def self.sanitize(text)
text.gsub!(/<( |-|3|:|>|\Z)/, "&lt;\\1")

View File

@@ -46,21 +46,23 @@ module PaginationExtension
end
def is_first_page?
if paginator_mode == :numbered
case paginator_mode
when :numbered
current_page == 1
elsif paginator_mode == :sequential_before
when :sequential_before
false
elsif paginator_mode == :sequential_after
when :sequential_after
size <= records_per_page
end
end
def is_last_page?
if paginator_mode == :numbered
case paginator_mode
when :numbered
current_page >= total_pages
elsif paginator_mode == :sequential_before
when :sequential_before
size <= records_per_page
elsif paginator_mode == :sequential_after
when :sequential_after
false
end
end
@@ -98,11 +100,12 @@ module PaginationExtension
# we override a rails internal method to discard that extra record. See
# #2044, #3642.
def records
if paginator_mode == :sequential_before
case paginator_mode
when :sequential_before
super.first(records_per_page)
elsif paginator_mode == :sequential_after
when :sequential_after
super.first(records_per_page).reverse
elsif paginator_mode == :numbered
when :numbered
super
end
end

View File

@@ -20,7 +20,7 @@ module PostSets
end
def has_blank_wiki?
tag.present? && !wiki_page.present?
tag.present? && wiki_page.nil?
end
def wiki_page
@@ -94,7 +94,7 @@ module PostSets
end
def get_post_count
if %w(json atom xml).include?(format.downcase)
if %w[json atom xml].include?(format.downcase)
# no need to get counts for formats that don't use a paginator
nil
else

View File

@@ -17,14 +17,14 @@ class RateLimiter
case action
when "users:create"
rate, burst = 1.0/5.minutes, 10
rate, burst = 1.0 / 5.minutes, 10
when "emails:update", "sessions:create", "moderation_reports:create"
rate, burst = 1.0/1.minute, 10
rate, burst = 1.0 / 1.minute, 10
when "dmails:create", "comments:create", "forum_posts:create", "forum_topics:create"
rate, burst = 1.0/1.minute, 50
rate, burst = 1.0 / 1.minute, 50
when "comment_votes:create", "comment_votes:destroy", "post_votes:create",
"post_votes:destroy", "favorites:create", "favorites:destroy", "post_disapprovals:create"
rate, burst = 1.0/1.second, 200
rate, burst = 1.0 / 1.second, 200
else
rate = user.api_regen_multiplier
burst = 200

View File

@@ -55,7 +55,7 @@ module RecommenderService
if user.present?
raise User::PrivilegeError unless Pundit.policy!(CurrentUser.user, user).can_see_favorites?
max_recommendations = params.fetch(:max_recommendations, user.favorite_count + 500).to_i.clamp(0, 50000)
max_recommendations = params.fetch(:max_recommendations, user.favorite_count + 500).to_i.clamp(0, 50_000)
recs = RecommenderService.recommend_for_user(user, tags: params[:post_tags_match], limit: max_recommendations)
elsif post.present?
max_recommendations = params.fetch(:max_recommendations, 100).to_i.clamp(0, 1000)

View File

@@ -10,7 +10,7 @@ class ReportbooruService
reportbooru_server.present?
end
def missed_search_rankings(expires_in: 1.minutes)
def missed_search_rankings(expires_in: 1.minute)
return [] unless enabled?
response = http.cache(expires_in).get("#{reportbooru_server}/missed_searches")
@@ -20,11 +20,11 @@ class ReportbooruService
body.lines.map(&:split).map { [_1, _2.to_i] }
end
def post_search_rankings(date, expires_in: 1.minutes)
def post_search_rankings(date, expires_in: 1.minute)
request("#{reportbooru_server}/post_searches/rank?date=#{date}", expires_in)
end
def post_view_rankings(date, expires_in: 1.minutes)
def post_view_rankings(date, expires_in: 1.minute)
request("#{reportbooru_server}/post_views/rank?date=#{date}", expires_in)
end

View File

@@ -156,12 +156,12 @@ module Sources::Strategies
"https://twitter.com/i/web/status/#{status_id}"
elsif url =~ %r{\Ahttps?://(?:o|image-proxy-origin)\.twimg\.com/\d/proxy\.jpg\?t=(\w+)&}i
str = Base64.decode64($1)
source = URI.extract(str, ['http', 'https'])
source = URI.extract(str, %w[http https])
if source.any?
source = source[0]
if source =~ %r{^https?://twitpic.com/show/large/[a-z0-9]+}i
source.gsub!(%r{show/large/}, "")
index = source.rindex('.')
index = source.rindex(".")
source = source[0..index - 1]
end
source

View File

@@ -68,7 +68,7 @@ class TagCategory
end
def category_ids_regex
@@category_ids_regex ||= "[#{category_ids.join("")}]"
@@category_ids_regex ||= "[#{category_ids.join}]"
end
end

View File

@@ -82,7 +82,7 @@ class TagMover
old_cosplay_tag = "#{old_tag.name}_(cosplay)"
new_cosplay_tag = "#{new_tag.name}_(cosplay)"
if Tag.nonempty.where(name: old_cosplay_tag).exists?
if Tag.nonempty.exists?(name: old_cosplay_tag)
TagMover.new(old_cosplay_tag, new_cosplay_tag).move!
end
end

View File

@@ -16,7 +16,7 @@ module TagRelationshipRetirementService
if topic.nil?
CurrentUser.as(User.system) do
topic = ForumTopic.create!(creator: User.system, title: forum_topic_title, category_id: 1)
forum_post = ForumPost.create!(creator: User.system, body: forum_topic_body, topic: topic)
ForumPost.create!(creator: User.system, body: forum_topic_body, topic: topic)
end
end
topic
@@ -45,6 +45,6 @@ module TagRelationshipRetirementService
end
def is_unused?(name)
!Post.raw_tag_match(name).where("created_at > ?", THRESHOLD.ago).exists?
!Post.raw_tag_match(name).exists?(["created_at > ?", THRESHOLD.ago])
end
end

View File

@@ -1,8 +1,3 @@
require 'upload_service/controller_helper'
require 'upload_service/preprocessor'
require 'upload_service/replacer'
require 'upload_service/utils'
class UploadService
attr_reader :params, :post, :upload

View File

@@ -34,15 +34,13 @@ class UploadService
def in_progress?
if md5.present?
return Upload.where(status: "preprocessing", md5: md5).exists?
end
if Utils.is_downloadable?(source)
return Upload.where(status: "preprocessing", source: source).exists?
end
Upload.exists?(status: "preprocessing", md5: md5)
elsif Utils.is_downloadable?(source)
Upload.exists?(status: "preprocessing", source: source)
else
false
end
end
def predecessor
if md5.present?

View File

@@ -11,7 +11,7 @@ class UploadService
end
def comment_replacement_message(post, replacement)
%("#{replacement.creator.name}":[#{Routes.user_path(replacement.creator)}] replaced this post with a new file:\n\n#{replacement_message(post, replacement)})
%{"#{replacement.creator.name}":[#{Routes.user_path(replacement.creator)}] replaced this post with a new file:\n\n#{replacement_message(post, replacement)}}
end
def replacement_message(post, replacement)
@@ -49,7 +49,7 @@ class UploadService
truncated_source = source.gsub(%r{\Ahttps?://}, "").truncate(64, omission: "...#{source.last(32)}")
if source =~ %r{\Ahttps?://}i
%("#{truncated_source}":[#{source}])
%{"#{truncated_source}":[#{source}]}
else
truncated_source
end
@@ -70,7 +70,7 @@ class UploadService
return "file://#{repl.replacement_file.original_filename}"
end
if !upload.source.present?
if upload.source.blank?
raise "No source found in upload for replacement"
end

View File

@@ -14,7 +14,7 @@ class UploadService
end
def is_downloadable?(source)
source =~ /^https?:\/\//
source =~ %r{\Ahttps?://}
end
def generate_resizes(media_file)

View File

@@ -42,8 +42,8 @@ class UserDeletion
user.email_address = nil
user.last_logged_in_at = nil
user.last_forum_read_at = nil
user.favorite_tags = ''
user.blacklisted_tags = ''
user.favorite_tags = ""
user.blacklisted_tags = ""
user.hide_deleted_posts = false
user.show_deleted_children = false
user.time_zone = "Eastern Time (US & Canada)"

View File

@@ -32,22 +32,18 @@ class ArtistVersion < ApplicationRecord
extend SearchMethods
def previous
@previous ||= begin
ArtistVersion.where("artist_id = ? and created_at < ?", artist_id, created_at).order("created_at desc").limit(1).to_a
end
@previous ||= ArtistVersion.where("artist_id = ? and created_at < ?", artist_id, created_at).order("created_at desc").limit(1).to_a
@previous.first
end
def subsequent
@subsequent ||= begin
ArtistVersion.where("artist_id = ? and created_at > ?", artist_id, created_at).order("created_at asc").limit(1).to_a
end
@subsequent ||= ArtistVersion.where("artist_id = ? and created_at > ?", artist_id, created_at).order("created_at asc").limit(1).to_a
@subsequent.first
end
def current
@previous ||= begin
ArtistVersion.where("artist_id = ?", artist_id).order("created_at desc").limit(1).to_a
ArtistVersion.where(artist_id: artist_id).order("created_at desc").limit(1).to_a
end
@previous.first
end
@@ -66,17 +62,17 @@ class ArtistVersion < ApplicationRecord
end
def other_names_changed(type)
other = self.send(type)
other = send(type)
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
end
def urls_changed(type)
other = self.send(type)
other = send(type)
((urls - other.urls) | (other.urls - urls)).length.positive?
end
def was_deleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_deleted && !other.is_deleted
else
@@ -85,7 +81,7 @@ class ArtistVersion < ApplicationRecord
end
def was_undeleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_deleted && other.is_deleted
else
@@ -94,7 +90,7 @@ class ArtistVersion < ApplicationRecord
end
def was_banned(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_banned && !other.is_banned
else
@@ -103,7 +99,7 @@ class ArtistVersion < ApplicationRecord
end
def was_unbanned(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_banned && other.is_banned
else

View File

@@ -12,8 +12,8 @@ class Ban < ApplicationRecord
validates :reason, presence: true
validate :user, :validate_user_is_bannable, on: :create
scope :unexpired, -> { where("bans.created_at + bans.duration > ?", Time.now) }
scope :expired, -> { where("bans.created_at + bans.duration <= ?", Time.now) }
scope :unexpired, -> { where("bans.created_at + bans.duration > ?", Time.zone.now) }
scope :expired, -> { where("bans.created_at + bans.duration <= ?", Time.zone.now) }
scope :active, -> { unexpired }
def self.search(params)
@@ -48,7 +48,7 @@ class Ban < ApplicationRecord
end
def update_user_on_destroy
user.update_attribute(:is_banned, false)
user.update!(is_banned: false)
end
def user_name
@@ -68,7 +68,7 @@ class Ban < ApplicationRecord
end
def expired?
persisted? && expires_at < Time.now
persisted? && expires_at < Time.zone.now
end
def create_feedback

View File

@@ -1,17 +1,16 @@
class BulkUpdateRequest < ApplicationRecord
attr_accessor :title
attr_accessor :reason
attr_accessor :title, :reason
belongs_to :user
belongs_to :forum_topic, optional: true
belongs_to :forum_post, optional: true
belongs_to :approver, optional: true, class_name: "User"
validates_presence_of :reason, on: :create
validates_presence_of :script
validates_presence_of :title, if: ->(rec) {rec.forum_topic_id.blank?}
validates_presence_of :forum_topic, if: ->(rec) {rec.forum_topic_id.present?}
validates_inclusion_of :status, :in => %w(pending approved rejected)
validates :reason, presence: true, on: :create
validates :script, presence: true
validates :title, presence: true, if: ->(rec) { rec.forum_topic_id.blank? }
validates :forum_topic, presence: true, if: ->(rec) { rec.forum_topic_id.present? }
validates :status, inclusion: { in: %w[pending approved rejected] }
validate :validate_script, if: :script_changed?
before_save :update_tags, if: :script_changed?

View File

@@ -3,8 +3,8 @@ class Comment < ApplicationRecord
belongs_to :creator, class_name: "User"
belongs_to_updater
has_many :moderation_reports, as: :model
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
has_many :moderation_reports, as: :model, dependent: :destroy
has_many :votes, class_name: "CommentVote", dependent: :destroy
validates :body, presence: true, length: { maximum: 15_000 }, if: :body_changed?
@@ -20,9 +20,9 @@ class Comment < ApplicationRecord
deletable
mentionable(
:message_field => :body,
:title => ->(user_name) {"#{creator.name} mentioned you in a comment on post ##{post_id}"},
:body => ->(user_name) {"@#{creator.name} mentioned you in comment ##{id} on post ##{post_id}:\n\n[quote]\n#{DText.extract_mention(body, "@" + user_name)}\n[/quote]\n"}
message_field: :body,
title: ->(_user_name) {"#{creator.name} mentioned you in a comment on post ##{post_id}"},
body: ->(user_name) {"@#{creator.name} mentioned you in comment ##{id} on post ##{post_id}:\n\n[quote]\n#{DText.extract_mention(body, "@#{user_name}")}\n[/quote]\n"}
)
module SearchMethods
@@ -55,7 +55,7 @@ class Comment < ApplicationRecord
def update_last_commented_at_on_create
Post.where(:id => post_id).update_all(:last_commented_at => created_at)
if Comment.where("post_id = ?", post_id).count <= Danbooru.config.comment_threshold && !do_not_bump_post?
if Comment.where(post_id: post_id).count <= Danbooru.config.comment_threshold && !do_not_bump_post?
Post.where(:id => post_id).update_all(:last_comment_bumped_at => created_at)
end
end

View File

@@ -7,8 +7,8 @@ class CommentVote < ApplicationRecord
validate :validate_vote_is_unique, if: :is_deleted_changed?
validates :score, inclusion: { in: [-1, 1], message: "must be 1 or -1" }
before_create :update_score_on_create
before_save :update_score_on_delete_or_undelete, if: -> { !new_record? && is_deleted_changed? }
before_create :update_score_on_create
deletable

View File

@@ -1,5 +1,3 @@
require 'digest/sha1'
class Dmail < ApplicationRecord
validate :validate_sender_is_not_limited, on: :create
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?

View File

@@ -30,9 +30,9 @@ class ForumPost < ApplicationRecord
deletable
mentionable(
:message_field => :body,
:title => ->(user_name) {%{#{creator.name} mentioned you in topic ##{topic_id} (#{topic.title})}},
:body => ->(user_name) {%{@#{creator.name} mentioned you in topic ##{topic_id} ("#{topic.title}":[#{Routes.forum_topic_path(topic, page: forum_topic_page)}]):\n\n[quote]\n#{DText.extract_mention(body, "@" + user_name)}\n[/quote]\n}}
message_field: :body,
title: ->(_user_name) {%{#{creator.name} mentioned you in topic ##{topic_id} (#{topic.title})}},
body: ->(user_name) {%{@#{creator.name} mentioned you in topic ##{topic_id} ("#{topic.title}":[#{Routes.forum_topic_path(topic, page: forum_topic_page)}]):\n\n[quote]\n#{DText.extract_mention(body, "@#{user_name}")}\n[/quote]\n}}
)
module SearchMethods
@@ -74,7 +74,7 @@ class ForumPost < ApplicationRecord
end
def voted?(user, score)
votes.where(creator_id: user.id, score: score).exists?
votes.exists?(creator_id: user.id, score: score)
end
def autoreport_spam
@@ -149,7 +149,7 @@ class ForumPost < ApplicationRecord
def is_original_post?(original_post_id = nil)
if original_post_id
return id == original_post_id
id == original_post_id
else
ForumPost.exists?(["id = ? and id = (select _.id from forum_posts _ where _.topic_id = ? order by _.id asc limit 1)", id, topic_id])
end

View File

@@ -7,7 +7,7 @@ class ForumPostVote < ApplicationRecord
scope :up, -> {where(score: 1)}
scope :down, -> {where(score: -1)}
scope :by, ->(user_id) {where(creator_id: user_id)}
scope :excluding_user, ->(user_id) {where("creator_id <> ?", user_id)}
scope :excluding_user, ->(user_id) { where.not(creator_id: user_id) }
def self.visible(user)
where(forum_post: ForumPost.visible(user))
@@ -37,14 +37,13 @@ class ForumPostVote < ApplicationRecord
end
def vote_type
if score == 1
return "up"
elsif score == -1
return "down"
elsif score == 0
return "meh"
else
raise
case score
when 1
"up"
when -1
"down"
when 0
"meh"
end
end

View File

@@ -2,13 +2,13 @@ class ForumTopic < ApplicationRecord
CATEGORIES = {
0 => "General",
1 => "Tags",
2 => "Bugs & Features"
2 => "Bugs & Features",
}
MIN_LEVELS = {
None: 0,
Moderator: User::Levels::MODERATOR,
Admin: User::Levels::ADMIN
Admin: User::Levels::ADMIN,
}
belongs_to :creator, class_name: "User"
@@ -17,14 +17,14 @@ class ForumTopic < ApplicationRecord
has_many :forum_topic_visits
has_one :forum_topic_visit_by_current_user, -> { where(user_id: CurrentUser.id) }, class_name: "ForumTopicVisit"
has_one :original_post, -> { order(id: :asc) }, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic
has_many :bulk_update_requests, :foreign_key => "forum_topic_id"
has_many :tag_aliases, :foreign_key => "forum_topic_id"
has_many :tag_implications, :foreign_key => "forum_topic_id"
has_many :bulk_update_requests
has_many :tag_aliases
has_many :tag_implications
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
validates_associated :original_post
validates_inclusion_of :category_id, :in => CATEGORIES.keys
validates_inclusion_of :min_level, :in => MIN_LEVELS.values
validates :category_id, inclusion: { in: CATEGORIES.keys }
validates :min_level, inclusion: { in: MIN_LEVELS.values }
accepts_nested_attributes_for :original_post
after_update :update_orignal_post
@@ -129,9 +129,9 @@ class ForumTopic < ApplicationRecord
def mark_as_read!(user = CurrentUser.user)
return if user.is_anonymous?
match = ForumTopicVisit.where(:user_id => user.id, :forum_topic_id => id).first
if match
match.update_attribute(:last_read_at, updated_at)
visit = ForumTopicVisit.find_by(user_id: user.id, forum_topic_id: id)
if visit
visit.update!(last_read_at: updated_at)
else
ForumTopicVisit.create(:user_id => user.id, :forum_topic_id => id, :last_read_at => updated_at)
end

View File

@@ -9,7 +9,7 @@ class IpBan < ApplicationRecord
deletable
enum category: {
full: 0,
partial: 100
partial: 100,
}, _suffix: "ban"
def self.visible(user)

View File

@@ -53,7 +53,7 @@ class ModAction < ApplicationRecord
ip_ban_undelete: 163,
mass_update: 1000, # XXX unused
bulk_revert: 1001, # XXX unused
other: 2000
other: 2000,
}
def self.visible(user)

View File

@@ -2,9 +2,14 @@ class Note < ApplicationRecord
class RevertError < StandardError; end
attr_accessor :html_id
belongs_to :post
has_many :versions, -> {order("note_versions.id ASC")}, :class_name => "NoteVersion", :dependent => :destroy
validates_presence_of :x, :y, :width, :height, :body
validates :x, presence: true
validates :y, presence: true
validates :width, presence: true
validates :height, presence: true
validates :body, presence: true
validate :note_within_image
after_save :update_post
after_save :create_version
@@ -95,7 +100,7 @@ class Note < ApplicationRecord
def revert_to(version)
if id != version.note_id
raise RevertError.new("You cannot revert to a previous version of another note.")
raise RevertError, "You cannot revert to a previous version of another note."
end
self.x = version.x

View File

@@ -11,23 +11,17 @@ class NoteVersion < ApplicationRecord
end
def previous
@previous ||= begin
NoteVersion.where("note_id = ? and version < ?", note_id, version).order("updated_at desc").limit(1).to_a
end
@previous ||= NoteVersion.where("note_id = ? and version < ?", note_id, version).order("updated_at desc").limit(1).to_a
@previous.first
end
def subsequent
@subsequent ||= begin
NoteVersion.where("note_id = ? and version > ?", note_id, version).order("updated_at asc").limit(1).to_a
end
@subsequent ||= NoteVersion.where("note_id = ? and version > ?", note_id, version).order("updated_at asc").limit(1).to_a
@subsequent.first
end
def current
@current ||= begin
NoteVersion.where("note_id = ?", note_id).order("updated_at desc").limit(1).to_a
end
@current ||= NoteVersion.where(note_id: note_id).order("updated_at desc").limit(1).to_a
@current.first
end
@@ -42,17 +36,17 @@ class NoteVersion < ApplicationRecord
end
def was_moved(type)
other = self.send(type)
other = send(type)
x != other.x || y != other.y
end
def was_resized(type)
other = self.send(type)
other = send(type)
width != other.width || height != other.height
end
def was_deleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_active && other.is_active
else
@@ -61,7 +55,7 @@ class NoteVersion < ApplicationRecord
end
def was_undeleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_active && !other.is_active
else

View File

@@ -4,14 +4,14 @@ class Pool < ApplicationRecord
array_attribute :post_ids, parse: /\d+/, cast: :to_i
validates_uniqueness_of :name, case_sensitive: false, if: :name_changed?
validates :name, uniqueness: { case_sensitive: false }, if: :name_changed?
validate :validate_name, if: :name_changed?
validates_inclusion_of :category, :in => %w(series collection)
validates :category, inclusion: { in: %w[series collection] }
validate :updater_can_edit_deleted
before_validation :normalize_post_ids
before_validation :normalize_name
after_save :create_version
after_create :synchronize!
after_save :create_version
deletable
@@ -47,9 +47,10 @@ class Pool < ApplicationRecord
q = q.name_matches(params[:name_matches])
end
if params[:category] == "series"
case params[:category]
when "series"
q = q.series
elsif params[:category] == "collection"
when "collection"
q = q.collection
end
@@ -80,7 +81,7 @@ class Pool < ApplicationRecord
def self.named(name)
if name =~ /^\d+$/
where("pools.id = ?", name.to_i)
where(id: name.to_i)
elsif name
where_ilike(:name, normalize_name_for_search(name))
else
@@ -93,11 +94,8 @@ class Pool < ApplicationRecord
end
def versions
if PoolVersion.enabled?
PoolVersion.where("pool_id = ?", id).order("id asc")
else
raise "Archive service not configured"
end
raise NotImplementedError, "Archive service not configured" unless PoolVersion.enabled?
PoolVersion.where(pool_id: id).order("id asc")
end
def is_series?
@@ -126,7 +124,7 @@ class Pool < ApplicationRecord
def revert_to!(version)
if id != version.pool_id
raise RevertError.new("You cannot revert to a previous version of another pool.")
raise RevertError, "You cannot revert to a previous version of another pool."
end
self.post_ids = version.post_ids

View File

@@ -18,7 +18,7 @@ class PoolVersion < ApplicationRecord
end
def for_user(user_id)
where("updater_id = ?", user_id)
where(updater_id: user_id)
end
def for_post_id(post_id)
@@ -65,7 +65,7 @@ class PoolVersion < ApplicationRecord
def self.queue(pool, updater, updater_ip_addr)
# queue updates to sqs so that if archives goes down for whatever reason it won't
# block pool updates
raise NotImplementedError.new("Archive service is not configured.") if !enabled?
raise NotImplementedError, "Archive service is not configured." if !enabled?
json = {
pool_id: pool.id,
@@ -93,23 +93,17 @@ class PoolVersion < ApplicationRecord
end
def previous
@previous ||= begin
PoolVersion.where("pool_id = ? and version < ?", pool_id, version).order("version desc").limit(1).to_a
end
@previous ||= PoolVersion.where("pool_id = ? and version < ?", pool_id, version).order("version desc").limit(1).to_a
@previous.first
end
def subsequent
@subsequent ||= begin
PoolVersion.where("pool_id = ? and version > ?", pool_id, version).order("version asc").limit(1).to_a
end
@subsequent ||= PoolVersion.where("pool_id = ? and version > ?", pool_id, version).order("version asc").limit(1).to_a
@subsequent.first
end
def current
@current ||= begin
PoolVersion.where("pool_id = ?", pool_id).order("version desc").limit(1).to_a
end
@current ||= PoolVersion.where(pool_id: pool_id).order("version desc").limit(1).to_a
@current.first
end
@@ -126,12 +120,12 @@ class PoolVersion < ApplicationRecord
end
def posts_changed(type)
other = self.send(type)
other = send(type)
((post_ids - other.post_ids) | (other.post_ids - post_ids)).length.positive?
end
def was_deleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_deleted && !other.is_deleted
else
@@ -140,7 +134,7 @@ class PoolVersion < ApplicationRecord
end
def was_undeleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_deleted && other.is_deleted
else
@@ -149,7 +143,7 @@ class PoolVersion < ApplicationRecord
end
def was_activated(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_active && !other.is_active
else
@@ -158,7 +152,7 @@ class PoolVersion < ApplicationRecord
end
def was_deactivated(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_active && other.is_active
else

View File

@@ -18,8 +18,8 @@ class Post < ApplicationRecord
before_validation :parse_pixiv_id
before_validation :blank_out_nonexistent_parents
before_validation :remove_parent_loops
validates_uniqueness_of :md5, :on => :create, message: ->(obj, data) { "duplicate: #{Post.find_by_md5(obj.md5).id}"}
validates_inclusion_of :rating, in: %w(s q e), message: "rating must be s, q, or e"
validates :md5, uniqueness: { message: ->(post, _data) { "duplicate: #{Post.find_by_md5(post.md5).id}" }}, on: :create
validates :rating, inclusion: { in: %w[s q e], message: "rating must be s, q, or e" }
validates :source, length: { maximum: 1200 }
validate :added_tags_are_valid
validate :removed_tags_are_valid
@@ -79,8 +79,8 @@ class Post < ApplicationRecord
module ClassMethods
def delete_files(post_id, md5, file_ext, force: false)
if Post.where(md5: md5).exists? && !force
raise DeletionError.new("Files still in use; skipping deletion.")
if Post.exists?(md5: md5) && !force
raise DeletionError, "Files still in use; skipping deletion."
end
Danbooru.config.storage_manager.delete_file(post_id, md5, file_ext, :original)
@@ -302,7 +302,7 @@ class Post < ApplicationRecord
flag = flags.create(reason: reason, is_deletion: is_deletion, creator: CurrentUser.user)
if flag.errors.any?
raise PostFlag::Error.new(flag.errors.full_messages.join("; "))
raise PostFlag::Error, flag.errors.full_messages.join("; ")
end
end
@@ -311,7 +311,7 @@ class Post < ApplicationRecord
end
def disapproved_by?(user)
PostDisapproval.where(:user_id => user.id, :post_id => id).exists?
PostDisapproval.exists?(user_id: user.id, post_id: id)
end
def autoban
@@ -353,7 +353,7 @@ class Post < ApplicationRecord
end
def source_domain
return "" unless source =~ %r!\Ahttps?://!i
return "" unless source =~ %r{\Ahttps?://}i
url = Addressable::URI.parse(normalized_source)
url.domain
@@ -400,11 +400,11 @@ class Post < ApplicationRecord
end
def set_tag_count(category, tagcount)
self.send("tag_count_#{category}=", tagcount)
send("tag_count_#{category}=", tagcount)
end
def inc_tag_count(category)
set_tag_count(category, self.send("tag_count_#{category}") + 1)
set_tag_count(category, send("tag_count_#{category}") + 1)
end
def set_tag_counts
@@ -469,7 +469,7 @@ class Post < ApplicationRecord
normalized_tags = filter_metatags(normalized_tags)
normalized_tags = TagAlias.to_aliased(normalized_tags)
normalized_tags = remove_negated_tags(normalized_tags)
normalized_tags = %w(tagme) if normalized_tags.empty?
normalized_tags = %w[tagme] if normalized_tags.empty?
normalized_tags = add_automatic_tags(normalized_tags)
normalized_tags = remove_invalid_tags(normalized_tags)
normalized_tags = Tag.convert_cosplay_tags(normalized_tags)
@@ -496,11 +496,11 @@ class Post < ApplicationRecord
@negated_tags, tags = tags.partition {|x| x =~ /\A-/i}
@negated_tags = @negated_tags.map {|x| x[1..-1]}
@negated_tags = TagAlias.to_aliased(@negated_tags)
return tags - @negated_tags
tags - @negated_tags
end
def add_automatic_tags(tags)
tags -= %w(incredibly_absurdres absurdres highres lowres huge_filesize flash)
tags -= %w[incredibly_absurdres absurdres highres lowres huge_filesize flash]
if has_dimensions?
if image_width >= 10_000 || image_height >= 10_000
@@ -549,7 +549,7 @@ class Post < ApplicationRecord
tags -= ["animated_png"]
end
return tags
tags
end
def apply_casesensitive_metatags(tags)
@@ -574,7 +574,8 @@ class Post < ApplicationRecord
end
end
end
return tags
tags
end
def filter_metatags(tags)
@@ -582,7 +583,7 @@ class Post < ApplicationRecord
tags = apply_categorization_metatags(tags)
@post_metatags, tags = tags.partition {|x| x =~ /\A(?:-pool|pool|newpool|fav|-fav|child|-child|-favgroup|favgroup|upvote|downvote|status|-status|disapproved):/i}
apply_pre_metatags
return tags
tags
end
def apply_categorization_metatags(tags)
@@ -1043,7 +1044,7 @@ class Post < ApplicationRecord
def revert_to(target)
if id != target.post_id
raise RevertError.new("You cannot revert to a previous version of another post.")
raise RevertError, "You cannot revert to a previous version of another post."
end
self.tag_string = target.tags
@@ -1359,13 +1360,11 @@ class Post < ApplicationRecord
end
def updater_can_change_rating
if rating_changed? && is_rating_locked?
# Don't forbid changes if the rating lock was just now set in the same update.
if !is_rating_locked_changed?
if rating_changed? && is_rating_locked? && !is_rating_locked_changed?
errors.add(:rating, "is locked and cannot be changed. Unlock the post first.")
end
end
end
def uploader_is_not_limited
errors.add(:uploader, "have reached your upload limit") if uploader.upload_limit.limited?
@@ -1401,7 +1400,7 @@ class Post < ApplicationRecord
def has_artist_tag
return if !new_record?
return if source !~ %r!\Ahttps?://!
return if source !~ %r{\Ahttps?://}
return if has_tag?("artist_request") || has_tag?("official_art")
return if tags.any?(&:artist?)
return if Sources::Strategies.find(source).is_a?(Sources::Strategies::Null)

View File

@@ -10,7 +10,7 @@ class PostAppeal < ApplicationRecord
enum status: {
pending: 0,
succeeded: 1,
rejected: 2
rejected: 2,
}
scope :expired, -> { pending.where("post_appeals.created_at < ?", Danbooru.config.moderation_period.ago) }

View File

@@ -20,7 +20,7 @@ class PostApproval < ApplicationRecord
errors.add(:base, "You cannot approve a post you uploaded")
end
if post.approver == user || post.approvals.where(user: user).exists?
if post.approver == user || post.approvals.exists?(user: user)
errors.add(:base, "You have previously approved this post and cannot approve it again")
end
end

View File

@@ -5,7 +5,7 @@ class PostDisapproval < ApplicationRecord
belongs_to :post
belongs_to :user
validates :user, uniqueness: { scope: :post, message: "have already hidden this post" }
validates_inclusion_of :reason, in: REASONS
validates :reason, inclusion: { in: REASONS }
validate :validate_disapproval
scope :with_message, -> { where.not(message: nil) }

View File

@@ -4,6 +4,7 @@ class PostEvent
include ActiveModel::Serializers::Xml
attr_accessor :event
delegate :created_at, to: :event
def self.find_for_post(post_id)
@@ -62,11 +63,11 @@ class PostEvent
def attributes
{
"creator_id": nil,
"created_at": nil,
"reason": nil,
"status": nil,
"type": nil
creator_id: nil,
created_at: nil,
reason: nil,
status: nil,
type: nil,
}
end

View File

@@ -18,7 +18,7 @@ class PostFlag < ApplicationRecord
enum status: {
pending: 0,
succeeded: 1,
rejected: 2
rejected: 2,
}
scope :by_users, -> { where.not(creator: User.system) }

View File

@@ -9,7 +9,7 @@ class PostReplacement < ApplicationRecord
def initialize_fields
self.creator = CurrentUser.user
self.original_url = post.source
self.tags = post.tag_string + " " + self.tags.to_s
self.tags = "#{post.tag_string} #{tags}"
self.old_file_ext = post.file_ext
self.old_file_size = post.file_size

View File

@@ -81,7 +81,7 @@ class PostVersion < ApplicationRecord
def queue(post)
# queue updates to sqs so that if archives goes down for whatever reason it won't
# block post updates
raise NotImplementedError.new("Archive service is not configured") if !enabled?
raise NotImplementedError, "Archive service is not configured" if !enabled?
json = {
"post_id" => post.id,
@@ -92,7 +92,7 @@ class PostVersion < ApplicationRecord
"updater_ip_addr" => CurrentUser.ip_addr.to_s,
"updated_at" => post.updated_at.try(:iso8601),
"created_at" => post.created_at.try(:iso8601),
"tags" => post.tag_string
"tags" => post.tag_string,
}
msg = "add post version\n#{json.to_json}"
sqs_service.send_message(msg, message_group_id: "post:#{post.id}")
@@ -117,25 +117,21 @@ class PostVersion < ApplicationRecord
# HACK: if all the post versions for this post have already been preloaded,
# we can use that to avoid a SQL query.
if association(:post).loaded? && post && post.association(:versions).loaded?
ver = [post.versions.sort_by(&:version).reverse.find { |v| v.version < version }]
[post.versions.sort_by(&:version).reverse.find { |v| v.version < version }]
else
ver = PostVersion.where("post_id = ? and version < ?", post_id, version).order("version desc").limit(1).to_a
PostVersion.where("post_id = ? and version < ?", post_id, version).order("version desc").limit(1).to_a
end
end
@previous.first
end
def subsequent
@subsequent ||= begin
PostVersion.where("post_id = ? and version > ?", post_id, version).order("version asc").limit(1).to_a
end
@subsequent ||= PostVersion.where("post_id = ? and version > ?", post_id, version).order("version asc").limit(1).to_a
@subsequent.first
end
def current
@current ||= begin
PostVersion.where("post_id = ?", post_id).order("version desc").limit(1).to_a
end
@current ||= PostVersion.where(post_id: post_id).order("version desc").limit(1).to_a
@current.first
end
@@ -167,11 +163,11 @@ class PostVersion < ApplicationRecord
def changes
delta = {
:added_tags => added_tags,
:removed_tags => removed_tags,
:obsolete_removed_tags => [],
:obsolete_added_tags => [],
:unchanged_tags => []
added_tags: added_tags,
removed_tags: removed_tags,
obsolete_removed_tags: [],
obsolete_added_tags: [],
unchanged_tags: [],
}
return delta if post.nil?
@@ -252,9 +248,10 @@ class PostVersion < ApplicationRecord
removed = changes[:removed_tags] - changes[:obsolete_removed_tags]
added.each do |tag|
if tag =~ /^source:/
case tag
when /^source:/
post.source = ""
elsif tag =~ /^parent:/
when /^parent:/
post.parent_id = nil
else
escaped_tag = Regexp.escape(tag)

View File

@@ -3,6 +3,7 @@ class SavedSearch < ApplicationRecord
QUERY_LIMIT = 1000
attr_reader :disable_labels
belongs_to :user
normalize :query, :normalize_query
@@ -146,7 +147,7 @@ class SavedSearch < ApplicationRecord
PostQueryBuilder.new(query.to_s).normalized_query(sort: false).to_s
end
def queries_for(user_id, label: nil, options: {})
def queries_for(user_id, label: nil)
searches = SavedSearch.where(user_id: user_id)
searches = searches.labeled(label) if label.present?
queries = searches.map(&:normalized_query)
@@ -167,8 +168,8 @@ class SavedSearch < ApplicationRecord
end
def rewrite_query(old_name, new_name)
self.query.gsub!(/(?:\A| )([-~])?#{Regexp.escape(old_name)}(?: |\z)/i) { " #{$1}#{new_name} " }
self.query.strip!
query.gsub!(/(?:\A| )([-~])?#{Regexp.escape(old_name)}(?: |\z)/i) { " #{$1}#{new_name} " }
query.strip!
end
end

View File

@@ -11,7 +11,7 @@ class Tag < ApplicationRecord
validates :name, tag_name: true, uniqueness: true, on: :create
validates :name, tag_name: true, on: :name
validates_inclusion_of :category, in: TagCategory.category_ids
validates :category, inclusion: { in: TagCategory.category_ids }
after_save :update_category_cache, if: :saved_change_to_category?
after_save :update_category_post_counts, if: :saved_change_to_category?
@@ -21,13 +21,13 @@ class Tag < ApplicationRecord
module ApiMethods
def to_legacy_json
return {
"name" => name,
"id" => id,
"created_at" => created_at.try(:strftime, "%Y-%m-%d %H:%M"),
"count" => post_count,
"type" => category,
"ambiguous" => false
{
name: name,
id: id,
created_at: created_at.try(:strftime, "%Y-%m-%d %H:%M"),
count: post_count,
type: category,
ambiguous: false,
}.to_json
end
end
@@ -255,7 +255,7 @@ class Tag < ApplicationRecord
def abbreviation_matches(abbrev)
abbrev = abbrev.downcase.delete_prefix("/")
return none if abbrev !~ /\A[a-z0-9\*]*\z/
return none if abbrev !~ /\A[a-z0-9*]*\z/
where("regexp_replace(tags.name, ?, '\\1', 'g') LIKE ?", ABBREVIATION_REGEXP.source, abbrev.to_escaped_for_sql_like)
end
@@ -309,7 +309,7 @@ class Tag < ApplicationRecord
def names_matches_with_aliases(name, limit)
name = normalize_name(name)
wildcard_name = name + '*'
wildcard_name = "#{name}*"
query1 =
Tag

View File

@@ -21,7 +21,8 @@ class TagRelationship < ApplicationRecord
before_validation :normalize_names
validates :status, inclusion: { in: %w[active deleted retired] }
validates_presence_of :antecedent_name, :consequent_name
validates :antecedent_name, presence: true
validates :consequent_name, presence: true
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
validate :antecedent_and_consequent_are_different
@@ -110,7 +111,7 @@ class TagRelationship < ApplicationRecord
end
def self.approve!(antecedent_name:, consequent_name:, approver:, forum_topic: nil)
ProcessTagRelationshipJob.perform_later(class_name: self.name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
ProcessTagRelationshipJob.perform_later(class_name: name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
end
def self.model_restriction(table)

View File

@@ -62,13 +62,14 @@ class Upload < ApplicationRecord
end
attr_accessor :as_pending, :replaced_post, :file
belongs_to :uploader, :class_name => "User"
belongs_to :post, optional: true
before_validation :initialize_attributes, on: :create
before_validation :assign_rating_from_tags
# validates :source, format: { with: /\Ahttps?/ }, if: ->(record) {record.file.blank?}, on: :create
validates :rating, inclusion: { in: %w(q e s) }, allow_nil: true
validates :rating, inclusion: { in: %w[q e s] }, allow_nil: true
validates :md5, confirmation: true, if: ->(rec) { rec.md5_confirmation.present? }
validates_with FileValidator, on: :file
serialize :context, JSON
@@ -109,7 +110,7 @@ class Upload < ApplicationRecord
def delete_files
# md5 is blank if the upload errored out before downloading the file.
if is_completed? || md5.blank? || Upload.where(md5: md5).exists? || Post.where(md5: md5).exists?
if is_completed? || md5.blank? || Upload.exists?(md5: md5) || Post.exists?(md5: md5)
return
end
@@ -170,7 +171,7 @@ class Upload < ApplicationRecord
source = source.unicode_normalize(:nfc)
# percent encode unicode characters in urls
if source =~ %r!\Ahttps?://!i
if source =~ %r{\Ahttps?://}i
source = Addressable::URI.normalized_encode(source) rescue source
end
@@ -178,7 +179,7 @@ class Upload < ApplicationRecord
end
def source_url
return nil unless source =~ %r!\Ahttps?://!i
return nil unless source =~ %r{\Ahttps?://}i
Addressable::URI.heuristic_parse(source) rescue nil
end
end

View File

@@ -1,5 +1,3 @@
require 'digest/sha1'
class User < ApplicationRecord
class Error < StandardError; end
class PrivilegeError < StandardError; end
@@ -17,10 +15,7 @@ class User < ApplicationRecord
end
# Used for `before_action :<role>_only`. Must have a corresponding `is_<role>?` method.
Roles = Levels.constants.map(&:downcase) + [
:banned,
:approver
]
Roles = Levels.constants.map(&:downcase) + %i[banned approver]
# candidates for removal:
# - enable_post_navigation (disabled by 700)
@@ -36,7 +31,7 @@ class User < ApplicationRecord
# - enable_recommended_posts
# - has_mail
# - is_super_voter
BOOLEAN_ATTRIBUTES = %w(
BOOLEAN_ATTRIBUTES = %w[
is_banned
has_mail
receive_email_notifications
@@ -67,7 +62,7 @@ class User < ApplicationRecord
no_feedback
requires_verification
is_verified
)
]
DEFAULT_BLACKLIST = ["spoilers", "guro", "scat", "furry -rating:s"].join("\n")
@@ -104,10 +99,10 @@ class User < ApplicationRecord
after_initialize :initialize_attributes, if: :new_record?
validates :name, user_name: true, on: :create
validates_length_of :password, :minimum => 5, :if => ->(rec) { rec.new_record? || rec.password.present?}
validates_inclusion_of :default_image_size, :in => %w(large original)
validates_inclusion_of :per_page, in: (1..PostSets::Post::MAX_PER_PAGE)
validates_confirmation_of :password
validates :password, length: { minimum: 5 }, if: ->(rec) { rec.new_record? || rec.password.present? }
validates :default_image_size, inclusion: { in: %w[large original] }
validates :per_page, inclusion: { in: (1..PostSets::Post::MAX_PER_PAGE) }
validates :password, confirmation: true
validates :comment_threshold, inclusion: { in: (-100..5) }
before_validation :normalize_blacklisted_tags
before_create :promote_to_owner_if_first_user
@@ -233,13 +228,13 @@ class User < ApplicationRecord
end
def anonymous
user = User.new(name: "Anonymous", level: Levels::ANONYMOUS, created_at: Time.now)
user = User.new(name: "Anonymous", level: Levels::ANONYMOUS, created_at: Time.zone.now)
user.freeze.readonly!
user
end
def level_hash
return {
{
"Restricted" => Levels::RESTRICTED,
"Member" => Levels::MEMBER,
"Gold" => Levels::GOLD,
@@ -247,7 +242,7 @@ class User < ApplicationRecord
"Builder" => Levels::BUILDER,
"Moderator" => Levels::MODERATOR,
"Admin" => Levels::ADMIN,
"Owner" => Levels::OWNER
"Owner" => Levels::OWNER,
}
end
@@ -293,7 +288,7 @@ class User < ApplicationRecord
def promote_to_owner_if_first_user
return if Rails.env.test?
if name != Danbooru.config.system_user && !User.where(level: Levels::OWNER).exists?
if name != Danbooru.config.system_user && !User.exists?(level: Levels::OWNER)
self.level = Levels::OWNER
self.can_approve_posts = true
self.can_upload_free = true
@@ -386,12 +381,12 @@ class User < ApplicationRecord
end
def rewrite_blacklist(old_name, new_name)
self.blacklisted_tags.gsub!(/(?:^| )([-~])?#{Regexp.escape(old_name)}(?: |$)/i) { " #{$1}#{new_name} " }
blacklisted_tags.gsub!(/(?:^| )([-~])?#{Regexp.escape(old_name)}(?: |$)/i) { " #{$1}#{new_name} " }
end
def normalize_blacklisted_tags
return unless blacklisted_tags.present?
self.blacklisted_tags = self.blacklisted_tags.lines.map(&:strip).join("\n")
self.blacklisted_tags = blacklisted_tags.lines.map(&:strip).join("\n")
end
end
@@ -615,7 +610,8 @@ class User < ApplicationRecord
params = params.dup
params[:name_matches] = params.delete(:name) if params[:name].present?
q = search_attributes(params,
q = search_attributes(
params,
:id, :created_at, :updated_at, :name, :level, :post_upload_count,
:post_update_count, :note_update_count, :favorite_count, :posts,
:note_versions, :artist_commentary_versions, :post_appeals,

View File

@@ -1,11 +1,12 @@
class UserFeedback < ApplicationRecord
self.table_name = "user_feedback"
attr_accessor :disable_dmail_notification
belongs_to :user
belongs_to :creator, class_name: "User"
attr_accessor :disable_dmail_notification
validates_presence_of :body, :category
validates_inclusion_of :category, :in => %w(positive negative neutral)
validates :body, presence: true
validates :category, presence: true, inclusion: { in: %w[positive negative neutral] }
after_create :create_dmail, unless: :disable_dmail_notification
after_update(:if => ->(rec) { CurrentUser.id != rec.creator_id}) do |rec|
ModAction.log(%{#{CurrentUser.user.name} updated user feedback for "#{rec.user.name}":#{Routes.user_path(rec.user)}}, :user_feedback_update)

View File

@@ -4,7 +4,8 @@ class UserNameChangeRequest < ApplicationRecord
validate :not_limited, on: :create
validates :desired_name, user_name: true, confirmation: true, on: :create
validates_presence_of :original_name, :desired_name
validates :original_name, presence: true
validates :desired_name, presence: true
after_create :update_name!
@@ -28,7 +29,7 @@ class UserNameChangeRequest < ApplicationRecord
end
def not_limited
if UserNameChangeRequest.unscoped.where(user: user).where("created_at >= ?", 1.week.ago).exists?
if UserNameChangeRequest.unscoped.where(user: user).exists?(["created_at >= ?", 1.week.ago])
errors.add(:base, "You can only submit one name change request per week")
end
end

View File

@@ -5,7 +5,7 @@ class UserUpgrade < ApplicationRecord
enum upgrade_type: {
gold: 0,
platinum: 10,
gold_to_platinum: 20
gold_to_platinum: 20,
}, _suffix: "upgrade"
enum status: {
@@ -175,7 +175,7 @@ class UserUpgrade < ApplicationRecord
country: country,
is_gift: is_gift?,
level: level,
},
}
)
update!(stripe_id: checkout.id)

View File

@@ -118,13 +118,13 @@ class WikiPage < ApplicationRecord
tag_was = Tag.find_by_name(Tag.normalize_name(title_was))
if tag_was.present? && !tag_was.empty?
warnings.add(:base, %!Warning: {{#{title_was}}} still has #{tag_was.post_count} #{"post".pluralize(tag_was.post_count)}. Be sure to move the posts!)
warnings.add(:base, %{Warning: {{#{title_was}}} still has #{tag_was.post_count} #{"post".pluralize(tag_was.post_count)}. Be sure to move the posts})
end
broken_wikis = WikiPage.linked_to(title_was)
if broken_wikis.count > 0
broken_wiki_search = Routes.wiki_pages_path(search: { linked_to: title_was })
warnings.add(:base, %!Warning: [[#{title_was}]] is still linked from "#{broken_wikis.count} #{"other wiki page".pluralize(broken_wikis.count)}":[#{broken_wiki_search}]. Update #{(broken_wikis.count > 1) ? "these wikis" : "this wiki"} to link to [[#{title}]] instead!)
warnings.add(:base, %{Warning: [[#{title_was}]] is still linked from "#{broken_wikis.count} #{"other wiki page".pluralize(broken_wikis.count)}":[#{broken_wiki_search}]. Update #{(broken_wikis.count > 1) ? "these wikis" : "this wiki"} to link to [[#{title}]] instead})
end
end
@@ -136,7 +136,7 @@ class WikiPage < ApplicationRecord
def revert_to(version)
if id != version.wiki_page_id
raise RevertError.new("You cannot revert to a previous version of another wiki page.")
raise RevertError, "You cannot revert to a previous version of another wiki page."
end
self.title = version.title

View File

@@ -21,23 +21,17 @@ class WikiPageVersion < ApplicationRecord
end
def previous
@previous ||= begin
WikiPageVersion.where("wiki_page_id = ? and id < ?", wiki_page_id, id).order("id desc").limit(1).to_a
end
@previous ||= WikiPageVersion.where("wiki_page_id = ? and id < ?", wiki_page_id, id).order("id desc").limit(1).to_a
@previous.first
end
def subsequent
@subsequent ||= begin
WikiPageVersion.where("wiki_page_id = ? and id > ?", wiki_page_id, id).order("id asc").limit(1).to_a
end
@subsequent ||= WikiPageVersion.where("wiki_page_id = ? and id > ?", wiki_page_id, id).order("id asc").limit(1).to_a
@subsequent.first
end
def current
@current ||= begin
WikiPageVersion.where("wiki_page_id = ?", wiki_page_id).order("id desc").limit(1).to_a
end
@current ||= WikiPageVersion.where(wiki_page_id: wiki_page_id).order("id desc").limit(1).to_a
@current.first
end
@@ -52,12 +46,12 @@ class WikiPageVersion < ApplicationRecord
end
def other_names_changed(type)
other = self.send(type)
other = send(type)
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
end
def was_deleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
is_deleted && !other.is_deleted
else
@@ -66,7 +60,7 @@ class WikiPageVersion < ApplicationRecord
end
def was_undeleted(type)
other = self.send(type)
other = send(type)
if type == "previous"
!is_deleted && other.is_deleted
else

View File

@@ -24,7 +24,7 @@ class ApiKeyPolicy < ApplicationPolicy
end
def permitted_attributes
[:name, :permitted_ip_addresses, permissions: []]
[:name, :permitted_ip_addresses, { permissions: [] }]
end
def api_attributes

View File

@@ -69,7 +69,7 @@ class ApplicationPolicy
# The list of attributes that are permitted to be returned by the API.
def api_attributes
# XXX allow inet
record.class.attribute_types.reject { |name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
record.class.attribute_types.reject { |_name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
end
# The list of attributes that are permitted to be used as data-* attributes

View File

@@ -16,6 +16,6 @@ class FavoriteGroupPolicy < ApplicationPolicy
end
def permitted_attributes
[:name, :post_ids_string, :is_public, :post_ids, post_ids: []]
[:name, :post_ids_string, :is_public, :post_ids, { post_ids: [] }]
end
end

View File

@@ -34,7 +34,7 @@ class ForumTopicPolicy < ApplicationPolicy
def permitted_attributes
[
:title, :category_id, { original_post_attributes: [:id, :body] },
([:is_sticky, :is_locked, :min_level] if moderate?)
([:is_sticky, :is_locked, :min_level] if moderate?),
].compact.flatten
end

View File

@@ -20,7 +20,7 @@ class PoolPolicy < ApplicationPolicy
end
def permitted_attributes
[:name, :description, :category, :post_ids, :post_ids_string, post_ids: []]
[:name, :description, :category, :post_ids, :post_ids_string, { post_ids: [] }]
end
def api_attributes

View File

@@ -8,12 +8,14 @@ class PostReplacementPolicy < ApplicationPolicy
end
def permitted_attributes_for_create
[:replacement_url, :replacement_file, :final_source, :tags]
%i[replacement_url replacement_file final_source tags]
end
def permitted_attributes_for_update
[:old_file_ext, :old_file_size, :old_image_width, :old_image_height,
:old_md5, :file_ext, :file_size, :image_width, :image_height, :md5,
:original_url, :replacement_url]
%i[
old_file_ext old_file_size old_image_width old_image_height old_md5
file_ext file_size image_width image_height md5 original_url
replacement_url
]
end
end

View File

@@ -36,15 +36,15 @@ class UserPolicy < ApplicationPolicy
end
def permitted_attributes_for_update
[
:comment_threshold, :default_image_size, :favorite_tags,
:blacklisted_tags, :time_zone, :per_page, :custom_style, :theme,
:receive_email_notifications, :always_resize_images,
:new_post_navigation_layout, :enable_private_favorites,
:hide_deleted_posts, :style_usernames, :show_deleted_children,
:disable_categorized_saved_searches, :disable_tagged_filenames,
:disable_cropped_thumbnails, :disable_mobile_gestures, :enable_safe_mode,
:enable_desktop_mode, :disable_post_tooltips,
%i[
comment_threshold default_image_size favorite_tags
blacklisted_tags time_zone per_page custom_style theme
receive_email_notifications always_resize_images
new_post_navigation_layout enable_private_favorites
hide_deleted_posts style_usernames show_deleted_children
disable_categorized_saved_searches disable_tagged_filenames
disable_cropped_thumbnails disable_mobile_gestures enable_safe_mode
enable_desktop_mode disable_post_tooltips
].compact
end

View File

@@ -1,5 +1,6 @@
class PostPresenter
attr_reader :pool, :next_post_in_pool
delegate :split_tag_list_text, to: :tag_set_presenter
def initialize(post)

View File

@@ -55,7 +55,7 @@ class TagSetPresenter
end
def ordered_tags
names_to_tags = tags.map { |tag| [tag.name, tag] }.to_h
names_to_tags = tags.index_by(&:name)
tag_names.map do |name|
names_to_tags[name] || Tag.new(name: name).freeze