rubocop: fix various Rubocop warnings.
This commit is contained in:
57
.rubocop.yml
57
.rubocop.yml
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)/, "<\\1")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class UploadService
|
||||
end
|
||||
|
||||
def is_downloadable?(source)
|
||||
source =~ /^https?:\/\//
|
||||
source =~ %r{\Ahttps?://}
|
||||
end
|
||||
|
||||
def generate_resizes(media_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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,7 +9,7 @@ class IpBan < ApplicationRecord
|
||||
deletable
|
||||
enum category: {
|
||||
full: 0,
|
||||
partial: 100
|
||||
partial: 100,
|
||||
}, _suffix: "ban"
|
||||
|
||||
def self.visible(user)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user