rubocop: fix various style issues.
This commit is contained in:
@@ -120,7 +120,7 @@ class AliasAndImplicationImporter
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def parse(tokens, approver)
|
||||
ActiveRecord::Base.transaction do
|
||||
|
||||
@@ -9,36 +9,35 @@ class APNGInspector
|
||||
@animated = false
|
||||
end
|
||||
|
||||
#PNG file consists of 8-byte magic number, followed by arbitrary number of chunks
|
||||
#Each chunk has the following structure:
|
||||
#4-byte length (unsigned int, can be zero)
|
||||
#4-byte name (ASCII string consisting of letters A-z)
|
||||
#(length)-byte data
|
||||
#4-byte CRC
|
||||
# PNG file consists of 8-byte magic number, followed by arbitrary number of chunks
|
||||
# Each chunk has the following structure:
|
||||
# 4-byte length (unsigned int, can be zero)
|
||||
# 4-byte name (ASCII string consisting of letters A-z)
|
||||
# (length)-byte data
|
||||
# 4-byte CRC
|
||||
#
|
||||
#Any data after chunk named IEND is irrelevant
|
||||
#APNG frame count is inside a chunk named acTL, in first 4 bytes of data.
|
||||
# Any data after chunk named IEND is irrelevant
|
||||
# APNG frame count is inside a chunk named acTL, in first 4 bytes of data.
|
||||
|
||||
|
||||
#This function calls associated block for each PNG chunk
|
||||
#parameters passed are |chunk_name, chunk_length, file_descriptor|
|
||||
#returns true if file is read succesfully from start to IEND,
|
||||
#or if 100 000 chunks are read; returns false otherwise.
|
||||
# This function calls associated block for each PNG chunk
|
||||
# parameters passed are |chunk_name, chunk_length, file_descriptor|
|
||||
# returns true if file is read succesfully from start to IEND,
|
||||
# or if 100 000 chunks are read; returns false otherwise.
|
||||
def each_chunk
|
||||
iend_reached = false
|
||||
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
|
||||
|
||||
chunks = 0
|
||||
|
||||
#We could be dealing with large number of chunks,
|
||||
#so the code should be optimized to create as few objects as possible.
|
||||
#All literal strings are frozen and read() function uses string buffer.
|
||||
# We could be dealing with large number of chunks,
|
||||
# so the code should be optimized to create as few objects as possible.
|
||||
# All literal strings are frozen and read() function uses string buffer.
|
||||
chunkheader = ''
|
||||
while file.read(8, chunkheader)
|
||||
#ensure that first 8 bytes from chunk were read properly
|
||||
if chunkheader == nil || chunkheader.length < 8
|
||||
# ensure that first 8 bytes from chunk were read properly
|
||||
if chunkheader.nil? || chunkheader.length < 8
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -48,23 +47,23 @@ class APNGInspector
|
||||
return false if chunk_name =~ /[^A-Za-z]/
|
||||
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
|
||||
iend_reached = true
|
||||
break
|
||||
end
|
||||
|
||||
#check if we processed too many chunks already
|
||||
#if we did, file is probably maliciously formed
|
||||
#fail gracefully without marking the file as corrupt
|
||||
# check if we processed too many chunks already
|
||||
# if we did, file is probably maliciously formed
|
||||
# fail gracefully without marking the file as corrupt
|
||||
chunks += 1
|
||||
if chunks > 100000
|
||||
iend_reached = true
|
||||
break
|
||||
end
|
||||
|
||||
#jump to the next chunk - go forward by chunk length + 4 bytes CRC
|
||||
file.seek(current_pos+chunk_len+4, IO::SEEK_SET)
|
||||
# jump to the next chunk - go forward by chunk length + 4 bytes CRC
|
||||
file.seek(current_pos + chunk_len + 4, IO::SEEK_SET)
|
||||
end
|
||||
end
|
||||
return iend_reached
|
||||
@@ -99,14 +98,13 @@ class APNGInspector
|
||||
|
||||
private
|
||||
|
||||
#return number of frames in acTL or -1 on failure
|
||||
def parse_actl(len, file)
|
||||
return -1 if len != 8
|
||||
framedata = file.read(4)
|
||||
if framedata == nil || framedata.length != 4
|
||||
return -1
|
||||
end
|
||||
return framedata.unpack("N".freeze)[0]
|
||||
# return number of frames in acTL or -1 on failure
|
||||
def parse_actl(len, file)
|
||||
return -1 if len != 8
|
||||
framedata = file.read(4)
|
||||
if framedata.nil? || framedata.length != 4
|
||||
return -1
|
||||
end
|
||||
|
||||
return framedata.unpack1("N".freeze)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module ApproverPruner
|
||||
extend self
|
||||
module_function
|
||||
|
||||
def inactive_approvers
|
||||
User.where("bit_prefs & ? > 0", User.flag_value_for("can_approve_posts")).select do |user|
|
||||
|
||||
@@ -64,13 +64,10 @@ class DText
|
||||
def self.parse_embedded_tag_request_text(text)
|
||||
[TagAlias, TagImplication, BulkUpdateRequest].each do |tag_request|
|
||||
text = text.gsub(tag_request.embedded_pattern) do |match|
|
||||
begin
|
||||
obj = tag_request.find($~[:id])
|
||||
tag_request_message(obj) || match
|
||||
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
match
|
||||
end
|
||||
obj = tag_request.find($~[:id])
|
||||
tag_request_message(obj) || match
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
match
|
||||
end
|
||||
end
|
||||
|
||||
@@ -143,7 +140,7 @@ class DText
|
||||
|
||||
def self.dtext_links_differ?(a, 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
|
||||
|
||||
def self.strip_blocks(string, tag)
|
||||
|
||||
@@ -36,4 +36,4 @@ module Danbooru
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module DanbooruImageResizer
|
||||
extend self
|
||||
module_function
|
||||
|
||||
# Taken from ArgyllCMS 2.0.0 (see also: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html)
|
||||
SRGB_PROFILE = "#{Rails.root}/config/sRGB.icm"
|
||||
@@ -46,7 +46,6 @@ module DanbooruImageResizer
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
ensure
|
||||
temp.close
|
||||
temp.unlink
|
||||
|
||||
@@ -39,14 +39,14 @@ class DanbooruLogger
|
||||
::NewRelic::Agent.add_custom_attributes(attributes)
|
||||
end
|
||||
|
||||
private
|
||||
private_class_method
|
||||
|
||||
# flatten_hash({ foo: { bar: { baz: 42 } } })
|
||||
# => { "foo.bar.baz" => 42 }
|
||||
def self.flatten_hash(hash)
|
||||
hash.each_with_object({}) do |(k, v), h|
|
||||
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
|
||||
end
|
||||
else
|
||||
|
||||
@@ -4,8 +4,8 @@ class DanbooruMath
|
||||
return 0
|
||||
end
|
||||
|
||||
z = Statistics2.pnormaldist(1-(1-confidence)/2)
|
||||
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)
|
||||
z = Statistics2.pnormaldist(1 - (1 - confidence) / 2)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# API requests must send a user agent and must use gzip compression, otherwise
|
||||
# 403 errors will be returned.
|
||||
|
||||
class DeviantArtApiClient < Struct.new(:deviation_id)
|
||||
DeviantArtApiClient = Struct.new(:deviation_id) do
|
||||
extend Memoist
|
||||
|
||||
def extended_fetch
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'resolv'
|
||||
module Downloads
|
||||
class File
|
||||
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]
|
||||
|
||||
@@ -12,7 +12,7 @@ module Downloads
|
||||
|
||||
validate :validate_url
|
||||
|
||||
def initialize(url, referer=nil)
|
||||
def initialize(url, referer = nil)
|
||||
@url = Addressable::URI.parse(url) rescue nil
|
||||
@referer = referer
|
||||
validate!
|
||||
@@ -59,7 +59,7 @@ module Downloads
|
||||
else
|
||||
raise Error.new("HTTP error code: #{res.code} #{res.message}")
|
||||
end
|
||||
end # def
|
||||
end
|
||||
|
||||
# Prevent Cloudflare from potentially mangling the image. See issue #3528.
|
||||
def uncached_url
|
||||
@@ -87,7 +87,7 @@ module Downloads
|
||||
timeout: 10,
|
||||
stream_body: true,
|
||||
headers: strategy.headers,
|
||||
connection_adapter: ValidatingConnectionAdapter,
|
||||
connection_adapter: ValidatingConnectionAdapter
|
||||
}.deep_merge(Danbooru.config.httparty_options)
|
||||
end
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ class ForumUpdater
|
||||
|
||||
def update(message, title_tag = nil)
|
||||
return if forum_topic.nil?
|
||||
|
||||
|
||||
CurrentUser.scoped(User.system) do
|
||||
create_response(message)
|
||||
update_title(title_tag) if title_tag
|
||||
|
||||
@@ -18,7 +18,8 @@ module Moderator
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def search_by_ip_addr(ip_addrs)
|
||||
sums = Hash.new {|h, k| h[k] = 0}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class NicoSeigaApiClient
|
||||
form["password"] = Danbooru.config.nico_seiga_password
|
||||
end.click_button
|
||||
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
|
||||
Cache.put("nico-seiga-session", session.value, 1.week)
|
||||
else
|
||||
@@ -74,7 +74,7 @@ class NicoSeigaApiClient
|
||||
|
||||
def 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)
|
||||
end
|
||||
|
||||
@@ -51,7 +51,7 @@ class NicoSeigaMangaApiClient
|
||||
|
||||
def 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)
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ module NoteSanitizer
|
||||
"span" => %w(class),
|
||||
"div" => %w(class align),
|
||||
"p" => %w(class align),
|
||||
"font" => %w(color size),
|
||||
"font" => %w(color size)
|
||||
}
|
||||
|
||||
ALLOWED_PROPERTIES = %w(
|
||||
@@ -61,7 +61,7 @@ module NoteSanitizer
|
||||
:elements => ALLOWED_ELEMENTS,
|
||||
:attributes => ALLOWED_ATTRIBUTES,
|
||||
:add_attributes => {
|
||||
"a" => { "rel" => "external noreferrer nofollow" },
|
||||
"a" => { "rel" => "external noreferrer nofollow" }
|
||||
},
|
||||
:protocols => {
|
||||
"a" => {
|
||||
@@ -73,9 +73,9 @@ module NoteSanitizer
|
||||
allow_hacks: false,
|
||||
at_rules: [],
|
||||
protocols: [],
|
||||
properties: ALLOWED_PROPERTIES,
|
||||
properties: ALLOWED_PROPERTIES
|
||||
},
|
||||
:transformers => method(:relativize_links),
|
||||
:transformers => method(:relativize_links)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module PaginationExtension
|
||||
class PaginationError < Exception ; end
|
||||
class PaginationError < Exception; end
|
||||
|
||||
attr_accessor :current_page, :records_per_page, :paginator_count, :paginator_mode
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class PawooApiClient
|
||||
STATUS1 = %r!\Ahttps?://pawoo\.net/web/statuses/(\d+)!
|
||||
STATUS2 = %r!\Ahttps?://pawoo\.net/@.+?/([^/]+)!
|
||||
|
||||
class MissingConfigurationError < Exception ; end
|
||||
class MissingConfigurationError < Exception; end
|
||||
|
||||
class Account
|
||||
attr_reader :json
|
||||
|
||||
@@ -23,8 +23,8 @@ class PixivApiClient
|
||||
VistaPro Sculptris Comi\ Po! modo DAZ\ Studio 3D-Coat
|
||||
]
|
||||
|
||||
class Error < Exception ; end
|
||||
class BadIDError < Error ; end
|
||||
class Error < Exception; end
|
||||
class BadIDError < Error; end
|
||||
|
||||
class WorkResponse
|
||||
attr_reader :json, :pages, :name, :moniker, :user_id, :page_count, :tags
|
||||
@@ -93,7 +93,7 @@ class PixivApiClient
|
||||
end
|
||||
|
||||
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/novel-cover-original/img/2017/07/27/23/14/17/8465454_80685d10e6df4d7d53ad347ddc18a36b.jpg (532129b)
|
||||
@@ -101,7 +101,8 @@ class PixivApiClient
|
||||
end
|
||||
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
|
||||
|
||||
def find_original(x)
|
||||
@@ -123,7 +124,7 @@ class PixivApiClient
|
||||
def name
|
||||
json["body"]["user"]["name"]
|
||||
end
|
||||
|
||||
|
||||
def user_id
|
||||
json["body"]["user"]["userId"]
|
||||
end
|
||||
@@ -177,11 +178,10 @@ class PixivApiClient
|
||||
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.")
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def fanbox(fanbox_id)
|
||||
@@ -228,14 +228,14 @@ class PixivApiClient
|
||||
headers = {
|
||||
"Referer": "http://www.pixiv.net",
|
||||
"X-Client-Time": client_time,
|
||||
"X-Client-Hash": client_hash,
|
||||
"X-Client-Hash": client_hash
|
||||
}
|
||||
params = {
|
||||
username: Danbooru.config.pixiv_login,
|
||||
password: Danbooru.config.pixiv_password,
|
||||
grant_type: "password",
|
||||
client_id: CLIENT_ID,
|
||||
client_secret: CLIENT_SECRET,
|
||||
client_secret: CLIENT_SECRET
|
||||
}
|
||||
url = "https://oauth.secure.pixiv.net/auth/token"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class PixivUgoiraConverter
|
||||
path = File.join(tmpdir, "images", file.name)
|
||||
file.extract(path)
|
||||
end
|
||||
|
||||
|
||||
# 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 =~ /\A(\d{6})(\.\w{,4})\Z/
|
||||
@@ -26,7 +26,7 @@ class PixivUgoiraConverter
|
||||
path_from = File.join(tmpdir, "images", last_file_name)
|
||||
path_to = File.join(tmpdir, "images", new_last_filename)
|
||||
FileUtils.cp(path_from, path_to)
|
||||
|
||||
|
||||
delay_sum = 0
|
||||
timecodes_path = File.join(tmpdir, "timecodes.tc")
|
||||
File.open(timecodes_path, "w+") do |f|
|
||||
@@ -50,7 +50,6 @@ class PixivUgoiraConverter
|
||||
Rails.logger.error "[write_webm][ffmpeg] #{line}"
|
||||
end
|
||||
Rails.logger.error "[write_webm] ******************************"
|
||||
return
|
||||
end
|
||||
|
||||
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}"
|
||||
end
|
||||
Rails.logger.error "[write_webm] ******************************"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ class PixivWebAgent
|
||||
COMIC_SESSION_COOKIE_KEY = "_pixiv-comic_session"
|
||||
|
||||
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
|
||||
|
||||
def self.build
|
||||
|
||||
@@ -22,9 +22,9 @@ class PopularSearchService
|
||||
JSON.parse(fetch_data.to_s).map {|x| x[0]}
|
||||
end
|
||||
|
||||
def fetch_data()
|
||||
def fetch_data
|
||||
return [] unless self.class.enabled?
|
||||
|
||||
|
||||
dates = date.strftime("%Y-%m-%d")
|
||||
|
||||
data = Cache.get("ps-day-#{dates}", 1.minute) do
|
||||
@@ -54,8 +54,7 @@ class PopularSearchService
|
||||
end
|
||||
|
||||
data
|
||||
|
||||
rescue => e
|
||||
rescue StandardError => e
|
||||
DanbooruLogger.log(e)
|
||||
return []
|
||||
end
|
||||
|
||||
@@ -5,16 +5,14 @@ class PostPruner
|
||||
prune_mod_actions!
|
||||
end
|
||||
|
||||
protected
|
||||
protected
|
||||
|
||||
def prune_pending!
|
||||
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|
|
||||
begin
|
||||
post.delete!("Unapproved in three days")
|
||||
rescue PostFlag::Error
|
||||
# swallow
|
||||
end
|
||||
post.delete!("Unapproved in three days")
|
||||
rescue PostFlag::Error
|
||||
# swallow
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -299,7 +299,7 @@ class PostQueryBuilder
|
||||
if q[:flagger_ids_neg]
|
||||
q[:flagger_ids_neg].each do |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?
|
||||
relation = relation.where.not("posts.id": post_ids)
|
||||
end
|
||||
@@ -310,11 +310,11 @@ class PostQueryBuilder
|
||||
if q[:flagger_ids]
|
||||
q[:flagger_ids].each do |flagger_id|
|
||||
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"
|
||||
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)
|
||||
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)
|
||||
end
|
||||
end
|
||||
@@ -322,7 +322,7 @@ class PostQueryBuilder
|
||||
|
||||
if q[:appealer_ids_neg]
|
||||
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
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ module PostSets
|
||||
end
|
||||
|
||||
def hidden_posts
|
||||
posts.select { |p| !p.visible? }
|
||||
posts.reject { |p| p.visible? }
|
||||
end
|
||||
|
||||
def banned_posts
|
||||
@@ -122,17 +122,17 @@ module PostSets
|
||||
|
||||
def posts
|
||||
@posts ||= begin
|
||||
@post_count = get_post_count()
|
||||
@post_count = get_post_count
|
||||
|
||||
if is_random?
|
||||
temp = get_random_posts()
|
||||
temp = get_random_posts
|
||||
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)
|
||||
else
|
||||
temp = ::Post.tag_match(tag_string).where("true /* PostSets::Post#posts:2 */").paginate(page, :count => post_count, :limit => per_page)
|
||||
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.each # hack to force rails to eager load
|
||||
@@ -159,11 +159,11 @@ module PostSets
|
||||
end
|
||||
|
||||
def is_empty_tag?
|
||||
tag_array.size == 0
|
||||
tag_array.empty?
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def current_page
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module PostSets
|
||||
class Recommended < PostSets::Post
|
||||
attr_reader :posts
|
||||
|
||||
|
||||
def initialize(posts)
|
||||
super("")
|
||||
@posts = posts
|
||||
|
||||
@@ -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 = tags.sort_by do |tag|
|
||||
# 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
|
||||
|
||||
tags
|
||||
|
||||
@@ -68,7 +68,7 @@ class RelatedTagQuery
|
||||
}
|
||||
end
|
||||
|
||||
protected
|
||||
protected
|
||||
|
||||
def tags_with_categories(list_of_tag_names)
|
||||
Tag.categories_for(list_of_tag_names).to_a
|
||||
|
||||
@@ -47,6 +47,5 @@ module Reports
|
||||
def removed_tags
|
||||
removed_tags_array.join(' ')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ module Reports
|
||||
else
|
||||
@max_date = Date.today
|
||||
end
|
||||
|
||||
|
||||
@queries = queries.to_s.split(/,\s*/).join(",")
|
||||
end
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ module Reports
|
||||
return 0
|
||||
end
|
||||
|
||||
z = Statistics2.pnormaldist(1-(1-confidence)/2)
|
||||
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)
|
||||
z = Statistics2.pnormaldist(1 - (1 - confidence) / 2)
|
||||
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)
|
||||
end
|
||||
|
||||
def self.min_time
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class SessionLoader
|
||||
class AuthenticationFailure < Exception ; end
|
||||
class AuthenticationFailure < Exception; end
|
||||
|
||||
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?
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def set_statement_timeout
|
||||
timeout = CurrentUser.user.statement_timeout
|
||||
|
||||
@@ -30,6 +30,6 @@ class SetDiff
|
||||
distance = ->(other) { ::DidYouMean::Levenshtein.distance(string, other) }
|
||||
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
|
||||
|
||||
@@ -10,11 +10,11 @@ module Sources
|
||||
Strategies::ArtStation,
|
||||
Strategies::Nijie,
|
||||
Strategies::Pawoo,
|
||||
Strategies::Moebooru,
|
||||
Strategies::Moebooru
|
||||
]
|
||||
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 || default&.new(url, referer)
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
attr_reader :json, :image_urls
|
||||
attr_reader :json
|
||||
|
||||
def domains
|
||||
["artstation.com"]
|
||||
@@ -38,13 +38,11 @@ module Sources::Strategies
|
||||
end
|
||||
|
||||
def image_urls
|
||||
image_urls_sub
|
||||
.map { |asset| original_asset_url(asset) }
|
||||
@image_urls ||= image_urls_sub.map { |asset| original_asset_url(asset) }
|
||||
end
|
||||
memoize :image_urls
|
||||
|
||||
def page_url
|
||||
return nil unless project_id.present?
|
||||
return nil if project_id.blank?
|
||||
|
||||
if artist_name.present?
|
||||
"https://#{artist_name}.artstation.com/projects/#{project_id}"
|
||||
@@ -54,7 +52,7 @@ module Sources::Strategies
|
||||
end
|
||||
|
||||
def profile_url
|
||||
return nil unless artist_name.present?
|
||||
return nil if artist_name.blank?
|
||||
"https://www.artstation.com/#{artist_name}"
|
||||
end
|
||||
|
||||
@@ -84,14 +82,13 @@ module Sources::Strategies
|
||||
profile_url.present? && url == profile_url
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def image_urls_sub
|
||||
if url.match?(ASSET)
|
||||
return [url]
|
||||
end
|
||||
|
||||
api_response[:assets].to_a
|
||||
api_response[:assets]
|
||||
.to_a
|
||||
.select { |asset| asset[:asset_type] == "image" }
|
||||
.map { |asset| asset[:image_url] }
|
||||
end
|
||||
@@ -100,7 +97,7 @@ module Sources::Strategies
|
||||
# purposes
|
||||
|
||||
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
|
||||
|
||||
def project_id
|
||||
@@ -108,7 +105,7 @@ module Sources::Strategies
|
||||
end
|
||||
|
||||
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")
|
||||
return {} if resp.code != 200
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 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
|
||||
# URL to download the image from. But it can also be used to normalize a URL
|
||||
# for use with the artist finder.
|
||||
# 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
|
||||
# URL to download the image from. But it can also be used to normalize a URL
|
||||
# for use with the artist finder.
|
||||
#
|
||||
# Design Principles
|
||||
#
|
||||
@@ -24,11 +24,11 @@ module Sources
|
||||
true
|
||||
end
|
||||
|
||||
# * <tt>url</tt> - Should point to a resource suitable for
|
||||
# downloading. This may sometimes point to the binary file.
|
||||
# * <tt>url</tt> - Should point to a resource suitable for
|
||||
# downloading. This may sometimes point to the binary file.
|
||||
# It may also point to the artist's profile page, in cases
|
||||
# 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.
|
||||
# * <tt>referer_url</tt> - Sometimes the HTML page cannot be
|
||||
# determined from <tt>url</tt>. You should generally pass in a
|
||||
@@ -63,9 +63,9 @@ module Sources
|
||||
nil
|
||||
end
|
||||
|
||||
# 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
|
||||
# be a list of JPEG, PNG, GIF, WEBM, MP4, ZIP, etc. It is what the
|
||||
# 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
|
||||
# be a list of JPEG, PNG, GIF, WEBM, MP4, ZIP, etc. It is what the
|
||||
# downloader will fetch and save to disk.
|
||||
def image_urls
|
||||
raise NotImplementedError
|
||||
@@ -269,7 +269,7 @@ module Sources
|
||||
:tag_name => tag_name,
|
||||
:other_names => other_names,
|
||||
:profile_url => profile_url,
|
||||
:profile_urls => profile_urls,
|
||||
:profile_urls => profile_urls
|
||||
},
|
||||
:artists => artists.as_json(include: :sorted_urls),
|
||||
:image_url => image_url,
|
||||
@@ -284,18 +284,16 @@ module Sources
|
||||
:title => artist_commentary_title,
|
||||
:description => artist_commentary_desc,
|
||||
: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
|
||||
|
||||
def to_json
|
||||
def to_json(*_args)
|
||||
to_h.to_json
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def http_exists?(url, headers)
|
||||
res = HTTParty.head(url, Danbooru.config.httparty_options.deep_merge(headers: headers))
|
||||
res.success?
|
||||
@@ -306,7 +304,7 @@ module Sources
|
||||
def self.to_dtext(text)
|
||||
text = text.to_s
|
||||
text = Rails::Html::FullSanitizer.new.sanitize(text, encode_special_chars: false)
|
||||
text = CGI::unescapeHTML(text)
|
||||
text = CGI.unescapeHTML(text)
|
||||
text
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,8 +57,6 @@ module Sources
|
||||
PATH_PROFILE = %r{\Ahttps?://(www\.)?deviantart\.com/#{ARTIST}/?\z}i
|
||||
SUBDOMAIN_PROFILE = %r{\Ahttps?://#{ARTIST}\.deviantart\.com/?\z}i
|
||||
|
||||
attr_accessor :api_client
|
||||
|
||||
def domains
|
||||
["deviantart.net", "deviantart.com"]
|
||||
end
|
||||
@@ -211,8 +209,6 @@ module Sources
|
||||
end.gsub(/\A[[:space:]]+|[[:space:]]+\z/, "")
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def self.deviation_id_from_url(url)
|
||||
if url =~ ASSET
|
||||
$~[:base36_deviation_id].try(:to_i, 36)
|
||||
|
||||
@@ -130,8 +130,6 @@ module Sources
|
||||
end
|
||||
memoize :tags
|
||||
|
||||
public
|
||||
|
||||
def api_client
|
||||
if illust_id
|
||||
NicoSeigaApiClient.new(illust_id: illust_id)
|
||||
|
||||
@@ -120,9 +120,11 @@ module Sources
|
||||
def tags
|
||||
links = page&.search("div#view-tag a") || []
|
||||
|
||||
links.select do |node|
|
||||
search_links = links.select do |node|
|
||||
node["href"] =~ /search\.php/
|
||||
end.map do |node|
|
||||
end
|
||||
|
||||
search_links.map do |node|
|
||||
[node.inner_text, "https://nijie.info" + node.attr("href")]
|
||||
end
|
||||
end
|
||||
@@ -131,8 +133,6 @@ module Sources
|
||||
"nijie" + artist_id.to_s
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def self.to_dtext(text)
|
||||
text = text.to_s.gsub(/\r\n|\r/, "<br>")
|
||||
DText.from_html(text).strip
|
||||
@@ -196,7 +196,7 @@ module Sources
|
||||
form['password'] = Danbooru.config.nijie_password
|
||||
end.click_button
|
||||
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
|
||||
end
|
||||
|
||||
@@ -207,7 +207,6 @@ module Sources
|
||||
mech.cookie_jar.add(cookie)
|
||||
|
||||
mech
|
||||
|
||||
rescue Mechanize::ResponseCodeError => x
|
||||
if x.response_code.to_i == 429
|
||||
sleep(5)
|
||||
|
||||
@@ -85,8 +85,6 @@ module Sources::Strategies
|
||||
end.strip
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def api_response
|
||||
[url, referer_url].each do |x|
|
||||
if client = PawooApiClient.new.get(x)
|
||||
|
||||
@@ -69,7 +69,7 @@ module Sources
|
||||
if text.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
text = text.gsub(%r!https?://www\.pixiv\.net/member_illust\.php\?mode=medium&illust_id=([0-9]+)!i) do |match|
|
||||
pixiv_id = $1
|
||||
%(pixiv ##{pixiv_id} "»":[/posts?tags=pixiv:#{pixiv_id}])
|
||||
@@ -132,11 +132,10 @@ module Sources
|
||||
end
|
||||
|
||||
return url
|
||||
|
||||
rescue PixivApiClient::BadIDError
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def canonical_url
|
||||
return image_url
|
||||
end
|
||||
@@ -183,7 +182,7 @@ module Sources
|
||||
rescue PixivApiClient::BadIDError
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def headers
|
||||
if fanbox_id.present?
|
||||
# need the session to download fanbox images
|
||||
@@ -236,8 +235,6 @@ module Sources
|
||||
illust_id.present? ? "pixiv:#{illust_id}" : "source:#{canonical_url}"
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def image_urls_sub
|
||||
if url =~ FANBOX_IMAGE
|
||||
return [url]
|
||||
|
||||
@@ -131,8 +131,6 @@ module Sources::Strategies
|
||||
DText.from_html(artist_commentary_desc).strip
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
# Look for the biggest available version on media.tumblr.com. A bigger
|
||||
# version may or may not exist.
|
||||
#
|
||||
@@ -181,7 +179,7 @@ module Sources::Strategies
|
||||
|
||||
response = Danbooru::Http.cache(1.minute).get(
|
||||
"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
|
||||
|
||||
@@ -134,15 +134,13 @@ module Sources::Strategies
|
||||
url_replacements = url_replacements.to_h
|
||||
|
||||
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!#([^[:space:]]+)!, '"#\\1":[https://twitter.com/hashtag/\\1]')
|
||||
desc = desc.gsub(%r!@([a-zA-Z0-9_]+)!, '"@\\1":[https://twitter.com/\\1]')
|
||||
desc.strip
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
def api_client
|
||||
TwitterApiClient.new(Danbooru.config.twitter_api_key, Danbooru.config.twitter_api_secret)
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ class SpamDetector
|
||||
# rakismet raises an exception if the api key or url aren't configured
|
||||
def self.working?
|
||||
Rakismet.validate_key
|
||||
rescue
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ class SpamDetector
|
||||
end
|
||||
|
||||
is_spam
|
||||
rescue => exception
|
||||
rescue StandardError => exception
|
||||
DanbooruLogger.log(exception)
|
||||
false
|
||||
end
|
||||
|
||||
@@ -20,7 +20,8 @@ class SqsService
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def sqs
|
||||
@sqs ||= Aws::SQS::Client.new(
|
||||
credentials: Danbooru.config.aws_credentials,
|
||||
|
||||
@@ -45,7 +45,7 @@ class StorageManager
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def file_url(post, type, tagged_filenames: false)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class StorageManager::Local < StorageManager
|
||||
DEFAULT_PERMISSIONS = 0644
|
||||
DEFAULT_PERMISSIONS = 0o644
|
||||
|
||||
def store(io, dest_path)
|
||||
temp_path = dest_path + "-" + SecureRandom.uuid + ".tmp"
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
=begin
|
||||
|
||||
Generalizes the hybrid storage manager to be more declarative in
|
||||
syntax. Matches are executed in order of appearance so the first
|
||||
matching manager is returned. You should always add at least one
|
||||
manager with no constraints as a default case.
|
||||
|
||||
#
|
||||
# Generalizes the hybrid storage manager to be more declarative in
|
||||
# syntax. Matches are executed in order of appearance so the first
|
||||
# matching manager is returned. You should always add at least one
|
||||
# manager with no constraints as a default case.
|
||||
#
|
||||
### Example
|
||||
|
||||
StorageManager::Match.new do |matcher|
|
||||
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")
|
||||
end
|
||||
|
||||
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")
|
||||
end
|
||||
|
||||
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")
|
||||
end
|
||||
|
||||
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")
|
||||
end
|
||||
|
||||
matcher.add_manager({}) do
|
||||
StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "#{CurrentUser.root_url}/data")
|
||||
end
|
||||
end
|
||||
|
||||
=end
|
||||
#
|
||||
# StorageManager::Match.new do |matcher|
|
||||
# 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")
|
||||
# end
|
||||
#
|
||||
# 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")
|
||||
# end
|
||||
#
|
||||
# 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")
|
||||
# end
|
||||
#
|
||||
# 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")
|
||||
# end
|
||||
#
|
||||
# matcher.add_manager({}) do
|
||||
# StorageManager::SFTP.new(*Danbooru.config.all_server_hosts, base_url: "#{CurrentUser.root_url}/data")
|
||||
# end
|
||||
# end
|
||||
#
|
||||
|
||||
class StorageManager::Match < StorageManager
|
||||
def initialize
|
||||
@@ -56,7 +54,7 @@ class StorageManager::Match < StorageManager
|
||||
end
|
||||
|
||||
if params[:type] && constraints[:type]
|
||||
if constraints[:type].respond_to?(:include?)
|
||||
if constraints[:type].respond_to?(:include?)
|
||||
if !constraints[:type].include?(params[:type])
|
||||
match = false
|
||||
end
|
||||
@@ -109,4 +107,3 @@ class StorageManager::Match < StorageManager
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
class StorageManager::SFTP < StorageManager
|
||||
DEFAULT_PERMISSIONS = 0644
|
||||
DEFAULT_PERMISSIONS = 0o644
|
||||
|
||||
# http://net-ssh.github.io/net-ssh/Net/SSH.html#method-c-start
|
||||
DEFAULT_SSH_OPTIONS = {
|
||||
timeout: 10,
|
||||
logger: Rails.logger,
|
||||
verbose: :fatal,
|
||||
non_interactive: true,
|
||||
non_interactive: true
|
||||
}
|
||||
|
||||
attr_reader :hosts, :ssh_options
|
||||
@@ -22,22 +22,20 @@ class StorageManager::SFTP < StorageManager
|
||||
dest_backup_path = dest_path + "-" + SecureRandom.uuid + ".bak"
|
||||
|
||||
each_host do |host, sftp|
|
||||
begin
|
||||
sftp.upload!(file.path, temp_upload_path)
|
||||
sftp.setstat!(temp_upload_path, permissions: DEFAULT_PERMISSIONS)
|
||||
sftp.upload!(file.path, temp_upload_path)
|
||||
sftp.setstat!(temp_upload_path, permissions: DEFAULT_PERMISSIONS)
|
||||
|
||||
# `rename!` can't overwrite existing files, so if a file already exists
|
||||
# at dest_path we move it out of the way first.
|
||||
force { sftp.rename!(dest_path, dest_backup_path) }
|
||||
force { sftp.rename!(temp_upload_path, dest_path) }
|
||||
rescue StandardError => e
|
||||
# if anything fails, try to move the original file back in place (if it was moved).
|
||||
force { sftp.rename!(dest_backup_path, dest_path) }
|
||||
raise Error, e
|
||||
ensure
|
||||
force { sftp.remove!(temp_upload_path) }
|
||||
force { sftp.remove!(dest_backup_path) }
|
||||
end
|
||||
# `rename!` can't overwrite existing files, so if a file already exists
|
||||
# at dest_path we move it out of the way first.
|
||||
force { sftp.rename!(dest_path, dest_backup_path) }
|
||||
force { sftp.rename!(temp_upload_path, dest_path) }
|
||||
rescue StandardError => e
|
||||
# if anything fails, try to move the original file back in place (if it was moved).
|
||||
force { sftp.rename!(dest_backup_path, dest_path) }
|
||||
raise Error, e
|
||||
ensure
|
||||
force { sftp.remove!(temp_upload_path) }
|
||||
force { sftp.remove!(dest_backup_path) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class TagAliasRequest
|
||||
def self.command_string(antecedent_name, consequent_name, id=nil)
|
||||
def self.command_string(antecedent_name, consequent_name, id = nil)
|
||||
if id
|
||||
return "[ta:#{id}]"
|
||||
end
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module TagAutocomplete
|
||||
extend self
|
||||
module_function
|
||||
|
||||
PREFIX_BOUNDARIES = "(_/:;-"
|
||||
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::Xml
|
||||
|
||||
@@ -28,7 +28,7 @@ module TagAutocomplete
|
||||
candidates = count_sort(
|
||||
query,
|
||||
search_exact(query, 8) +
|
||||
search_prefix(query, 4) +
|
||||
search_prefix(query, 4) +
|
||||
search_correct(query, 2) +
|
||||
search_aliases(query, 3)
|
||||
)
|
||||
@@ -40,7 +40,7 @@ module TagAutocomplete
|
||||
end.reverse.slice(0, LIMIT)
|
||||
end
|
||||
|
||||
def search_exact(query, n=4)
|
||||
def search_exact(query, n = 4)
|
||||
Tag
|
||||
.where("name like ? escape e'\\\\'", query.to_escaped_for_sql_like + "%")
|
||||
.where("post_count > 0")
|
||||
@@ -50,7 +50,7 @@ module TagAutocomplete
|
||||
.map {|row| Result.new(*row, nil, :exact)}
|
||||
end
|
||||
|
||||
def search_correct(query, n=2)
|
||||
def search_correct(query, n = 2)
|
||||
if query.size <= 3
|
||||
return []
|
||||
end
|
||||
@@ -66,7 +66,7 @@ module TagAutocomplete
|
||||
.map {|row| Result.new(*row, nil, :correct)}
|
||||
end
|
||||
|
||||
def search_prefix(query, n=3)
|
||||
def search_prefix(query, n = 3)
|
||||
if query.size >= 5
|
||||
return []
|
||||
end
|
||||
@@ -97,7 +97,7 @@ module TagAutocomplete
|
||||
.map {|row| Result.new(*row, nil, :prefix)}
|
||||
end
|
||||
|
||||
def search_aliases(query, n=10)
|
||||
def search_aliases(query, n = 10)
|
||||
wildcard_name = query + "*"
|
||||
TagAlias
|
||||
.select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name")
|
||||
@@ -112,4 +112,3 @@ module TagAutocomplete
|
||||
.map {|row| Result.new(*row, :alias)}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module TagChangeNoticeService
|
||||
extend self
|
||||
module_function
|
||||
|
||||
def get_forum_topic_id(tag)
|
||||
Cache.get("tcn:#{tag}")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class TagImplicationRequest
|
||||
def self.command_string(antecedent_name, consequent_name, id=nil)
|
||||
def self.command_string(antecedent_name, consequent_name, id = nil)
|
||||
if id
|
||||
return "[ti:#{id}]"
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module TagRelationshipRetirementService
|
||||
THRESHOLD = 2.year
|
||||
|
||||
extend self
|
||||
module_function
|
||||
THRESHOLD = 2.years
|
||||
|
||||
def forum_topic_title
|
||||
return "Retired tag aliases & implications"
|
||||
|
||||
1
app/logical/upload_error_checker.rb
Normal file → Executable file
1
app/logical/upload_error_checker.rb
Normal file → Executable file
@@ -19,4 +19,3 @@ class UploadErrorChecker
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ class UploadService
|
||||
@upload.save!
|
||||
@post = create_post_from_upload(@upload)
|
||||
return @upload
|
||||
|
||||
rescue Exception => x
|
||||
@upload.update(status: "error: #{x.class} - #{x.message}", backtrace: x.backtrace.join("\n"))
|
||||
@upload
|
||||
|
||||
@@ -62,7 +62,6 @@ class UploadService
|
||||
CurrentUser.as(uploader_id) do
|
||||
start!
|
||||
end
|
||||
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
return
|
||||
end
|
||||
@@ -106,9 +105,9 @@ class UploadService
|
||||
end
|
||||
|
||||
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
|
||||
pred.initialize_attributes
|
||||
|
||||
@@ -124,5 +123,4 @@ class UploadService
|
||||
return pred
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -95,7 +95,7 @@ class UploadService
|
||||
upload = preprocessor.finish!(upload)
|
||||
raise Error, upload.status if upload.is_errored?
|
||||
md5_changed = upload.md5 != post.md5
|
||||
|
||||
|
||||
replacement.replacement_url = find_replacement_url(replacement, upload)
|
||||
|
||||
if md5_changed
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class UploadService
|
||||
module Utils
|
||||
extend self
|
||||
module_function
|
||||
class CorruptFileError < RuntimeError; end
|
||||
|
||||
def file_header_to_file_ext(file)
|
||||
@@ -93,7 +93,7 @@ class UploadService
|
||||
|
||||
def generate_video_crop_for(video, width)
|
||||
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)
|
||||
vp.close
|
||||
return crop
|
||||
@@ -108,7 +108,7 @@ class UploadService
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
@@ -140,8 +140,8 @@ class UploadService
|
||||
end
|
||||
end
|
||||
|
||||
# these methods are only really used during upload processing even
|
||||
# though logically they belong on upload. post can rely on the
|
||||
# these methods are only really used during upload processing even
|
||||
# though logically they belong on upload. post can rely on the
|
||||
# automatic tag that's added.
|
||||
def is_animated_gif?(upload, file)
|
||||
return false if upload.file_ext != "gif"
|
||||
@@ -179,7 +179,7 @@ class UploadService
|
||||
|
||||
def get_file_for_upload(upload, file: nil)
|
||||
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
|
||||
|
||||
@@ -190,8 +190,7 @@ class UploadService
|
||||
if !DanbooruImageResizer.validate_shell(file)
|
||||
raise CorruptFileError.new("File is corrupted")
|
||||
end
|
||||
|
||||
rescue
|
||||
rescue StandardError
|
||||
if attempts == 3
|
||||
raise
|
||||
end
|
||||
@@ -201,7 +200,7 @@ class UploadService
|
||||
end
|
||||
|
||||
if download.data[:ugoira_frame_data].present?
|
||||
upload.context = {
|
||||
upload.context = {
|
||||
"ugoira" => {
|
||||
"frame_data" => download.data[:ugoira_frame_data],
|
||||
"content_type" => "image/jpeg"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class UserDeletion
|
||||
class ValidationError < Exception ; end
|
||||
class ValidationError < Exception; end
|
||||
|
||||
attr_reader :user, :password
|
||||
|
||||
@@ -18,10 +18,10 @@ class UserDeletion
|
||||
create_mod_action
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
private
|
||||
|
||||
def create_mod_action
|
||||
ModAction.log("user ##{user.id} deleted",:user_delete)
|
||||
ModAction.log("user ##{user.id} deleted", :user_delete)
|
||||
end
|
||||
|
||||
def clear_saved_searches
|
||||
@@ -55,9 +55,7 @@ private
|
||||
def rename
|
||||
name = "user_#{user.id}"
|
||||
n = 0
|
||||
while User.where(:name => name).exists? && (n < 10)
|
||||
name += "~"
|
||||
end
|
||||
name += "~" while User.where(:name => name).exists? && (n < 10)
|
||||
|
||||
if n == 10
|
||||
raise ValidationError.new("New name could not be found")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class UserNameValidator < ActiveModel::EachValidator
|
||||
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] << "must be 2 to 100 characters long" if !name.length.between?(2, 100)
|
||||
rec.errors[attr] << "cannot have whitespace or colons" if name =~ /[[:space:]]|:/
|
||||
|
||||
@@ -18,22 +18,22 @@ class UserPromotion
|
||||
|
||||
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]
|
||||
end
|
||||
|
||||
if options.has_key?(:can_upload_free)
|
||||
if options.key?(:can_upload_free)
|
||||
user.can_upload_free = options[:can_upload_free]
|
||||
end
|
||||
|
||||
if options.has_key?(:no_feedback)
|
||||
if options.key?(:no_feedback)
|
||||
user.no_feedback = options[:no_feedback]
|
||||
end
|
||||
|
||||
if options.has_key?(:no_flagging)
|
||||
if options.key?(:no_flagging)
|
||||
user.no_flagging = options[:no_flagging]
|
||||
end
|
||||
|
||||
|
||||
user.inviter_id = promoter.id
|
||||
|
||||
create_user_feedback unless options[:is_upgrade]
|
||||
@@ -43,23 +43,23 @@ class UserPromotion
|
||||
user.save
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
private
|
||||
|
||||
def create_mod_actions
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
if user.level_changed?
|
||||
@@ -75,7 +75,7 @@ private
|
||||
# can't promote/demote moderators
|
||||
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
|
||||
end
|
||||
|
||||
@@ -108,11 +108,11 @@ private
|
||||
messages << "You gained the ability to give user feedback."
|
||||
end
|
||||
|
||||
if user.no_flagging? && !old_no_flagging
|
||||
if user.no_flagging? && !old_no_flagging
|
||||
messages << "You lost the ability to flag posts."
|
||||
elsif !user.no_flagging? && old_no_flagging
|
||||
messages << "You gained the ability to flag posts."
|
||||
end
|
||||
end
|
||||
|
||||
messages.join("\n")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user