rubocop: fix various style issues.

This commit is contained in:
evazion
2019-12-22 16:21:58 -06:00
parent 09f6a84660
commit 309821bf73
288 changed files with 912 additions and 962 deletions

View File

@@ -1,7 +1,7 @@
# Add your own tasks in files placed in lib/tasks ending in .rake, # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__) require File.expand_path('config/application', __dir__)
require 'rake' require 'rake'
Rails.application.load_tasks Rails.application.load_tasks

View File

@@ -16,14 +16,14 @@ class ApplicationController < ActionController::Base
rescue_from Exception, :with => :rescue_exception rescue_from Exception, :with => :rescue_exception
protected
def self.rescue_with(*klasses, status: 500) def self.rescue_with(*klasses, status: 500)
rescue_from *klasses do |exception| rescue_from(*klasses) do |exception|
render_error_page(status, exception) render_error_page(status, exception)
end end
end end
protected
def enable_cors def enable_cors
response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Origin"] = "*"
end end
@@ -61,7 +61,7 @@ class ApplicationController < ActionController::Base
when ActionController::RoutingError when ActionController::RoutingError
render_error_page(405, exception) render_error_page(405, exception)
when ActionController::UnknownFormat, ActionView::MissingTemplate when ActionController::UnknownFormat, ActionView::MissingTemplate
render_error_page(406, exception, message: "#{request.format.to_s} is not a supported format for this page") render_error_page(406, exception, message: "#{request.format} is not a supported format for this page")
when PaginationExtension::PaginationError when PaginationExtension::PaginationError
render_error_page(410, exception, template: "static/pagination_error", message: "You cannot go beyond page #{Danbooru.config.max_numbered_pages}.") render_error_page(410, exception, template: "static/pagination_error", message: "You cannot go beyond page #{Danbooru.config.max_numbered_pages}.")
when Post::SearchError when Post::SearchError
@@ -80,7 +80,7 @@ class ApplicationController < ActionController::Base
def render_error_page(status, exception, message: exception.message, template: "static/error", format: request.format.symbol) def render_error_page(status, exception, message: exception.message, template: "static/error", format: request.format.symbol)
@exception = exception @exception = exception
@expected = status < 500 @expected = status < 500
@message = message.encode("utf-8", { invalid: :replace, undef: :replace }) @message = message.encode("utf-8", invalid: :replace, undef: :replace)
@backtrace = Rails.backtrace_cleaner.clean(@exception.backtrace) @backtrace = Rails.backtrace_cleaner.clean(@exception.backtrace)
format = :html unless format.in?(%i[html json xml js atom]) format = :html unless format.in?(%i[html json xml js atom])

View File

@@ -34,7 +34,7 @@ class ArtistCommentariesController < ApplicationController
@artist_commentary.revert_to!(@version) @artist_commentary.revert_to!(@version)
end end
private private
def commentary_params def commentary_params
params.fetch(:artist_commentary, {}).except(:post_id).permit(%i[ params.fetch(:artist_commentary, {}).except(:post_id).permit(%i[

View File

@@ -5,7 +5,7 @@ class ArtistUrlsController < ApplicationController
def index def index
@artist_urls = ArtistUrl.includes(:artist).paginated_search(params) @artist_urls = ArtistUrl.includes(:artist).paginated_search(params)
respond_with(@artist_urls) do |format| respond_with(@artist_urls) do |format|
format.json { render json: @artist_urls.to_json(include: "artist",) } format.json { render json: @artist_urls.to_json(include: "artist") }
format.xml { render xml: @artist_urls.to_xml(include: "artist", root: "artist-urls") } format.xml { render xml: @artist_urls.to_xml(include: "artist", root: "artist-urls") }
end end
end end
@@ -16,7 +16,7 @@ class ArtistUrlsController < ApplicationController
respond_with(@artist_url) respond_with(@artist_url)
end end
private private
def artist_url_params def artist_url_params
permitted_params = %i[is_active] permitted_params = %i[is_active]

View File

@@ -85,7 +85,7 @@ class ArtistsController < ApplicationController
end end
end end
private private
def load_artist def load_artist
@artist = Artist.find(params[:id]) @artist = Artist.find(params[:id])

View File

@@ -72,7 +72,8 @@ class CommentsController < ApplicationController
respond_with(@comment) respond_with(@comment)
end end
private private
def index_for_post def index_for_post
@post = Post.find(params[:post_id]) @post = Post.find(params[:post_id])
@comments = @post.comments @comments = @post.comments

View File

@@ -3,8 +3,8 @@ class CountsController < ApplicationController
def posts def posts
@count = Post.fast_count( @count = Post.fast_count(
params[:tags], params[:tags],
timeout: CurrentUser.statement_timeout, timeout: CurrentUser.statement_timeout,
raise_on_timeout: true, raise_on_timeout: true,
skip_cache: params[:skip_cache] skip_cache: params[:skip_cache]
) )

View File

@@ -60,7 +60,7 @@ class DmailsController < ApplicationController
@dmail.update_column(:is_spam, false) @dmail.update_column(:is_spam, false)
end end
private private
def check_privilege(dmail) def check_privilege(dmail)
if !dmail.visible_to?(CurrentUser.user, params[:key]) if !dmail.visible_to?(CurrentUser.user, params[:key])

View File

@@ -28,7 +28,8 @@ module Explore
render :layout => "blank" render :layout => "blank"
end end
private private
def set_date def set_date
@date = params[:date] ? Date.parse(params[:date]) : Date.today @date = params[:date] ? Date.parse(params[:date]) : Date.today
end end

View File

@@ -19,7 +19,7 @@ class ForumPostVotesController < ApplicationController
respond_with(@forum_post_vote) respond_with(@forum_post_vote)
end end
private private
def forum_post_vote_params def forum_post_vote_params
params.fetch(:forum_post_vote, {}).permit(:score) params.fetch(:forum_post_vote, {}).permit(:score)

View File

@@ -4,10 +4,10 @@ class ForumPostsController < ApplicationController
before_action :load_post, :only => [:edit, :show, :update, :destroy, :undelete] before_action :load_post, :only => [:edit, :show, :update, :destroy, :undelete]
before_action :check_min_level, :only => [:edit, :show, :update, :destroy, :undelete] before_action :check_min_level, :only => [:edit, :show, :update, :destroy, :undelete]
skip_before_action :api_check skip_before_action :api_check
def new def new
if params[:topic_id] if params[:topic_id]
@forum_topic = ForumTopic.find(params[:topic_id]) @forum_topic = ForumTopic.find(params[:topic_id])
raise User::PrivilegeError.new unless @forum_topic.visible?(CurrentUser.user) raise User::PrivilegeError.new unless @forum_topic.visible?(CurrentUser.user)
end end
if params[:post_id] if params[:post_id]
@@ -66,7 +66,8 @@ class ForumPostsController < ApplicationController
respond_with(@forum_post) respond_with(@forum_post)
end end
private private
def load_post def load_post
@forum_post = ForumPost.find(params[:id]) @forum_post = ForumPost.find(params[:id])
@forum_topic = @forum_post.topic @forum_topic = @forum_post.topic

View File

@@ -93,13 +93,12 @@ class ForumTopicsController < ApplicationController
def unsubscribe def unsubscribe
subscription = ForumSubscription.where(:forum_topic_id => @forum_topic.id, :user_id => CurrentUser.user.id).first subscription = ForumSubscription.where(:forum_topic_id => @forum_topic.id, :user_id => CurrentUser.user.id).first
if subscription subscription&.destroy
subscription.destroy
end
respond_with(@forum_topic) respond_with(@forum_topic)
end end
private private
def normalize_search def normalize_search
if params[:title_matches] if params[:title_matches]
params[:search] ||= {} params[:search] ||= {}

View File

@@ -5,13 +5,12 @@ class IpAddressesController < ApplicationController
def index def index
if search_params[:group_by] == "ip_addr" if search_params[:group_by] == "ip_addr"
@ip_addresses = IpAddress.search(search_params).group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen]).paginate(params[:page], limit: params[:limit] || 1000) @ip_addresses = IpAddress.search(search_params).group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen]).paginate(params[:page], limit: params[:limit] || 1000)
respond_with(@ip_addresses)
elsif search_params[:group_by] == "user" elsif search_params[:group_by] == "user"
@ip_addresses = IpAddress.includes(:user).search(search_params).group_by_user.paginate(params[:page], limit: params[:limit] || 1000) @ip_addresses = IpAddress.includes(:user).search(search_params).group_by_user.paginate(params[:page], limit: params[:limit] || 1000)
respond_with(@ip_addresses)
else else
@ip_addresses = IpAddress.includes(:user, :model).paginated_search(params) @ip_addresses = IpAddress.includes(:user, :model).paginated_search(params)
respond_with(@ip_addresses)
end end
respond_with(@ip_addresses)
end end
end end

View File

@@ -33,7 +33,8 @@ class LegacyController < ApplicationController
render :plain => "this resource is no longer available", :status => 410 render :plain => "this resource is no longer available", :status => 410
end end
private private
def tag_query def tag_query
params[:tags] || (params[:post] && params[:post][:tags]) params[:tags] || (params[:post] && params[:post][:tags])
end end

View File

@@ -1,7 +1,7 @@
module Maintenance module Maintenance
module User module User
class EmailNotificationsController < ApplicationController class EmailNotificationsController < ApplicationController
class VerificationError < Exception ; end class VerificationError < Exception; end
before_action :validate_sig, :only => [:destroy] before_action :validate_sig, :only => [:destroy]
rescue_from VerificationError, :with => :render_403 rescue_from VerificationError, :with => :render_403
@@ -15,7 +15,7 @@ module Maintenance
@user.save @user.save
end end
private private
def render_403 def render_403
render plain: "", :status => 403 render plain: "", :status => 403

View File

@@ -2,7 +2,7 @@ module Moderator
module Post module Post
class QueuesController < ApplicationController class QueuesController < ApplicationController
RANDOM_COUNT = 12 RANDOM_COUNT = 12
respond_to :html, :json respond_to :html, :json
before_action :approver_only before_action :approver_only
skip_before_action :api_check skip_before_action :api_check
@@ -38,7 +38,7 @@ module Moderator
respond_with(@posts) respond_with(@posts)
end end
protected protected
def per_page def per_page
cookies["mq_per_page"] || search_params[:per_page] || 25 cookies["mq_per_page"] || search_params[:per_page] || 25

View File

@@ -27,7 +27,8 @@ class PoolElementsController < ApplicationController
@pools @pools
end end
private private
def append_pool_to_session(pool) def append_pool_to_session(pool)
recent_pool_ids = session[:recent_pool_ids].to_s.scan(/\d+/) recent_pool_ids = session[:recent_pool_ids].to_s.scan(/\d+/)
recent_pool_ids << pool.id.to_s recent_pool_ids << pool.id.to_s

View File

@@ -22,7 +22,7 @@ class PoolVersionsController < ApplicationController
end end
end end
private private
def set_timeout def set_timeout
PoolArchive.connection.execute("SET statement_timeout = #{CurrentUser.user.statement_timeout}") PoolArchive.connection.execute("SET statement_timeout = #{CurrentUser.user.statement_timeout}")

View File

@@ -23,13 +23,14 @@ class PostReplacementsController < ApplicationController
end end
def index def index
params[:search][:post_id] = params.delete(:post_id) if params.has_key?(:post_id) params[:search][:post_id] = params.delete(:post_id) if params.key?(:post_id)
@post_replacements = PostReplacement.paginated_search(params) @post_replacements = PostReplacement.paginated_search(params)
respond_with(@post_replacements) respond_with(@post_replacements)
end end
private private
def create_params def create_params
params.require(:post_replacement).permit(:replacement_url, :replacement_file, :final_source, :tags) params.require(:post_replacement).permit(:replacement_url, :replacement_file, :final_source, :tags)
end end

View File

@@ -58,7 +58,7 @@ class PostsController < ApplicationController
if @post.visible? if @post.visible?
@post.revert_to!(@version) @post.revert_to!(@version)
end end
respond_with(@post) do |format| respond_with(@post) do |format|
format.js format.js
end end
@@ -68,7 +68,7 @@ class PostsController < ApplicationController
@post = Post.find(params[:id]) @post = Post.find(params[:id])
@other_post = Post.find(params[:other_post_id].to_i) @other_post = Post.find(params[:other_post_id].to_i)
@post.copy_notes_to(@other_post) @post.copy_notes_to(@other_post)
if @post.errors.any? if @post.errors.any?
@error_message = @post.errors.full_messages.join("; ") @error_message = @post.errors.full_messages.join("; ")
render :json => {:success => false, :reason => @error_message}.to_json, :status => 400 render :json => {:success => false, :reason => @error_message}.to_json, :status => 400
@@ -91,7 +91,7 @@ class PostsController < ApplicationController
respond_with_post_after_update(@post) respond_with_post_after_update(@post)
end end
private private
def tag_query def tag_query
params[:tags] || (params[:post] && params[:post][:tags]) params[:tags] || (params[:post] && params[:post][:tags])
@@ -109,7 +109,7 @@ private
render :template => "static/error", :status => 500 render :template => "static/error", :status => 500
else else
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], :favgroup_id => params[:favgroup_id]} 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) redirect_to post_path(post, response_params)
end end
end end

View File

@@ -28,6 +28,6 @@ class SessionsController < ApplicationController
end end
def sign_out def sign_out
destroy() destroy
end end
end end

View File

@@ -40,7 +40,7 @@ class TagAliasesController < ApplicationController
respond_with(@tag_alias, :location => tag_alias_path(@tag_alias)) respond_with(@tag_alias, :location => tag_alias_path(@tag_alias))
end end
private private
def tag_alias_params def tag_alias_params
params.require(:tag_alias).permit(%i[antecedent_name consequent_name forum_topic_id skip_secondary_validations]) params.require(:tag_alias).permit(%i[antecedent_name consequent_name forum_topic_id skip_secondary_validations])

View File

@@ -40,7 +40,7 @@ class TagImplicationsController < ApplicationController
respond_with(@tag_implication, :location => tag_implication_path(@tag_implication)) respond_with(@tag_implication, :location => tag_implication_path(@tag_implication))
end end
private private
def tag_implication_params def tag_implication_params
params.require(:tag_implication).permit(%i[antecedent_name consequent_name forum_topic_id skip_secondary_validations]) params.require(:tag_implication).permit(%i[antecedent_name consequent_name forum_topic_id skip_secondary_validations])

View File

@@ -37,7 +37,8 @@ class TagsController < ApplicationController
respond_with(@tag) respond_with(@tag)
end end
private private
def check_privilege(tag) def check_privilege(tag)
raise User::PrivilegeError unless tag.editable_by?(CurrentUser.user) raise User::PrivilegeError unless tag.editable_by?(CurrentUser.user)
end end

View File

@@ -99,7 +99,7 @@ class UsersController < ApplicationController
private private
def check_privilege(user) def check_privilege(user)
raise User::PrivilegeError unless (user.id == CurrentUser.id || CurrentUser.is_admin?) raise User::PrivilegeError unless user.id == CurrentUser.id || CurrentUser.is_admin?
end end
def user_params(context) def user_params(context)

View File

@@ -10,7 +10,7 @@ class WikiPagesController < ApplicationController
end end
def edit def edit
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id]) @wiki_page, _found_by = WikiPage.find_by_id_or_title(params[:id])
respond_with(@wiki_page) respond_with(@wiki_page)
end end
@@ -49,7 +49,7 @@ class WikiPagesController < ApplicationController
end end
def update def update
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id]) @wiki_page, _found_by = WikiPage.find_by_id_or_title(params[:id])
@wiki_page.update(wiki_page_params(:update)) @wiki_page.update(wiki_page_params(:update))
flash[:notice] = @wiki_page.warnings.full_messages.join(".\n \n") if @wiki_page.warnings.any? flash[:notice] = @wiki_page.warnings.full_messages.join(".\n \n") if @wiki_page.warnings.any?
@@ -57,13 +57,13 @@ class WikiPagesController < ApplicationController
end end
def destroy def destroy
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id]) @wiki_page, _found_by = WikiPage.find_by_id_or_title(params[:id])
@wiki_page.update(is_deleted: true) @wiki_page.update(is_deleted: true)
respond_with(@wiki_page) respond_with(@wiki_page)
end end
def revert def revert
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id]) @wiki_page, _found_by = WikiPage.find_by_id_or_title(params[:id])
@version = @wiki_page.versions.find(params[:version_id]) @version = @wiki_page.versions.find(params[:version_id])
@wiki_page.revert_to!(@version) @wiki_page.revert_to!(@version)
flash[:notice] = "Page was reverted" flash[:notice] = "Page was reverted"

View File

@@ -8,7 +8,7 @@ module ApplicationHelper
def wordbreakify(string) def wordbreakify(string)
lines = string.scan(/.{1,10}/) lines = string.scan(/.{1,10}/)
wordbreaked_string = lines.map{|str| h(str)}.join("<wbr>") wordbreaked_string = lines.map {|str| h(str)}.join("<wbr>")
raw(wordbreaked_string) raw(wordbreaked_string)
end end
@@ -43,7 +43,7 @@ module ApplicationHelper
def error_messages_for(instance_name) def error_messages_for(instance_name)
instance = instance_variable_get("@#{instance_name}") instance = instance_variable_get("@#{instance_name}")
if instance && instance.errors.any? if instance&.errors&.any?
%{<div class="error-messages ui-state-error ui-corner-all"><strong>Error</strong>: #{instance.__send__(:errors).full_messages.join(", ")}</div>}.html_safe %{<div class="error-messages ui-state-error ui-corner-all"><strong>Error</strong>: #{instance.__send__(:errors).full_messages.join(", ")}</div>}.html_safe
else else
"" ""
@@ -133,11 +133,11 @@ module ApplicationHelper
return "anonymous" if user.blank? return "anonymous" if user.blank?
user_class = "user-#{user.level_string.downcase}" user_class = "user-#{user.level_string.downcase}"
user_class = user_class + " user-post-approver" if user.can_approve_posts? user_class += " user-post-approver" if user.can_approve_posts?
user_class = user_class + " user-post-uploader" if user.can_upload_free? user_class += " user-post-uploader" if user.can_upload_free?
user_class = user_class + " user-super-voter" if user.is_super_voter? user_class += " user-super-voter" if user.is_super_voter?
user_class = user_class + " user-banned" if user.is_banned? user_class += " user-banned" if user.is_banned?
user_class = user_class + " with-style" if CurrentUser.user.style_usernames? user_class += " with-style" if CurrentUser.user.style_usernames?
if options[:raw_name] if options[:raw_name]
name = user.name name = user.name
else else
@@ -252,15 +252,13 @@ module ApplicationHelper
CurrentUser.can_approve_posts? && (cookies[:moderated].blank? || Time.at(cookies[:moderated].to_i) < 72.hours.ago) CurrentUser.can_approve_posts? && (cookies[:moderated].blank? || Time.at(cookies[:moderated].to_i) < 72.hours.ago)
end end
protected protected
def nav_link_match(controller, url) def nav_link_match(controller, url)
url =~ case controller url =~ case controller
when "sessions", "users", "maintenance/user/password_resets", "admin/users" when "sessions", "users", "maintenance/user/password_resets", "admin/users"
/^\/(session|users)/ /^\/(session|users)/
when "forum_posts"
/^\/forum_topics/
when "comments" when "comments"
/^\/comments/ /^\/comments/

View File

@@ -1,6 +1,6 @@
module ArtistVersionsHelper module ArtistVersionsHelper
def artist_versions_listing_type def artist_versions_listing_type
params.dig(:search, :artist_id).present? && CurrentUser.is_member? ? :revert : :standard (params.dig(:search, :artist_id).present? && CurrentUser.is_member?) ? :revert : :standard
end end
def artist_version_other_names_diff(artist_version) def artist_version_other_names_diff(artist_version)

View File

@@ -94,7 +94,7 @@ module BulkUpdateRequestsHelper
"#{btag}remove implication " + link_to(arg1, posts_path(:tags => arg1)) + " (#{arg1_count}) -&gt; " + link_to(arg2, posts_path(:tags => arg2)) + " (#{arg2_count})#{etag}" "#{btag}remove implication " + link_to(arg1, posts_path(:tags => arg1)) + " (#{arg1_count}) -&gt; " + link_to(arg2, posts_path(:tags => arg2)) + " (#{arg2_count})#{etag}"
when :mass_update when :mass_update
"#{btag}mass update " + link_to(arg1, posts_path(:tags => arg1)) + " -&gt; " + link_to(arg2, posts_path(:tags => arg2)) + "#{etag}" "#{btag}mass update " + link_to(arg1, posts_path(:tags => arg1)) + " -&gt; " + link_to(arg2, posts_path(:tags => arg2)) + etag.to_s
when :change_category when :change_category
arg1_count = Tag.find_by_name(arg1).try(:post_count).to_i arg1_count = Tag.find_by_name(arg1).try(:post_count).to_i

View File

@@ -54,7 +54,7 @@ module PaginationHelper
else else
html << numbered_paginator_item(1, records.current_page) html << numbered_paginator_item(1, records.current_page)
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page)
if records.size > 0 if records.present?
right_window = records.current_page + window right_window = records.current_page + window
else else
right_window = records.current_page right_window = records.current_page
@@ -62,13 +62,13 @@ module PaginationHelper
(records.current_page - window).upto(right_window) do |page| (records.current_page - window).upto(right_window) do |page|
html << numbered_paginator_item(page, records.current_page) html << numbered_paginator_item(page, records.current_page)
end end
if records.size > 0 if records.present?
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page)
html << numbered_paginator_final_item(records.total_pages, records.current_page) html << numbered_paginator_final_item(records.total_pages, records.current_page)
end end
end end
if records.current_page < records.total_pages && records.size > 0 if records.current_page < records.total_pages && records.present?
html << "<li class='arrow'>" + link_to(content_tag(:i, nil, class: "fas fa-chevron-right"), nav_params_for(records.current_page + 1), rel: "next", id: "paginator-next", "data-shortcut": "d right") + "</li>" html << "<li class='arrow'>" + link_to(content_tag(:i, nil, class: "fas fa-chevron-right"), nav_params_for(records.current_page + 1), rel: "next", id: "paginator-next", "data-shortcut": "d right") + "</li>"
else else
html << "<li class='arrow'><span>" + content_tag(:i, nil, class: "fas fa-chevron-right") + "</span></li>" html << "<li class='arrow'><span>" + content_tag(:i, nil, class: "fas fa-chevron-right") + "</span></li>"
@@ -93,7 +93,7 @@ module PaginationHelper
if page == "..." if page == "..."
html << "<li class='more'>" html << "<li class='more'>"
html << content_tag(:i, nil, class: "fas fa-ellipsis-h") html << content_tag(:i, nil, class: "fas fa-ellipsis-h")
html << "</li>" html << "</li>"
elsif page == current_page elsif page == current_page
html << "<li class='current-page'>" html << "<li class='current-page'>"
html << '<span>' + page.to_s + '</span>' html << '<span>' + page.to_s + '</span>'

View File

@@ -23,7 +23,7 @@ module PostsHelper
def missed_post_search_count_js def missed_post_search_count_js
return nil unless post_search_counts_enabled? return nil unless post_search_counts_enabled?
if params[:ms] == "1" && @post_set.post_count == 0 && @post_set.is_single_tag? if params[:ms] == "1" && @post_set.post_count == 0 && @post_set.is_single_tag?
session_id = session.id session_id = session.id
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.reportbooru_key, serializer: JSON, digest: "SHA256") verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.reportbooru_key, serializer: JSON, digest: "SHA256")
@@ -34,7 +34,7 @@ module PostsHelper
def post_search_count_js def post_search_count_js
return nil unless post_search_counts_enabled? return nil unless post_search_counts_enabled?
if params[:action] == "index" && params[:page].nil? if params[:action] == "index" && params[:page].nil?
tags = Tag.scan_query(params[:tags]).sort.join(" ") tags = Tag.scan_query(params[:tags]).sort.join(" ")
@@ -68,7 +68,7 @@ module PostsHelper
end end
def post_favlist(post) def post_favlist(post)
post.favorited_users.reverse_each.map{|user| link_to_user(user)}.join(", ").html_safe post.favorited_users.reverse_each.map {|user| link_to_user(user)}.join(", ").html_safe
end end
def has_parent_message(post, parent_post_set) def has_parent_message(post, parent_post_set)
@@ -81,7 +81,7 @@ module PostsHelper
sibling_count = parent_post_set.children.count - 1 sibling_count = parent_post_set.children.count - 1
if sibling_count > 0 if sibling_count > 0
html << " and has " html << " and has "
text = sibling_count == 1 ? "a sibling" : "#{sibling_count} siblings" text = (sibling_count == 1) ? "a sibling" : "#{sibling_count} siblings"
html << link_to(text, posts_path(:tags => "parent:#{post.parent_id}")) html << link_to(text, posts_path(:tags => "parent:#{post.parent_id}"))
end end
@@ -96,7 +96,7 @@ module PostsHelper
html = "" html = ""
html << "This post has " html << "This post has "
text = children_post_set.children.count == 1 ? "a child" : "#{children_post_set.children.count} children" text = (children_post_set.children.count == 1) ? "a child" : "#{children_post_set.children.count} children"
html << link_to(text, posts_path(:tags => "parent:#{post.id}")) html << link_to(text, posts_path(:tags => "parent:#{post.id}"))
html << " (#{link_to_wiki "learn more", "help:post_relationships"}) " html << " (#{link_to_wiki "learn more", "help:post_relationships"}) "
@@ -111,9 +111,9 @@ module PostsHelper
end end
def is_pool_selected?(pool) def is_pool_selected?(pool)
return false if params.has_key?(:q) return false if params.key?(:q)
return false if params.has_key?(:favgroup_id) return false if params.key?(:favgroup_id)
return false if !params.has_key?(:pool_id) return false if !params.key?(:pool_id)
return params[:pool_id].to_i == pool.id return params[:pool_id].to_i == pool.id
end end

View File

@@ -7,11 +7,11 @@ module UploadsHelper
when /\Aerror: / when /\Aerror: /
search_params = params[:search].permit! search_params = params[:search].permit!
link_to(upload.sanitized_status, uploads_path(search: search_params.merge({ status: upload.sanitized_status }))) link_to(upload.sanitized_status, uploads_path(search: search_params.merge(status: upload.sanitized_status)))
else else
search_params = params[:search].permit! search_params = params[:search].permit!
link_to(upload.status, uploads_path(search: search_params.merge({ status: upload.status }))) link_to(upload.status, uploads_path(search: search_params.merge(status: upload.status)))
end end
end end
end end

View File

@@ -1,6 +1,6 @@
module UsersHelper module UsersHelper
def email_sig(user) def email_sig(user)
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, serializer: JSON, digest: "SHA256") verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, serializer: JSON, digest: "SHA256")
verifier.generate("#{user.id}") verifier.generate(user.id.to_s)
end end
end end

View File

@@ -8,7 +8,7 @@ module WikiPageVersionsHelper
status = [] status = []
status += ["Renamed"] if cur.title != prev.title status += ["Renamed"] if cur.title != prev.title
status += ["Deleted"] if cur.is_deleted? && !prev.is_deleted? status += ["Deleted"] if cur.is_deleted? && !prev.is_deleted?
status += ["Undeleted"] if !cur.is_deleted? && prev.is_deleted? status += ["Undeleted"] if !cur.is_deleted? && prev.is_deleted?
status.join(" ") status.join(" ")
end end
@@ -27,15 +27,15 @@ module WikiPageVersionsHelper
cbo = Diff::LCS::ContextDiffCallbacks.new cbo = Diff::LCS::ContextDiffCallbacks.new
diffs = thisarr.diff(otharr, cbo) diffs = thisarr.diff(otharr, cbo)
escape_html = ->(str) {str.gsub(/&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;')} escape_html = ->(str) {str.gsub(/&/, '&amp;').gsub(/</, '&lt;').gsub(/>/, '&gt;')}
output = thisarr output = thisarr
output.each { |q| q.replace(escape_html[q]) } output.each { |q| q.replace(escape_html[q]) }
diffs.reverse_each do |hunk| diffs.reverse_each do |hunk|
newchange = hunk.max{|a,b| a.old_position <=> b.old_position} newchange = hunk.max {|a, b| a.old_position <=> b.old_position}
newstart = newchange.old_position newstart = newchange.old_position
oldstart = hunk.min{|a,b| a.old_position <=> b.old_position}.old_position oldstart = hunk.min {|a, b| a.old_position <=> b.old_position}.old_position
if newchange.action == '+' if newchange.action == '+'
output.insert(newstart, '</ins>') output.insert(newstart, '</ins>')
@@ -50,7 +50,7 @@ module WikiPageVersionsHelper
if chg.new_element.match(/^\r?\n$/) if chg.new_element.match(/^\r?\n$/)
output.insert(chg.old_position, '<br>') output.insert(chg.old_position, '<br>')
else else
output.insert(chg.old_position, "#{escape_html[chg.new_element]}") output.insert(chg.old_position, (escape_html[chg.new_element]).to_s)
end end
end end
end end
@@ -60,7 +60,7 @@ module WikiPageVersionsHelper
end end
if hunk[0].action == '-' if hunk[0].action == '-'
output.insert((newstart == oldstart || newchange.action != '+') ? newstart+1 : newstart, '</del>') output.insert((newstart == oldstart || newchange.action != '+') ? newstart + 1 : newstart, '</del>')
output.insert(oldstart, '<del>') output.insert(oldstart, '<del>')
end end
end end

View File

@@ -11,14 +11,14 @@ module WikiPagesHelper
html << "<h2>Posts (#{full_link})</h2>" html << "<h2>Posts (#{full_link})</h2>"
html << wiki_page.post_set.presenter.post_previews_html(self) html << wiki_page.post_set.presenter.post_previews_html(self)
end end
html << "</div>" html << "</div>"
html.html_safe html.html_safe
end end
def wiki_page_other_names_list(wiki_page) 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 = 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.join(" ").html_safe
end end
end end

View File

@@ -1,5 +1,5 @@
class TagBatchChangeJob < ApplicationJob class TagBatchChangeJob < ApplicationJob
class Error < Exception ; end class Error < Exception; end
queue_as :default queue_as :default

View File

@@ -1,6 +1,6 @@
class UploadPreprocessorDelayedStartJob < ApplicationJob class UploadPreprocessorDelayedStartJob < ApplicationJob
queue_as :default queue_as :default
queue_with_priority -1 queue_with_priority(-1)
def perform(source, referer_url, uploader) def perform(source, referer_url, uploader)
UploadService::Preprocessor.new(source: source, referer_url: referer_url).delayed_start(uploader.id) UploadService::Preprocessor.new(source: source, referer_url: referer_url).delayed_start(uploader.id)

View File

@@ -1,6 +1,6 @@
class UploadServiceDelayedStartJob < ApplicationJob class UploadServiceDelayedStartJob < ApplicationJob
queue_as :default queue_as :default
queue_with_priority -1 queue_with_priority(-1)
def perform(uploader) def perform(uploader)
UploadService.delayed_start(uploader.id) UploadService.delayed_start(uploader.id)

View File

@@ -120,7 +120,7 @@ class AliasAndImplicationImporter
end end
end end
private private
def parse(tokens, approver) def parse(tokens, approver)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do

View File

@@ -9,36 +9,35 @@ class APNGInspector
@animated = false @animated = false
end end
#PNG file consists of 8-byte magic number, followed by arbitrary number of chunks # PNG file consists of 8-byte magic number, followed by arbitrary number of chunks
#Each chunk has the following structure: # Each chunk has the following structure:
#4-byte length (unsigned int, can be zero) # 4-byte length (unsigned int, can be zero)
#4-byte name (ASCII string consisting of letters A-z) # 4-byte name (ASCII string consisting of letters A-z)
#(length)-byte data # (length)-byte data
#4-byte CRC # 4-byte CRC
# #
#Any data after chunk named IEND is irrelevant # Any data after chunk named IEND is irrelevant
#APNG frame count is inside a chunk named acTL, in first 4 bytes of data. # APNG frame count is inside a chunk named acTL, in first 4 bytes of data.
# This function calls associated block for each PNG chunk
#This function calls associated block for each PNG chunk # parameters passed are |chunk_name, chunk_length, file_descriptor|
#parameters passed are |chunk_name, chunk_length, file_descriptor| # returns true if file is read succesfully from start to IEND,
#returns true if file is read succesfully from start to IEND, # or if 100 000 chunks are read; returns false otherwise.
#or if 100 000 chunks are read; returns false otherwise.
def each_chunk def each_chunk
iend_reached = false iend_reached = false
File.open(@file_path, 'rb') do |file| File.open(@file_path, 'rb') do |file|
#check if file is not PNG at all # check if file is not PNG at all
return false if file.read(8) != PNG_MAGIC_NUMBER return false if file.read(8) != PNG_MAGIC_NUMBER
chunks = 0 chunks = 0
#We could be dealing with large number of chunks, # We could be dealing with large number of chunks,
#so the code should be optimized to create as few objects as possible. # so the code should be optimized to create as few objects as possible.
#All literal strings are frozen and read() function uses string buffer. # All literal strings are frozen and read() function uses string buffer.
chunkheader = '' chunkheader = ''
while file.read(8, chunkheader) while file.read(8, chunkheader)
#ensure that first 8 bytes from chunk were read properly # ensure that first 8 bytes from chunk were read properly
if chunkheader == nil || chunkheader.length < 8 if chunkheader.nil? || chunkheader.length < 8
return false return false
end end
@@ -48,23 +47,23 @@ class APNGInspector
return false if chunk_name =~ /[^A-Za-z]/ return false if chunk_name =~ /[^A-Za-z]/
yield chunk_name, chunk_len, file yield chunk_name, chunk_len, file
#no need to read further if IEND is reached # no need to read further if IEND is reached
if chunk_name == "IEND".freeze if chunk_name == "IEND".freeze
iend_reached = true iend_reached = true
break break
end end
#check if we processed too many chunks already # check if we processed too many chunks already
#if we did, file is probably maliciously formed # if we did, file is probably maliciously formed
#fail gracefully without marking the file as corrupt # fail gracefully without marking the file as corrupt
chunks += 1 chunks += 1
if chunks > 100000 if chunks > 100000
iend_reached = true iend_reached = true
break break
end end
#jump to the next chunk - go forward by chunk length + 4 bytes CRC # jump to the next chunk - go forward by chunk length + 4 bytes CRC
file.seek(current_pos+chunk_len+4, IO::SEEK_SET) file.seek(current_pos + chunk_len + 4, IO::SEEK_SET)
end end
end end
return iend_reached return iend_reached
@@ -99,14 +98,13 @@ class APNGInspector
private private
#return number of frames in acTL or -1 on failure # return number of frames in acTL or -1 on failure
def parse_actl(len, file) def parse_actl(len, file)
return -1 if len != 8 return -1 if len != 8
framedata = file.read(4) framedata = file.read(4)
if framedata == nil || framedata.length != 4 if framedata.nil? || framedata.length != 4
return -1 return -1
end
return framedata.unpack("N".freeze)[0]
end end
return framedata.unpack1("N".freeze)
end
end end

View File

@@ -1,5 +1,5 @@
module ApproverPruner module ApproverPruner
extend self module_function
def inactive_approvers def inactive_approvers
User.where("bit_prefs & ? > 0", User.flag_value_for("can_approve_posts")).select do |user| User.where("bit_prefs & ? > 0", User.flag_value_for("can_approve_posts")).select do |user|

View File

@@ -64,13 +64,10 @@ class DText
def self.parse_embedded_tag_request_text(text) def self.parse_embedded_tag_request_text(text)
[TagAlias, TagImplication, BulkUpdateRequest].each do |tag_request| [TagAlias, TagImplication, BulkUpdateRequest].each do |tag_request|
text = text.gsub(tag_request.embedded_pattern) do |match| text = text.gsub(tag_request.embedded_pattern) do |match|
begin obj = tag_request.find($~[:id])
obj = tag_request.find($~[:id]) tag_request_message(obj) || match
tag_request_message(obj) || match rescue ActiveRecord::RecordNotFound
match
rescue ActiveRecord::RecordNotFound
match
end
end end
end end
@@ -143,7 +140,7 @@ class DText
def self.dtext_links_differ?(a, b) def self.dtext_links_differ?(a, b)
Set.new(parse_wiki_titles(a)) != Set.new(parse_wiki_titles(b)) || Set.new(parse_wiki_titles(a)) != Set.new(parse_wiki_titles(b)) ||
Set.new(parse_external_links(a)) != Set.new(parse_external_links(b)) Set.new(parse_external_links(a)) != Set.new(parse_external_links(b))
end end
def self.strip_blocks(string, tag) def self.strip_blocks(string, tag)

View File

@@ -36,4 +36,4 @@ module Danbooru
end end
end end
end end
end end

View File

@@ -1,5 +1,5 @@
module DanbooruImageResizer module DanbooruImageResizer
extend self module_function
# Taken from ArgyllCMS 2.0.0 (see also: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html) # Taken from ArgyllCMS 2.0.0 (see also: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html)
SRGB_PROFILE = "#{Rails.root}/config/sRGB.icm" SRGB_PROFILE = "#{Rails.root}/config/sRGB.icm"
@@ -46,7 +46,6 @@ module DanbooruImageResizer
end end
return true return true
ensure ensure
temp.close temp.close
temp.unlink temp.unlink

View File

@@ -39,14 +39,14 @@ class DanbooruLogger
::NewRelic::Agent.add_custom_attributes(attributes) ::NewRelic::Agent.add_custom_attributes(attributes)
end end
private private_class_method
# flatten_hash({ foo: { bar: { baz: 42 } } }) # flatten_hash({ foo: { bar: { baz: 42 } } })
# => { "foo.bar.baz" => 42 } # => { "foo.bar.baz" => 42 }
def self.flatten_hash(hash) def self.flatten_hash(hash)
hash.each_with_object({}) do |(k, v), h| hash.each_with_object({}) do |(k, v), h|
if v.is_a?(Hash) if v.is_a?(Hash)
flatten_hash(v).map do|h_k, h_v| flatten_hash(v).map do |h_k, h_v|
h["#{k}.#{h_k}"] = h_v h["#{k}.#{h_k}"] = h_v
end end
else else

View File

@@ -4,8 +4,8 @@ class DanbooruMath
return 0 return 0
end end
z = Statistics2.pnormaldist(1-(1-confidence)/2) z = Statistics2.pnormaldist(1 - (1 - confidence) / 2)
phat = 1.0*pos/n phat = 1.0 * pos / n
100 * (phat + z*z/(2*n) - z * Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n) 100 * (phat + z * z / (2 * n) - z * Math.sqrt((phat * (1 - phat) + z * z / (4 * n)) / n)) / (1 + z * z / n)
end end
end end

View File

@@ -3,7 +3,7 @@
# API requests must send a user agent and must use gzip compression, otherwise # API requests must send a user agent and must use gzip compression, otherwise
# 403 errors will be returned. # 403 errors will be returned.
class DeviantArtApiClient < Struct.new(:deviation_id) DeviantArtApiClient = Struct.new(:deviation_id) do
extend Memoist extend Memoist
def extended_fetch def extended_fetch

View File

@@ -3,7 +3,7 @@ require 'resolv'
module Downloads module Downloads
class File class File
include ActiveModel::Validations include ActiveModel::Validations
class Error < Exception ; end class Error < Exception; end
RETRIABLE_ERRORS = [Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EIO, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Timeout::Error, IOError] RETRIABLE_ERRORS = [Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EIO, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Timeout::Error, IOError]
@@ -12,7 +12,7 @@ module Downloads
validate :validate_url validate :validate_url
def initialize(url, referer=nil) def initialize(url, referer = nil)
@url = Addressable::URI.parse(url) rescue nil @url = Addressable::URI.parse(url) rescue nil
@referer = referer @referer = referer
validate! validate!
@@ -59,7 +59,7 @@ module Downloads
else else
raise Error.new("HTTP error code: #{res.code} #{res.message}") raise Error.new("HTTP error code: #{res.code} #{res.message}")
end end
end # def end
# Prevent Cloudflare from potentially mangling the image. See issue #3528. # Prevent Cloudflare from potentially mangling the image. See issue #3528.
def uncached_url def uncached_url
@@ -87,7 +87,7 @@ module Downloads
timeout: 10, timeout: 10,
stream_body: true, stream_body: true,
headers: strategy.headers, headers: strategy.headers,
connection_adapter: ValidatingConnectionAdapter, connection_adapter: ValidatingConnectionAdapter
}.deep_merge(Danbooru.config.httparty_options) }.deep_merge(Danbooru.config.httparty_options)
end end

View File

@@ -10,7 +10,7 @@ class ForumUpdater
def update(message, title_tag = nil) def update(message, title_tag = nil)
return if forum_topic.nil? return if forum_topic.nil?
CurrentUser.scoped(User.system) do CurrentUser.scoped(User.system) do
create_response(message) create_response(message)
update_title(title_tag) if title_tag update_title(title_tag) if title_tag

View File

@@ -18,7 +18,8 @@ module Moderator
end end
end end
private private
def search_by_ip_addr(ip_addrs) def search_by_ip_addr(ip_addrs)
sums = Hash.new {|h, k| h[k] = 0} sums = Hash.new {|h, k| h[k] = 0}

View File

@@ -21,7 +21,7 @@ class NicoSeigaApiClient
form["password"] = Danbooru.config.nico_seiga_password form["password"] = Danbooru.config.nico_seiga_password
end.click_button end.click_button
end end
session = mech.cookie_jar.cookies.select{|c| c.name == "user_session"}.first session = mech.cookie_jar.cookies.select {|c| c.name == "user_session"}.first
if session if session
Cache.put("nico-seiga-session", session.value, 1.week) Cache.put("nico-seiga-session", session.value, 1.week)
else else
@@ -74,7 +74,7 @@ class NicoSeigaApiClient
def get(url) def get(url)
response = Danbooru::Http.cache(1.minute).get(url) response = Danbooru::Http.cache(1.minute).get(url)
raise "nico seiga api call failed (code=#{response.code}, body=#{response.body.to_s})" if response.code != 200 raise "nico seiga api call failed (code=#{response.code}, body=#{response.body})" if response.code != 200
Hash.from_xml(response.to_s) Hash.from_xml(response.to_s)
end end

View File

@@ -51,7 +51,7 @@ class NicoSeigaMangaApiClient
def get(url) def get(url)
response = Danbooru::Http.cache(1.minute).get(url) response = Danbooru::Http.cache(1.minute).get(url)
raise "nico seiga api call failed (code=#{response.code}, body=#{response.body.to_s})" if response.code != 200 raise "nico seiga api call failed (code=#{response.code}, body=#{response.body})" if response.code != 200
Hash.from_xml(response.to_s) Hash.from_xml(response.to_s)
end end

View File

@@ -10,7 +10,7 @@ module NoteSanitizer
"span" => %w(class), "span" => %w(class),
"div" => %w(class align), "div" => %w(class align),
"p" => %w(class align), "p" => %w(class align),
"font" => %w(color size), "font" => %w(color size)
} }
ALLOWED_PROPERTIES = %w( ALLOWED_PROPERTIES = %w(
@@ -61,7 +61,7 @@ module NoteSanitizer
:elements => ALLOWED_ELEMENTS, :elements => ALLOWED_ELEMENTS,
:attributes => ALLOWED_ATTRIBUTES, :attributes => ALLOWED_ATTRIBUTES,
:add_attributes => { :add_attributes => {
"a" => { "rel" => "external noreferrer nofollow" }, "a" => { "rel" => "external noreferrer nofollow" }
}, },
:protocols => { :protocols => {
"a" => { "a" => {
@@ -73,9 +73,9 @@ module NoteSanitizer
allow_hacks: false, allow_hacks: false,
at_rules: [], at_rules: [],
protocols: [], protocols: [],
properties: ALLOWED_PROPERTIES, properties: ALLOWED_PROPERTIES
}, },
:transformers => method(:relativize_links), :transformers => method(:relativize_links)
) )
end end

View File

@@ -1,5 +1,5 @@
module PaginationExtension module PaginationExtension
class PaginationError < Exception ; end class PaginationError < Exception; end
attr_accessor :current_page, :records_per_page, :paginator_count, :paginator_mode attr_accessor :current_page, :records_per_page, :paginator_count, :paginator_mode

View File

@@ -6,7 +6,7 @@ class PawooApiClient
STATUS1 = %r!\Ahttps?://pawoo\.net/web/statuses/(\d+)! STATUS1 = %r!\Ahttps?://pawoo\.net/web/statuses/(\d+)!
STATUS2 = %r!\Ahttps?://pawoo\.net/@.+?/([^/]+)! STATUS2 = %r!\Ahttps?://pawoo\.net/@.+?/([^/]+)!
class MissingConfigurationError < Exception ; end class MissingConfigurationError < Exception; end
class Account class Account
attr_reader :json attr_reader :json

View File

@@ -23,8 +23,8 @@ class PixivApiClient
VistaPro Sculptris Comi\ Po! modo DAZ\ Studio 3D-Coat VistaPro Sculptris Comi\ Po! modo DAZ\ Studio 3D-Coat
] ]
class Error < Exception ; end class Error < Exception; end
class BadIDError < Error ; end class BadIDError < Error; end
class WorkResponse class WorkResponse
attr_reader :json, :pages, :name, :moniker, :user_id, :page_count, :tags attr_reader :json, :pages, :name, :moniker, :user_id, :page_count, :tags
@@ -93,7 +93,7 @@ class PixivApiClient
end end
def pages def pages
# ex: # ex:
# https://i.pximg.net/c/150x150_80/novel-cover-master/img/2017/07/27/23/14/17/8465454_80685d10e6df4d7d53ad347ddc18a36b_master1200.jpg (6096b) # https://i.pximg.net/c/150x150_80/novel-cover-master/img/2017/07/27/23/14/17/8465454_80685d10e6df4d7d53ad347ddc18a36b_master1200.jpg (6096b)
# => # =>
# https://i.pximg.net/novel-cover-original/img/2017/07/27/23/14/17/8465454_80685d10e6df4d7d53ad347ddc18a36b.jpg (532129b) # https://i.pximg.net/novel-cover-original/img/2017/07/27/23/14/17/8465454_80685d10e6df4d7d53ad347ddc18a36b.jpg (532129b)
@@ -101,7 +101,8 @@ class PixivApiClient
end end
memoize :pages memoize :pages
public public
PXIMG = %r!\Ahttps?://i\.pximg\.net/c/\d+x\d+_\d+/novel-cover-master/img/(?<timestamp>\d+/\d+/\d+/\d+/\d+/\d+)/(?<filename>\d+_[a-f0-9]+)_master\d+\.(?<ext>jpg|jpeg|png|gif)!i PXIMG = %r!\Ahttps?://i\.pximg\.net/c/\d+x\d+_\d+/novel-cover-master/img/(?<timestamp>\d+/\d+/\d+/\d+/\d+/\d+)/(?<filename>\d+_[a-f0-9]+)_master\d+\.(?<ext>jpg|jpeg|png|gif)!i
def find_original(x) def find_original(x)
@@ -123,7 +124,7 @@ class PixivApiClient
def name def name
json["body"]["user"]["name"] json["body"]["user"]["name"]
end end
def user_id def user_id
json["body"]["user"]["userId"] json["body"]["user"]["userId"]
end end
@@ -177,11 +178,10 @@ class PixivApiClient
elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/ elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/
raise BadIDError.new("Pixiv ##{illust_id} not found: work was deleted, made private, or ID is invalid.") raise BadIDError.new("Pixiv ##{illust_id} not found: work was deleted, made private, or ID is invalid.")
else else
raise Error.new("Pixiv API call failed (status=#{response.code} body=#{response.body.to_s})") raise Error.new("Pixiv API call failed (status=#{response.code} body=#{response.body})")
end end
rescue JSON::ParserError rescue JSON::ParserError
raise Error.new("Pixiv API call failed (status=#{response.code} body=#{response.body.to_s})") raise Error.new("Pixiv API call failed (status=#{response.code} body=#{response.body})")
end end
def fanbox(fanbox_id) def fanbox(fanbox_id)
@@ -228,14 +228,14 @@ class PixivApiClient
headers = { headers = {
"Referer": "http://www.pixiv.net", "Referer": "http://www.pixiv.net",
"X-Client-Time": client_time, "X-Client-Time": client_time,
"X-Client-Hash": client_hash, "X-Client-Hash": client_hash
} }
params = { params = {
username: Danbooru.config.pixiv_login, username: Danbooru.config.pixiv_login,
password: Danbooru.config.pixiv_password, password: Danbooru.config.pixiv_password,
grant_type: "password", grant_type: "password",
client_id: CLIENT_ID, client_id: CLIENT_ID,
client_secret: CLIENT_SECRET, client_secret: CLIENT_SECRET
} }
url = "https://oauth.secure.pixiv.net/auth/token" url = "https://oauth.secure.pixiv.net/auth/token"

View File

@@ -16,7 +16,7 @@ class PixivUgoiraConverter
path = File.join(tmpdir, "images", file.name) path = File.join(tmpdir, "images", file.name)
file.extract(path) file.extract(path)
end end
# Duplicate last frame to avoid it being displayed only for a very short amount of time. # Duplicate last frame to avoid it being displayed only for a very short amount of time.
last_file_name = folder.to_a.last.name last_file_name = folder.to_a.last.name
last_file_name =~ /\A(\d{6})(\.\w{,4})\Z/ last_file_name =~ /\A(\d{6})(\.\w{,4})\Z/
@@ -26,7 +26,7 @@ class PixivUgoiraConverter
path_from = File.join(tmpdir, "images", last_file_name) path_from = File.join(tmpdir, "images", last_file_name)
path_to = File.join(tmpdir, "images", new_last_filename) path_to = File.join(tmpdir, "images", new_last_filename)
FileUtils.cp(path_from, path_to) FileUtils.cp(path_from, path_to)
delay_sum = 0 delay_sum = 0
timecodes_path = File.join(tmpdir, "timecodes.tc") timecodes_path = File.join(tmpdir, "timecodes.tc")
File.open(timecodes_path, "w+") do |f| File.open(timecodes_path, "w+") do |f|
@@ -50,7 +50,6 @@ class PixivUgoiraConverter
Rails.logger.error "[write_webm][ffmpeg] #{line}" Rails.logger.error "[write_webm][ffmpeg] #{line}"
end end
Rails.logger.error "[write_webm] ******************************" Rails.logger.error "[write_webm] ******************************"
return
end end
mkvmerge_out, status = Open3.capture2e("mkvmerge -o #{write_path} --webm --timecodes 0:#{tmpdir}/timecodes.tc #{tmpdir}/tmp.webm") mkvmerge_out, status = Open3.capture2e("mkvmerge -o #{write_path} --webm --timecodes 0:#{tmpdir}/timecodes.tc #{tmpdir}/tmp.webm")
@@ -63,7 +62,6 @@ class PixivUgoiraConverter
Rails.logger.error "[write_webm][mkvmerge] #{line}" Rails.logger.error "[write_webm][mkvmerge] #{line}"
end end
Rails.logger.error "[write_webm] ******************************" Rails.logger.error "[write_webm] ******************************"
return
end end
end end

View File

@@ -5,7 +5,7 @@ class PixivWebAgent
COMIC_SESSION_COOKIE_KEY = "_pixiv-comic_session" COMIC_SESSION_COOKIE_KEY = "_pixiv-comic_session"
def self.phpsessid(agent) def self.phpsessid(agent)
agent.cookies.select do |cookie| cookie.name == SESSION_COOKIE_KEY end.first.try(:value) agent.cookies.select { |cookie| cookie.name == SESSION_COOKIE_KEY }.first.try(:value)
end end
def self.build def self.build

View File

@@ -22,9 +22,9 @@ class PopularSearchService
JSON.parse(fetch_data.to_s).map {|x| x[0]} JSON.parse(fetch_data.to_s).map {|x| x[0]}
end end
def fetch_data() def fetch_data
return [] unless self.class.enabled? return [] unless self.class.enabled?
dates = date.strftime("%Y-%m-%d") dates = date.strftime("%Y-%m-%d")
data = Cache.get("ps-day-#{dates}", 1.minute) do data = Cache.get("ps-day-#{dates}", 1.minute) do
@@ -54,8 +54,7 @@ class PopularSearchService
end end
data data
rescue StandardError => e
rescue => e
DanbooruLogger.log(e) DanbooruLogger.log(e)
return [] return []
end end

View File

@@ -5,16 +5,14 @@ class PostPruner
prune_mod_actions! prune_mod_actions!
end end
protected protected
def prune_pending! def prune_pending!
CurrentUser.scoped(User.system, "127.0.0.1") do CurrentUser.scoped(User.system, "127.0.0.1") do
Post.where("is_deleted = ? and is_pending = ? and created_at < ?", false, true, 3.days.ago).each do |post| Post.where("is_deleted = ? and is_pending = ? and created_at < ?", false, true, 3.days.ago).each do |post|
begin post.delete!("Unapproved in three days")
post.delete!("Unapproved in three days") rescue PostFlag::Error
rescue PostFlag::Error # swallow
# swallow
end
end end
end end
end end

View File

@@ -299,7 +299,7 @@ class PostQueryBuilder
if q[:flagger_ids_neg] if q[:flagger_ids_neg]
q[:flagger_ids_neg].each do |flagger_id| q[:flagger_ids_neg].each do |flagger_id|
if CurrentUser.can_view_flagger?(flagger_id) if CurrentUser.can_view_flagger?(flagger_id)
post_ids = PostFlag.unscoped.search({:creator_id => flagger_id, :category => "normal"}).reorder("").select {|flag| flag.not_uploaded_by?(CurrentUser.id)}.map {|flag| flag.post_id}.uniq post_ids = PostFlag.unscoped.search(:creator_id => flagger_id, :category => "normal").reorder("").select {|flag| flag.not_uploaded_by?(CurrentUser.id)}.map {|flag| flag.post_id}.uniq
if post_ids.any? if post_ids.any?
relation = relation.where.not("posts.id": post_ids) relation = relation.where.not("posts.id": post_ids)
end end
@@ -310,11 +310,11 @@ class PostQueryBuilder
if q[:flagger_ids] if q[:flagger_ids]
q[:flagger_ids].each do |flagger_id| q[:flagger_ids].each do |flagger_id|
if flagger_id == "any" if flagger_id == "any"
relation = relation.where('EXISTS (' + PostFlag.unscoped.search({:category => "normal"}).where('post_id = posts.id').reorder('').select('1').to_sql + ')') relation = relation.where('EXISTS (' + PostFlag.unscoped.search(:category => "normal").where('post_id = posts.id').reorder('').select('1').to_sql + ')')
elsif flagger_id == "none" elsif flagger_id == "none"
relation = relation.where('NOT EXISTS (' + PostFlag.unscoped.search({:category => "normal"}).where('post_id = posts.id').reorder('').select('1').to_sql + ')') relation = relation.where('NOT EXISTS (' + PostFlag.unscoped.search(:category => "normal").where('post_id = posts.id').reorder('').select('1').to_sql + ')')
elsif CurrentUser.can_view_flagger?(flagger_id) elsif CurrentUser.can_view_flagger?(flagger_id)
post_ids = PostFlag.unscoped.search({:creator_id => flagger_id, :category => "normal"}).reorder("").select {|flag| flag.not_uploaded_by?(CurrentUser.id)}.map {|flag| flag.post_id}.uniq post_ids = PostFlag.unscoped.search(:creator_id => flagger_id, :category => "normal").reorder("").select {|flag| flag.not_uploaded_by?(CurrentUser.id)}.map {|flag| flag.post_id}.uniq
relation = relation.where("posts.id": post_ids) relation = relation.where("posts.id": post_ids)
end end
end end
@@ -322,7 +322,7 @@ class PostQueryBuilder
if q[:appealer_ids_neg] if q[:appealer_ids_neg]
q[:appealer_ids_neg].each do |appealer_id| q[:appealer_ids_neg].each do |appealer_id|
relation = relation.where.not("posts.id": PostAppeal.unscoped.where(creator_id: appealer_id).select(:post_id).distinct) relation = relation.where.not("posts.id": PostAppeal.unscoped.where(creator_id: appealer_id).select(:post_id).distinct)
end end
end end

View File

@@ -78,7 +78,7 @@ module PostSets
end end
def hidden_posts def hidden_posts
posts.select { |p| !p.visible? } posts.reject { |p| p.visible? }
end end
def banned_posts def banned_posts
@@ -122,17 +122,17 @@ module PostSets
def posts def posts
@posts ||= begin @posts ||= begin
@post_count = get_post_count() @post_count = get_post_count
if is_random? if is_random?
temp = get_random_posts() temp = get_random_posts
elsif raw elsif raw
temp = ::Post.raw_tag_match(tag_string).order("posts.id DESC").where("true /* PostSets::Post#posts:1 */").paginate(page, :count => post_count, :limit => per_page) temp = ::Post.raw_tag_match(tag_string).order("posts.id DESC").where("true /* PostSets::Post#posts:1 */").paginate(page, :count => post_count, :limit => per_page)
else else
temp = ::Post.tag_match(tag_string).where("true /* PostSets::Post#posts:2 */").paginate(page, :count => post_count, :limit => per_page) temp = ::Post.tag_match(tag_string).where("true /* PostSets::Post#posts:2 */").paginate(page, :count => post_count, :limit => per_page)
end end
# XXX HACK: uploader_name is needed in api responses and in data-uploader attribs (visible to mods only). # HACK: uploader_name is needed in api responses and in data-uploader attribs (visible to mods only).
temp = temp.includes(:uploader) if !is_random? && (format.to_sym != :html || CurrentUser.is_moderator?) temp = temp.includes(:uploader) if !is_random? && (format.to_sym != :html || CurrentUser.is_moderator?)
temp.each # hack to force rails to eager load temp.each # hack to force rails to eager load
@@ -159,11 +159,11 @@ module PostSets
end end
def is_empty_tag? def is_empty_tag?
tag_array.size == 0 tag_array.empty?
end end
def is_pattern_search? def is_pattern_search?
is_single_tag? && tag_string =~ /\*/ && !tag_array.any? {|x| x =~ /^-?source:.+/} is_single_tag? && tag_string =~ /\*/ && tag_array.none? {|x| x =~ /^-?source:.+/}
end end
def current_page def current_page

View File

@@ -1,7 +1,7 @@
module PostSets module PostSets
class Recommended < PostSets::Post class Recommended < PostSets::Post
attr_reader :posts attr_reader :posts
def initialize(posts) def initialize(posts)
super("") super("")
@posts = posts @posts = posts

View File

@@ -9,7 +9,7 @@ module RelatedTagCalculator
tags = frequent_tags_for_search(tag_query, search_sample_size: search_sample_size, category: category).limit(tag_sample_size) tags = frequent_tags_for_search(tag_query, search_sample_size: search_sample_size, category: category).limit(tag_sample_size)
tags = tags.sort_by do |tag| tags = tags.sort_by do |tag|
# cosine distance(tag1, tag2) = 1 - {{tag1 tag2}} / sqrt({{tag1}} * {{tag2}}) # cosine distance(tag1, tag2) = 1 - {{tag1 tag2}} / sqrt({{tag1}} * {{tag2}})
1 - tag.overlap_count / (Math.sqrt(tag.post_count * search_count.to_f)) 1 - tag.overlap_count / Math.sqrt(tag.post_count * search_count.to_f)
end end
tags tags

View File

@@ -68,7 +68,7 @@ class RelatedTagQuery
} }
end end
protected protected
def tags_with_categories(list_of_tag_names) def tags_with_categories(list_of_tag_names)
Tag.categories_for(list_of_tag_names).to_a Tag.categories_for(list_of_tag_names).to_a

View File

@@ -47,6 +47,5 @@ module Reports
def removed_tags def removed_tags
removed_tags_array.join(' ') removed_tags_array.join(' ')
end end
end end
end end

View File

@@ -14,7 +14,7 @@ module Reports
else else
@max_date = Date.today @max_date = Date.today
end end
@queries = queries.to_s.split(/,\s*/).join(",") @queries = queries.to_s.split(/,\s*/).join(",")
end end

View File

@@ -56,9 +56,9 @@ module Reports
return 0 return 0
end end
z = Statistics2.pnormaldist(1-(1-confidence)/2) z = Statistics2.pnormaldist(1 - (1 - confidence) / 2)
phat = 1.0*pos/n phat = 1.0 * pos / n
100 * (phat + z*z/(2*n) - z * Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n) 100 * (phat + z * z / (2 * n) - z * Math.sqrt((phat * (1 - phat) + z * z / (4 * n)) / n)) / (1 + z * z / n)
end end
def self.min_time def self.min_time

View File

@@ -1,5 +1,5 @@
class SessionLoader class SessionLoader
class AuthenticationFailure < Exception ; end class AuthenticationFailure < Exception; end
attr_reader :session, :cookies, :request, :params attr_reader :session, :cookies, :request, :params
@@ -37,7 +37,7 @@ class SessionLoader
request.authorization.present? || params[:login].present? || params[:api_key].present? || params[:password_hash].present? request.authorization.present? || params[:login].present? || params[:api_key].present? || params[:password_hash].present?
end end
private private
def set_statement_timeout def set_statement_timeout
timeout = CurrentUser.user.statement_timeout timeout = CurrentUser.user.statement_timeout

View File

@@ -30,6 +30,6 @@ class SetDiff
distance = ->(other) { ::DidYouMean::Levenshtein.distance(string, other) } distance = ->(other) { ::DidYouMean::Levenshtein.distance(string, other) }
max_distance = string.size * max_dissimilarity max_distance = string.size * max_dissimilarity
candidates.select { |candidate| distance[candidate] <= max_distance }.sort_by(&distance).first candidates.select { |candidate| distance[candidate] <= max_distance }.min_by(&distance)
end end
end end

View File

@@ -10,11 +10,11 @@ module Sources
Strategies::ArtStation, Strategies::ArtStation,
Strategies::Nijie, Strategies::Nijie,
Strategies::Pawoo, Strategies::Pawoo,
Strategies::Moebooru, Strategies::Moebooru
] ]
end end
def self.find(url, referer=nil, default: Strategies::Null) def self.find(url, referer = nil, default: Strategies::Null)
strategy = all.map { |strategy| strategy.new(url, referer) }.detect(&:match?) strategy = all.map { |strategy| strategy.new(url, referer) }.detect(&:match?)
strategy || default&.new(url, referer) strategy || default&.new(url, referer)
end end

View File

@@ -27,7 +27,7 @@ module Sources::Strategies
ASSET = %r!\Ahttps?://cdn\w*\.artstation\.com/p/assets/images/images/\d+/\d+/\d+/(?:medium|small|large)/!i ASSET = %r!\Ahttps?://cdn\w*\.artstation\.com/p/assets/images/images/\d+/\d+/\d+/(?:medium|small|large)/!i
attr_reader :json, :image_urls attr_reader :json
def domains def domains
["artstation.com"] ["artstation.com"]
@@ -38,13 +38,11 @@ module Sources::Strategies
end end
def image_urls def image_urls
image_urls_sub @image_urls ||= image_urls_sub.map { |asset| original_asset_url(asset) }
.map { |asset| original_asset_url(asset) }
end end
memoize :image_urls
def page_url def page_url
return nil unless project_id.present? return nil if project_id.blank?
if artist_name.present? if artist_name.present?
"https://#{artist_name}.artstation.com/projects/#{project_id}" "https://#{artist_name}.artstation.com/projects/#{project_id}"
@@ -54,7 +52,7 @@ module Sources::Strategies
end end
def profile_url def profile_url
return nil unless artist_name.present? return nil if artist_name.blank?
"https://www.artstation.com/#{artist_name}" "https://www.artstation.com/#{artist_name}"
end end
@@ -84,14 +82,13 @@ module Sources::Strategies
profile_url.present? && url == profile_url profile_url.present? && url == profile_url
end end
public
def image_urls_sub def image_urls_sub
if url.match?(ASSET) if url.match?(ASSET)
return [url] return [url]
end end
api_response[:assets].to_a api_response[:assets]
.to_a
.select { |asset| asset[:asset_type] == "image" } .select { |asset| asset[:asset_type] == "image" }
.map { |asset| asset[:image_url] } .map { |asset| asset[:image_url] }
end end
@@ -100,7 +97,7 @@ module Sources::Strategies
# purposes # purposes
def artist_name_from_url def artist_name_from_url
urls.map { |url| url[PROJECT, :artist_name] || url[ARTIST, :artist_name] }.compact.first urls.map { |url| url[PROJECT, :artist_name] || url[ARTIST, :artist_name] }.compact.first
end end
def project_id def project_id
@@ -108,7 +105,7 @@ module Sources::Strategies
end end
def api_response def api_response
return {} unless project_id.present? return {} if project_id.blank?
resp = Danbooru::Http.cache(1.minute).get("https://www.artstation.com/projects/#{project_id}.json") resp = Danbooru::Http.cache(1.minute).get("https://www.artstation.com/projects/#{project_id}.json")
return {} if resp.code != 200 return {} if resp.code != 200

View File

@@ -1,7 +1,7 @@
# This is a collection of strategies for extracting information about a # This is a collection of strategies for extracting information about a
# resource. At a minimum it tries to extract the artist name and a canonical # resource. At a minimum it tries to extract the artist name and a canonical
# URL to download the image from. But it can also be used to normalize a URL # URL to download the image from. But it can also be used to normalize a URL
# for use with the artist finder. # for use with the artist finder.
# #
# Design Principles # Design Principles
# #
@@ -24,11 +24,11 @@ module Sources
true true
end end
# * <tt>url</tt> - Should point to a resource suitable for # * <tt>url</tt> - Should point to a resource suitable for
# downloading. This may sometimes point to the binary file. # downloading. This may sometimes point to the binary file.
# It may also point to the artist's profile page, in cases # It may also point to the artist's profile page, in cases
# where this class is being used to normalize artist urls. # where this class is being used to normalize artist urls.
# Implementations should be smart enough to detect this and # Implementations should be smart enough to detect this and
# behave accordingly. # behave accordingly.
# * <tt>referer_url</tt> - Sometimes the HTML page cannot be # * <tt>referer_url</tt> - Sometimes the HTML page cannot be
# determined from <tt>url</tt>. You should generally pass in a # determined from <tt>url</tt>. You should generally pass in a
@@ -63,9 +63,9 @@ module Sources
nil nil
end end
# Whatever <tt>url</tt> is, this method should return the direct links # Whatever <tt>url</tt> is, this method should return the direct links
# to the canonical binary files. It should not be an HTML page. It should # to the canonical binary files. It should not be an HTML page. It should
# be a list of JPEG, PNG, GIF, WEBM, MP4, ZIP, etc. It is what the # be a list of JPEG, PNG, GIF, WEBM, MP4, ZIP, etc. It is what the
# downloader will fetch and save to disk. # downloader will fetch and save to disk.
def image_urls def image_urls
raise NotImplementedError raise NotImplementedError
@@ -269,7 +269,7 @@ module Sources
:tag_name => tag_name, :tag_name => tag_name,
:other_names => other_names, :other_names => other_names,
:profile_url => profile_url, :profile_url => profile_url,
:profile_urls => profile_urls, :profile_urls => profile_urls
}, },
:artists => artists.as_json(include: :sorted_urls), :artists => artists.as_json(include: :sorted_urls),
:image_url => image_url, :image_url => image_url,
@@ -284,18 +284,16 @@ module Sources
:title => artist_commentary_title, :title => artist_commentary_title,
:description => artist_commentary_desc, :description => artist_commentary_desc,
:dtext_title => dtext_artist_commentary_title, :dtext_title => dtext_artist_commentary_title,
:dtext_description => dtext_artist_commentary_desc, :dtext_description => dtext_artist_commentary_desc
}, },
:api_response => api_response.to_h, :api_response => api_response.to_h
} }
end end
def to_json def to_json(*_args)
to_h.to_json to_h.to_json
end end
protected
def http_exists?(url, headers) def http_exists?(url, headers)
res = HTTParty.head(url, Danbooru.config.httparty_options.deep_merge(headers: headers)) res = HTTParty.head(url, Danbooru.config.httparty_options.deep_merge(headers: headers))
res.success? res.success?
@@ -306,7 +304,7 @@ module Sources
def self.to_dtext(text) def self.to_dtext(text)
text = text.to_s text = text.to_s
text = Rails::Html::FullSanitizer.new.sanitize(text, encode_special_chars: false) text = Rails::Html::FullSanitizer.new.sanitize(text, encode_special_chars: false)
text = CGI::unescapeHTML(text) text = CGI.unescapeHTML(text)
text text
end end
end end

View File

@@ -57,8 +57,6 @@ module Sources
PATH_PROFILE = %r{\Ahttps?://(www\.)?deviantart\.com/#{ARTIST}/?\z}i PATH_PROFILE = %r{\Ahttps?://(www\.)?deviantart\.com/#{ARTIST}/?\z}i
SUBDOMAIN_PROFILE = %r{\Ahttps?://#{ARTIST}\.deviantart\.com/?\z}i SUBDOMAIN_PROFILE = %r{\Ahttps?://#{ARTIST}\.deviantart\.com/?\z}i
attr_accessor :api_client
def domains def domains
["deviantart.net", "deviantart.com"] ["deviantart.net", "deviantart.com"]
end end
@@ -211,8 +209,6 @@ module Sources
end.gsub(/\A[[:space:]]+|[[:space:]]+\z/, "") end.gsub(/\A[[:space:]]+|[[:space:]]+\z/, "")
end end
public
def self.deviation_id_from_url(url) def self.deviation_id_from_url(url)
if url =~ ASSET if url =~ ASSET
$~[:base36_deviation_id].try(:to_i, 36) $~[:base36_deviation_id].try(:to_i, 36)

View File

@@ -130,8 +130,6 @@ module Sources
end end
memoize :tags memoize :tags
public
def api_client def api_client
if illust_id if illust_id
NicoSeigaApiClient.new(illust_id: illust_id) NicoSeigaApiClient.new(illust_id: illust_id)

View File

@@ -120,9 +120,11 @@ module Sources
def tags def tags
links = page&.search("div#view-tag a") || [] links = page&.search("div#view-tag a") || []
links.select do |node| search_links = links.select do |node|
node["href"] =~ /search\.php/ node["href"] =~ /search\.php/
end.map do |node| end
search_links.map do |node|
[node.inner_text, "https://nijie.info" + node.attr("href")] [node.inner_text, "https://nijie.info" + node.attr("href")]
end end
end end
@@ -131,8 +133,6 @@ module Sources
"nijie" + artist_id.to_s "nijie" + artist_id.to_s
end end
public
def self.to_dtext(text) def self.to_dtext(text)
text = text.to_s.gsub(/\r\n|\r/, "<br>") text = text.to_s.gsub(/\r\n|\r/, "<br>")
DText.from_html(text).strip DText.from_html(text).strip
@@ -196,7 +196,7 @@ module Sources
form['password'] = Danbooru.config.nijie_password form['password'] = Danbooru.config.nijie_password
end.click_button end.click_button
end end
session = mech.cookie_jar.cookies.select{|c| c.name == "NIJIEIJIEID"}.first session = mech.cookie_jar.cookies.select {|c| c.name == "NIJIEIJIEID"}.first
Cache.put("nijie-session", session.value, 1.day) if session Cache.put("nijie-session", session.value, 1.day) if session
end end
@@ -207,7 +207,6 @@ module Sources
mech.cookie_jar.add(cookie) mech.cookie_jar.add(cookie)
mech mech
rescue Mechanize::ResponseCodeError => x rescue Mechanize::ResponseCodeError => x
if x.response_code.to_i == 429 if x.response_code.to_i == 429
sleep(5) sleep(5)

View File

@@ -85,8 +85,6 @@ module Sources::Strategies
end.strip end.strip
end end
public
def api_response def api_response
[url, referer_url].each do |x| [url, referer_url].each do |x|
if client = PawooApiClient.new.get(x) if client = PawooApiClient.new.get(x)

View File

@@ -69,7 +69,7 @@ module Sources
if text.nil? if text.nil?
return nil return nil
end end
text = text.gsub(%r!https?://www\.pixiv\.net/member_illust\.php\?mode=medium&illust_id=([0-9]+)!i) do |match| text = text.gsub(%r!https?://www\.pixiv\.net/member_illust\.php\?mode=medium&illust_id=([0-9]+)!i) do |match|
pixiv_id = $1 pixiv_id = $1
%(pixiv ##{pixiv_id} "»":[/posts?tags=pixiv:#{pixiv_id}]) %(pixiv ##{pixiv_id} "»":[/posts?tags=pixiv:#{pixiv_id}])
@@ -132,11 +132,10 @@ module Sources
end end
return url return url
rescue PixivApiClient::BadIDError rescue PixivApiClient::BadIDError
nil nil
end end
def canonical_url def canonical_url
return image_url return image_url
end end
@@ -183,7 +182,7 @@ module Sources
rescue PixivApiClient::BadIDError rescue PixivApiClient::BadIDError
nil nil
end end
def headers def headers
if fanbox_id.present? if fanbox_id.present?
# need the session to download fanbox images # need the session to download fanbox images
@@ -236,8 +235,6 @@ module Sources
illust_id.present? ? "pixiv:#{illust_id}" : "source:#{canonical_url}" illust_id.present? ? "pixiv:#{illust_id}" : "source:#{canonical_url}"
end end
public
def image_urls_sub def image_urls_sub
if url =~ FANBOX_IMAGE if url =~ FANBOX_IMAGE
return [url] return [url]

View File

@@ -131,8 +131,6 @@ module Sources::Strategies
DText.from_html(artist_commentary_desc).strip DText.from_html(artist_commentary_desc).strip
end end
public
# Look for the biggest available version on media.tumblr.com. A bigger # Look for the biggest available version on media.tumblr.com. A bigger
# version may or may not exist. # version may or may not exist.
# #
@@ -181,7 +179,7 @@ module Sources::Strategies
response = Danbooru::Http.cache(1.minute).get( response = Danbooru::Http.cache(1.minute).get(
"https://api.tumblr.com/v2/blog/#{blog_name}/posts", "https://api.tumblr.com/v2/blog/#{blog_name}/posts",
params: { id: post_id, api_key: Danbooru.config.tumblr_consumer_key }, params: { id: post_id, api_key: Danbooru.config.tumblr_consumer_key }
) )
return {} if response.code != 200 return {} if response.code != 200

View File

@@ -134,15 +134,13 @@ module Sources::Strategies
url_replacements = url_replacements.to_h url_replacements = url_replacements.to_h
desc = artist_commentary_desc.unicode_normalize(:nfkc) desc = artist_commentary_desc.unicode_normalize(:nfkc)
desc = CGI::unescapeHTML(desc) desc = CGI.unescapeHTML(desc)
desc = desc.gsub(%r!https?://t\.co/[a-zA-Z0-9]+!i, url_replacements) desc = desc.gsub(%r!https?://t\.co/[a-zA-Z0-9]+!i, url_replacements)
desc = desc.gsub(%r!#([^[:space:]]+)!, '"#\\1":[https://twitter.com/hashtag/\\1]') desc = desc.gsub(%r!#([^[:space:]]+)!, '"#\\1":[https://twitter.com/hashtag/\\1]')
desc = desc.gsub(%r!@([a-zA-Z0-9_]+)!, '"@\\1":[https://twitter.com/\\1]') desc = desc.gsub(%r!@([a-zA-Z0-9_]+)!, '"@\\1":[https://twitter.com/\\1]')
desc.strip desc.strip
end end
public
def api_client def api_client
TwitterApiClient.new(Danbooru.config.twitter_api_key, Danbooru.config.twitter_api_secret) TwitterApiClient.new(Danbooru.config.twitter_api_key, Danbooru.config.twitter_api_secret)
end end

View File

@@ -20,7 +20,7 @@ class SpamDetector
# rakismet raises an exception if the api key or url aren't configured # rakismet raises an exception if the api key or url aren't configured
def self.working? def self.working?
Rakismet.validate_key Rakismet.validate_key
rescue rescue StandardError
false false
end end
@@ -61,7 +61,7 @@ class SpamDetector
end end
is_spam is_spam
rescue => exception rescue StandardError => exception
DanbooruLogger.log(exception) DanbooruLogger.log(exception)
false false
end end

View File

@@ -20,7 +20,8 @@ class SqsService
) )
end end
private private
def sqs def sqs
@sqs ||= Aws::SQS::Client.new( @sqs ||= Aws::SQS::Client.new(
credentials: Danbooru.config.aws_credentials, credentials: Danbooru.config.aws_credentials,

View File

@@ -45,7 +45,7 @@ class StorageManager
end end
def open_file(post, type) def open_file(post, type)
open(file_path(post.md5, post.file_ext, type)) self.open(file_path(post.md5, post.file_ext, type))
end end
def file_url(post, type, tagged_filenames: false) def file_url(post, type, tagged_filenames: false)

View File

@@ -1,5 +1,5 @@
class StorageManager::Local < StorageManager class StorageManager::Local < StorageManager
DEFAULT_PERMISSIONS = 0644 DEFAULT_PERMISSIONS = 0o644
def store(io, dest_path) def store(io, dest_path)
temp_path = dest_path + "-" + SecureRandom.uuid + ".tmp" temp_path = dest_path + "-" + SecureRandom.uuid + ".tmp"

View File

@@ -1,35 +1,33 @@
=begin #
# Generalizes the hybrid storage manager to be more declarative in
Generalizes the hybrid storage manager to be more declarative in # syntax. Matches are executed in order of appearance so the first
syntax. Matches are executed in order of appearance so the first # matching manager is returned. You should always add at least one
matching manager is returned. You should always add at least one # manager with no constraints as a default case.
manager with no constraints as a default case. #
### Example ### Example
#
StorageManager::Match.new do |matcher| # StorageManager::Match.new do |matcher|
matcher.add_manager(type: :crop) do # matcher.add_manager(type: :crop) do
StorageManager::SFTP.new("raikou3.donmai.us", base_url: "https://raikou3.donmai.us", hierarchical: true, base_dir: "/var/www/raikou3") # StorageManager::SFTP.new("raikou3.donmai.us", base_url: "https://raikou3.donmai.us", hierarchical: true, base_dir: "/var/www/raikou3")
end # end
#
matcher.add_manager(id: 1..850_000) do # matcher.add_manager(id: 1..850_000) do
StorageManager::SFTP.new("raikou1.donmai.us", base_url: "https://raikou1.donmai.us", hierarchical: true, base_dir: "/var/www/raikou1") # StorageManager::SFTP.new("raikou1.donmai.us", base_url: "https://raikou1.donmai.us", hierarchical: true, base_dir: "/var/www/raikou1")
end # end
#
matcher.add_manager(id: 850_001..2_000_000) do # matcher.add_manager(id: 850_001..2_000_000) do
StorageManager::SFTP.new("raikou2.donmai.us", base_url: "https://raikou2.donmai.us", hierarchical: true, base_dir: "/var/www/raikou2") # StorageManager::SFTP.new("raikou2.donmai.us", base_url: "https://raikou2.donmai.us", hierarchical: true, base_dir: "/var/www/raikou2")
end # end
#
matcher.add_manager(id: 1..3_000_000, type: [:large, :original]) do # matcher.add_manager(id: 1..3_000_000, type: [:large, :original]) do
StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "https://hijiribe.donmai.us/data") # StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "https://hijiribe.donmai.us/data")
end # end
#
matcher.add_manager({}) do # matcher.add_manager({}) do
StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "#{CurrentUser.root_url}/data") # StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "#{CurrentUser.root_url}/data")
end # end
end # end
#
=end
class StorageManager::Match < StorageManager class StorageManager::Match < StorageManager
def initialize def initialize
@@ -56,7 +54,7 @@ class StorageManager::Match < StorageManager
end end
if params[:type] && constraints[:type] if params[:type] && constraints[:type]
if constraints[:type].respond_to?(:include?) if constraints[:type].respond_to?(:include?)
if !constraints[:type].include?(params[:type]) if !constraints[:type].include?(params[:type])
match = false match = false
end end
@@ -109,4 +107,3 @@ class StorageManager::Match < StorageManager
end end
end end
end end

View File

@@ -1,12 +1,12 @@
class StorageManager::SFTP < StorageManager class StorageManager::SFTP < StorageManager
DEFAULT_PERMISSIONS = 0644 DEFAULT_PERMISSIONS = 0o644
# http://net-ssh.github.io/net-ssh/Net/SSH.html#method-c-start # http://net-ssh.github.io/net-ssh/Net/SSH.html#method-c-start
DEFAULT_SSH_OPTIONS = { DEFAULT_SSH_OPTIONS = {
timeout: 10, timeout: 10,
logger: Rails.logger, logger: Rails.logger,
verbose: :fatal, verbose: :fatal,
non_interactive: true, non_interactive: true
} }
attr_reader :hosts, :ssh_options attr_reader :hosts, :ssh_options
@@ -22,22 +22,20 @@ class StorageManager::SFTP < StorageManager
dest_backup_path = dest_path + "-" + SecureRandom.uuid + ".bak" dest_backup_path = dest_path + "-" + SecureRandom.uuid + ".bak"
each_host do |host, sftp| each_host do |host, sftp|
begin sftp.upload!(file.path, temp_upload_path)
sftp.upload!(file.path, temp_upload_path) sftp.setstat!(temp_upload_path, permissions: DEFAULT_PERMISSIONS)
sftp.setstat!(temp_upload_path, permissions: DEFAULT_PERMISSIONS)
# `rename!` can't overwrite existing files, so if a file already exists # `rename!` can't overwrite existing files, so if a file already exists
# at dest_path we move it out of the way first. # at dest_path we move it out of the way first.
force { sftp.rename!(dest_path, dest_backup_path) } force { sftp.rename!(dest_path, dest_backup_path) }
force { sftp.rename!(temp_upload_path, dest_path) } force { sftp.rename!(temp_upload_path, dest_path) }
rescue StandardError => e rescue StandardError => e
# if anything fails, try to move the original file back in place (if it was moved). # if anything fails, try to move the original file back in place (if it was moved).
force { sftp.rename!(dest_backup_path, dest_path) } force { sftp.rename!(dest_backup_path, dest_path) }
raise Error, e raise Error, e
ensure ensure
force { sftp.remove!(temp_upload_path) } force { sftp.remove!(temp_upload_path) }
force { sftp.remove!(dest_backup_path) } force { sftp.remove!(dest_backup_path) }
end
end end
end end

View File

@@ -1,5 +1,5 @@
class TagAliasRequest class TagAliasRequest
def self.command_string(antecedent_name, consequent_name, id=nil) def self.command_string(antecedent_name, consequent_name, id = nil)
if id if id
return "[ta:#{id}]" return "[ta:#{id}]"
end end

View File

@@ -1,10 +1,10 @@
module TagAutocomplete module TagAutocomplete
extend self module_function
PREFIX_BOUNDARIES = "(_/:;-" PREFIX_BOUNDARIES = "(_/:;-"
LIMIT = 10 LIMIT = 10
class Result < Struct.new(:name, :post_count, :category, :antecedent_name, :source) Result = Struct.new(:name, :post_count, :category, :antecedent_name, :source) do
include ActiveModel::Serializers::JSON include ActiveModel::Serializers::JSON
include ActiveModel::Serializers::Xml include ActiveModel::Serializers::Xml
@@ -28,7 +28,7 @@ module TagAutocomplete
candidates = count_sort( candidates = count_sort(
query, query,
search_exact(query, 8) + search_exact(query, 8) +
search_prefix(query, 4) + search_prefix(query, 4) +
search_correct(query, 2) + search_correct(query, 2) +
search_aliases(query, 3) search_aliases(query, 3)
) )
@@ -40,7 +40,7 @@ module TagAutocomplete
end.reverse.slice(0, LIMIT) end.reverse.slice(0, LIMIT)
end end
def search_exact(query, n=4) def search_exact(query, n = 4)
Tag Tag
.where("name like ? escape e'\\\\'", query.to_escaped_for_sql_like + "%") .where("name like ? escape e'\\\\'", query.to_escaped_for_sql_like + "%")
.where("post_count > 0") .where("post_count > 0")
@@ -50,7 +50,7 @@ module TagAutocomplete
.map {|row| Result.new(*row, nil, :exact)} .map {|row| Result.new(*row, nil, :exact)}
end end
def search_correct(query, n=2) def search_correct(query, n = 2)
if query.size <= 3 if query.size <= 3
return [] return []
end end
@@ -66,7 +66,7 @@ module TagAutocomplete
.map {|row| Result.new(*row, nil, :correct)} .map {|row| Result.new(*row, nil, :correct)}
end end
def search_prefix(query, n=3) def search_prefix(query, n = 3)
if query.size >= 5 if query.size >= 5
return [] return []
end end
@@ -97,7 +97,7 @@ module TagAutocomplete
.map {|row| Result.new(*row, nil, :prefix)} .map {|row| Result.new(*row, nil, :prefix)}
end end
def search_aliases(query, n=10) def search_aliases(query, n = 10)
wildcard_name = query + "*" wildcard_name = query + "*"
TagAlias TagAlias
.select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name") .select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name")
@@ -112,4 +112,3 @@ module TagAutocomplete
.map {|row| Result.new(*row, :alias)} .map {|row| Result.new(*row, :alias)}
end end
end end

View File

@@ -1,5 +1,5 @@
module TagChangeNoticeService module TagChangeNoticeService
extend self module_function
def get_forum_topic_id(tag) def get_forum_topic_id(tag)
Cache.get("tcn:#{tag}") Cache.get("tcn:#{tag}")

View File

@@ -1,5 +1,5 @@
class TagImplicationRequest class TagImplicationRequest
def self.command_string(antecedent_name, consequent_name, id=nil) def self.command_string(antecedent_name, consequent_name, id = nil)
if id if id
return "[ti:#{id}]" return "[ti:#{id}]"
end end

View File

@@ -1,7 +1,6 @@
module TagRelationshipRetirementService module TagRelationshipRetirementService
THRESHOLD = 2.year module_function
THRESHOLD = 2.years
extend self
def forum_topic_title def forum_topic_title
return "Retired tag aliases & implications" return "Retired tag aliases & implications"

1
app/logical/upload_error_checker.rb Normal file → Executable file
View File

@@ -19,4 +19,3 @@ class UploadErrorChecker
end end
end end
end end

View File

@@ -54,7 +54,6 @@ class UploadService
@upload.save! @upload.save!
@post = create_post_from_upload(@upload) @post = create_post_from_upload(@upload)
return @upload return @upload
rescue Exception => x rescue Exception => x
@upload.update(status: "error: #{x.class} - #{x.message}", backtrace: x.backtrace.join("\n")) @upload.update(status: "error: #{x.class} - #{x.message}", backtrace: x.backtrace.join("\n"))
@upload @upload

View File

@@ -62,7 +62,6 @@ class UploadService
CurrentUser.as(uploader_id) do CurrentUser.as(uploader_id) do
start! start!
end end
rescue ActiveRecord::RecordNotUnique rescue ActiveRecord::RecordNotUnique
return return
end end
@@ -106,9 +105,9 @@ class UploadService
end end
def finish!(upload = nil) def finish!(upload = nil)
pred = upload || self.predecessor() pred = upload || self.predecessor
# regardless of who initialized the upload, credit should # regardless of who initialized the upload, credit should
# goto whoever submitted the form # goto whoever submitted the form
pred.initialize_attributes pred.initialize_attributes
@@ -124,5 +123,4 @@ class UploadService
return pred return pred
end end
end end
end end

View File

@@ -95,7 +95,7 @@ class UploadService
upload = preprocessor.finish!(upload) upload = preprocessor.finish!(upload)
raise Error, upload.status if upload.is_errored? raise Error, upload.status if upload.is_errored?
md5_changed = upload.md5 != post.md5 md5_changed = upload.md5 != post.md5
replacement.replacement_url = find_replacement_url(replacement, upload) replacement.replacement_url = find_replacement_url(replacement, upload)
if md5_changed if md5_changed

View File

@@ -1,6 +1,6 @@
class UploadService class UploadService
module Utils module Utils
extend self module_function
class CorruptFileError < RuntimeError; end class CorruptFileError < RuntimeError; end
def file_header_to_file_ext(file) def file_header_to_file_ext(file)
@@ -93,7 +93,7 @@ class UploadService
def generate_video_crop_for(video, width) def generate_video_crop_for(video, width)
vp = Tempfile.new(["video-preview", ".jpg"], binmode: true) vp = Tempfile.new(["video-preview", ".jpg"], binmode: true)
video.screenshot(vp.path, {:seek_time => 0, :resolution => "#{video.width}x#{video.height}"}) video.screenshot(vp.path, :seek_time => 0, :resolution => "#{video.width}x#{video.height}")
crop = DanbooruImageResizer.crop(vp, width, width, 85) crop = DanbooruImageResizer.crop(vp, width, width, 85)
vp.close vp.close
return crop return crop
@@ -108,7 +108,7 @@ class UploadService
end end
output_file = Tempfile.new(["video-preview", ".jpg"], binmode: true) output_file = Tempfile.new(["video-preview", ".jpg"], binmode: true)
video.screenshot(output_file.path, {:seek_time => 0, :resolution => "#{width}x#{height}"}) video.screenshot(output_file.path, :seek_time => 0, :resolution => "#{width}x#{height}")
output_file output_file
end end
@@ -140,8 +140,8 @@ class UploadService
end end
end end
# these methods are only really used during upload processing even # these methods are only really used during upload processing even
# though logically they belong on upload. post can rely on the # though logically they belong on upload. post can rely on the
# automatic tag that's added. # automatic tag that's added.
def is_animated_gif?(upload, file) def is_animated_gif?(upload, file)
return false if upload.file_ext != "gif" return false if upload.file_ext != "gif"
@@ -179,7 +179,7 @@ class UploadService
def get_file_for_upload(upload, file: nil) def get_file_for_upload(upload, file: nil)
return file if file.present? return file if file.present?
raise RuntimeError, "No file or source URL provided" if upload.source_url.blank? raise "No file or source URL provided" if upload.source_url.blank?
attempts = 0 attempts = 0
@@ -190,8 +190,7 @@ class UploadService
if !DanbooruImageResizer.validate_shell(file) if !DanbooruImageResizer.validate_shell(file)
raise CorruptFileError.new("File is corrupted") raise CorruptFileError.new("File is corrupted")
end end
rescue StandardError
rescue
if attempts == 3 if attempts == 3
raise raise
end end
@@ -201,7 +200,7 @@ class UploadService
end end
if download.data[:ugoira_frame_data].present? if download.data[:ugoira_frame_data].present?
upload.context = { upload.context = {
"ugoira" => { "ugoira" => {
"frame_data" => download.data[:ugoira_frame_data], "frame_data" => download.data[:ugoira_frame_data],
"content_type" => "image/jpeg" "content_type" => "image/jpeg"

View File

@@ -1,5 +1,5 @@
class UserDeletion class UserDeletion
class ValidationError < Exception ; end class ValidationError < Exception; end
attr_reader :user, :password attr_reader :user, :password
@@ -18,10 +18,10 @@ class UserDeletion
create_mod_action create_mod_action
end end
private private
def create_mod_action def create_mod_action
ModAction.log("user ##{user.id} deleted",:user_delete) ModAction.log("user ##{user.id} deleted", :user_delete)
end end
def clear_saved_searches def clear_saved_searches
@@ -55,9 +55,7 @@ private
def rename def rename
name = "user_#{user.id}" name = "user_#{user.id}"
n = 0 n = 0
while User.where(:name => name).exists? && (n < 10) name += "~" while User.where(:name => name).exists? && (n < 10)
name += "~"
end
if n == 10 if n == 10
raise ValidationError.new("New name could not be found") raise ValidationError.new("New name could not be found")

View File

@@ -1,7 +1,7 @@
class UserNameValidator < ActiveModel::EachValidator class UserNameValidator < ActiveModel::EachValidator
def validate_each(rec, attr, value) def validate_each(rec, attr, value)
name = value name = value
rec.errors[attr] << "already exists" if User.find_by_name(name).present? rec.errors[attr] << "already exists" if User.find_by_name(name).present?
rec.errors[attr] << "must be 2 to 100 characters long" if !name.length.between?(2, 100) rec.errors[attr] << "must be 2 to 100 characters long" if !name.length.between?(2, 100)
rec.errors[attr] << "cannot have whitespace or colons" if name =~ /[[:space:]]|:/ rec.errors[attr] << "cannot have whitespace or colons" if name =~ /[[:space:]]|:/

View File

@@ -18,22 +18,22 @@ class UserPromotion
user.level = new_level user.level = new_level
if options.has_key?(:can_approve_posts) if options.key?(:can_approve_posts)
user.can_approve_posts = options[:can_approve_posts] user.can_approve_posts = options[:can_approve_posts]
end end
if options.has_key?(:can_upload_free) if options.key?(:can_upload_free)
user.can_upload_free = options[:can_upload_free] user.can_upload_free = options[:can_upload_free]
end end
if options.has_key?(:no_feedback) if options.key?(:no_feedback)
user.no_feedback = options[:no_feedback] user.no_feedback = options[:no_feedback]
end end
if options.has_key?(:no_flagging) if options.key?(:no_flagging)
user.no_flagging = options[:no_flagging] user.no_flagging = options[:no_flagging]
end end
user.inviter_id = promoter.id user.inviter_id = promoter.id
create_user_feedback unless options[:is_upgrade] create_user_feedback unless options[:is_upgrade]
@@ -43,23 +43,23 @@ class UserPromotion
user.save user.save
end end
private private
def create_mod_actions def create_mod_actions
if old_can_approve_posts != user.can_approve_posts? if old_can_approve_posts != user.can_approve_posts?
ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed approval privileges for \"#{user.name}\":/users/#{user.id} from #{old_can_approve_posts} to [b]#{user.can_approve_posts?}[/b]",:user_approval_privilege) ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed approval privileges for \"#{user.name}\":/users/#{user.id} from #{old_can_approve_posts} to [b]#{user.can_approve_posts?}[/b]", :user_approval_privilege)
end end
if old_can_upload_free != user.can_upload_free? if old_can_upload_free != user.can_upload_free?
ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed unlimited upload privileges for \"#{user.name}\":/users/#{user.id} from #{old_can_upload_free} to [b]#{user.can_upload_free?}[/b]",:user_upload_privilege) ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed unlimited upload privileges for \"#{user.name}\":/users/#{user.id} from #{old_can_upload_free} to [b]#{user.can_upload_free?}[/b]", :user_upload_privilege)
end end
if old_no_flagging != user.no_flagging? if old_no_flagging != user.no_flagging?
ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed banned from flagging for \"#{user.name}\":/users/#{user.id} from #{old_no_flagging} to [b]#{user.no_flagging?}[/b]",:user_approval_privilege) ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed banned from flagging for \"#{user.name}\":/users/#{user.id} from #{old_no_flagging} to [b]#{user.no_flagging?}[/b]", :user_approval_privilege)
end end
if old_no_feedback != user.no_feedback? if old_no_feedback != user.no_feedback?
ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed banned from feedback for \"#{user.name}\":/users/#{user.id} from #{old_no_feedback} to [b]#{user.no_feedback?}[/b]",:user_approval_privilege) ModAction.log("\"#{promoter.name}\":/users/#{promoter.id} changed banned from feedback for \"#{user.name}\":/users/#{user.id} from #{old_no_feedback} to [b]#{user.no_feedback?}[/b]", :user_approval_privilege)
end end
if user.level_changed? if user.level_changed?
@@ -75,7 +75,7 @@ private
# can't promote/demote moderators # can't promote/demote moderators
raise User::PrivilegeError if user.is_moderator? raise User::PrivilegeError if user.is_moderator?
# can't promote to admin # can't promote to admin
raise User::PrivilegeError if new_level.to_i >= User::Levels::ADMIN raise User::PrivilegeError if new_level.to_i >= User::Levels::ADMIN
end end
@@ -108,11 +108,11 @@ private
messages << "You gained the ability to give user feedback." messages << "You gained the ability to give user feedback."
end end
if user.no_flagging? && !old_no_flagging if user.no_flagging? && !old_no_flagging
messages << "You lost the ability to flag posts." messages << "You lost the ability to flag posts."
elsif !user.no_flagging? && old_no_flagging elsif !user.no_flagging? && old_no_flagging
messages << "You gained the ability to flag posts." messages << "You gained the ability to flag posts."
end end
messages.join("\n") messages.join("\n")
end end

View File

@@ -356,7 +356,7 @@ class ApplicationRecord < ActiveRecord::Base
def belongs_to_creator(options = {}) def belongs_to_creator(options = {})
class_eval do class_eval do
belongs_to :creator, options.merge(class_name: "User") belongs_to :creator, options.merge(class_name: "User")
before_validation(on: :create) do |rec| before_validation(on: :create) do |rec|
if rec.creator_id.nil? if rec.creator_id.nil?
rec.creator_id = CurrentUser.id rec.creator_id = CurrentUser.id
rec.creator_ip_addr = CurrentUser.ip_addr if rec.respond_to?(:creator_ip_addr=) rec.creator_ip_addr = CurrentUser.ip_addr if rec.respond_to?(:creator_ip_addr=)

Some files were not shown because too many files have changed in this diff Show More