Merge pull request #10 from insales/cleanup

Remove old code, DRY, fixes
This commit is contained in:
printercu
2018-11-27 17:08:58 +03:00
committed by GitHub
7 changed files with 111 additions and 168 deletions

View File

@@ -42,12 +42,21 @@ require 'paperclip/matchers'
require 'paperclip/callback_compatability'
require 'paperclip/railtie' if defined?(Rails)
require 'active_support/concern'
require 'active_support/core_ext/class/attribute'
# The base module that gets included in ActiveRecord::Base. See the
# documentation for Paperclip::ClassMethods for more useful information.
module Paperclip
VERSION = "2.2.9.2"
extend ActiveSupport::Concern
included do
class_attribute :attachment_definitions
Paperclip::CallbackCompatability.install_to(self)
end
class << self
# Provides configurability to Paperclip. There are a number of options available, such as:
# * whiny: Will raise an error if Paperclip cannot process thumbnails of
@@ -109,17 +118,6 @@ module Paperclip
File.exist?("/dev/null") ? "/dev/null" : "NUL"
end
def included base #:nodoc:
base.extend ClassMethods
base.class_attribute :attachment_definitions
if base.respond_to?(:set_callback)
base.send :include, Paperclip::CallbackCompatability::Rails3
else
base.send :include, Paperclip::CallbackCompatability::Rails21
end
end
def processor name #:nodoc:
name = name.to_s.camelize
processor = Paperclip.const_get(name)
@@ -217,11 +215,7 @@ module Paperclip
def has_attached_file name, options = {}
include InstanceMethods
if attachment_definitions.nil?
self.attachment_definitions = {}
else
self.attachment_definitions = self.attachment_definitions.dup
end
self.attachment_definitions = self.attachment_definitions&.dup || {}
attachment_definitions[name] = {:validations => []}.merge(options)
after_save :save_attached_files
@@ -258,16 +252,13 @@ module Paperclip
# * +if+: A lambda or name of a method on the instance. Validation will only
# be run is this lambda or method returns true.
# * +unless+: Same as +if+ but validates if lambda or method returns false.
def validates_attachment_size name, options = {}
def validates_attachment_size(name, **options)
min = options[:greater_than] || (options[:in] && options[:in].first) || 0
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
range = (min..max)
message = options[:message] || "file size must be between :min and :max bytes."
attachment_definitions[name][:validations] << [:size, {:range => range,
:message => message,
:if => options[:if],
:unless => options[:unless]}]
_add_attachment_validation(name, :size, options,
message: "file size must be between :min and :max bytes.",
range: (min..max)
)
end
# Places ActiveRecord-style validations on the presence of a file.
@@ -275,12 +266,8 @@ module Paperclip
# * +if+: A lambda or name of a method on the instance. Validation will only
# be run is this lambda or method returns true.
# * +unless+: Same as +if+ but validates if lambda or method returns false.
def validates_attachment_presence name, options = {}
message = options[:message] || :blank
attachment_definitions[name][:validations] << [:presence, {:message => message,
:if => options[:if],
:unless => options[:unless]}]
def validates_attachment_presence(name, **options)
_add_attachment_validation(name, :presence, options, message: :blank)
end
# Places ActiveRecord-style validations on the content type of the file
@@ -299,15 +286,16 @@ module Paperclip
# NOTE: If you do not specify an [attachment]_content_type field on your
# model, content_type validation will work _ONLY upon assignment_ and
# re-validation after the instance has been reloaded will always succeed.
def validates_attachment_content_type name, options = {}
attachment_definitions[name][:validations] << [:content_type, {:content_type => options[:content_type],
:message => options[:message],
:if => options[:if],
:unless => options[:unless]}]
def validates_attachment_content_type(name, content_type:, **options)
_add_attachment_validation(name, :content_type, options, content_type: content_type)
end
def attachment_definitions
self.attachment_definitions
def _add_attachment_validation(name, type, default_options, options)
attachment_definitions[name][:validations] << [
type,
**options,
**default_options.slice(:message, :if, :unless)
]
end
end

View File

@@ -1,5 +1,7 @@
require 'fastimage'
require 'paperclip/styles_parser'
module Paperclip
# The Attachment class manages the files for a given attachment. It saves
# when the model saves, deletes when the model is destroyed, and processes
@@ -14,13 +16,11 @@ module Paperclip
@default_options ||= {
:url => "/system/:attachment/:id/:style/:filename",
:path => ":rails_root/public:url",
:style_order => [],
:styles => {},
:default_url => "/:attachment/:style/missing.png",
:default_style => :original,
:validations => [],
:storage => :filesystem,
# :whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails],
:whiny => true,
:restricted_characters => /[^\w\p{Word}\d\.\-]|(^\.{0,2}$)+/,
:filename_sanitizer => nil
@@ -48,8 +48,7 @@ module Paperclip
attachment_class_cache[storage].new(name, instance, options)
end
attr_reader :name, :instance, :style_order, :styles, :default_style,
:convert_options, :queued_for_write, :options
attr_reader :name, :instance, :styles, :default_style, :queued_for_write, :options
attr_accessor :post_processing
@@ -63,20 +62,13 @@ module Paperclip
options = Attachment.default_options.merge(options)
@url = options[:url]
@url = @url.call(self) if @url.is_a?(Proc)
@path = options[:path]
@path = @path.call(self) if @path.is_a?(Proc)
@style_order = options[:style_order]
@style_order = @style_order.call(self) if @style_order.is_a?(Proc)
@styles = options[:styles]
@styles = @styles.call(self) if @styles.is_a?(Proc)
@styles = StylesParser.new(options).styles
@default_url = options[:default_url]
@validations = options[:validations]
@default_style = options[:default_style]
@storage = options[:storage]
@whiny = options[:whiny_thumbnails] || options[:whiny]
@convert_options = options[:convert_options] || {}
@processors = options[:processors] || [:thumbnail]
@options = options
@queued_for_delete = []
@queued_for_write = {}
@@ -86,8 +78,6 @@ module Paperclip
@post_processing = true
@processing_url = options[:processing_url] || @default_url
normalize_style_definition
end
# What gets called when you call instance.attachment = File. It clears
@@ -159,10 +149,6 @@ module Paperclip
!sizes || (sizes[0] <= MAX_IMAGE_RESOLUTION && sizes[1] <= MAX_IMAGE_RESOLUTION)
end
def most_appropriate_url
# stub for delayed_paperclip
end
# Returns the public URL of the attachment, with a given style. Note that
# this does not necessarily need to point to a file that your web server
# can access and can point to an action in your app, if you need fine
@@ -274,18 +260,6 @@ module Paperclip
time && time.to_i
end
# Paths and URLs can have a number of variables interpolated into them
# to vary the storage location based on name, id, style, class, etc.
# This method is a deprecated access into supplying and retrieving these
# interpolations. Future access should use either Paperclip.interpolates
# or extend the Paperclip::Interpolations module directly.
def self.interpolations
warn('[DEPRECATION] Paperclip::Attachment.interpolations is deprecated ' +
'and will be removed from future versions. ' +
'Use Paperclip.interpolates instead')
Paperclip::Interpolations
end
def sanitize_filename(file_name)
file_name = file_name.strip
file_name.gsub!(@options[:restricted_characters], '_') if @options[:restricted_characters]
@@ -415,48 +389,9 @@ module Paperclip
end
end
def normalize_style_definition #:nodoc:
styles.each do |name, args|
unless args.is_a? Hash
dimensions, format = [args, nil].flatten[0..1]
format = nil if format.blank?
@styles[name] = {
:processors => @processors,
:geometry => dimensions,
:format => format,
:whiny => @whiny,
:convert_options => extra_options_for(name)
}
else
@styles[name] = {
:processors => @processors,
:whiny => @whiny,
:convert_options => extra_options_for(name)
}.merge(@styles[name])
end
end
end
def solidify_style_definitions #:nodoc:
@styles.each do |name, args|
@styles[name][:geometry] = @styles[name][:geometry].call(instance) if @styles[name][:geometry].respond_to?(:call)
@styles[name][:processors] = @styles[name][:processors].call(instance) if @styles[name][:processors].respond_to?(:call)
end
end
def extra_options_for(style) #:nodoc:
all_options = convert_options[:all]
all_options = all_options.call(instance) if all_options.respond_to?(:call)
style_options = convert_options[style]
style_options = style_options.call(instance) if style_options.respond_to?(:call)
[ style_options, all_options ].compact.join(" ")
end
def post_process #:nodoc:
return unless content_type.match(/image/)
return if @queued_for_write[:original].nil?
solidify_style_definitions
instance.run_paperclip_callbacks(:post_process) do
instance.run_paperclip_callbacks(:"#{name}_post_process") do
@@ -466,8 +401,7 @@ module Paperclip
end
def post_process_styles #:nodoc:
styles_in_order = @style_order.empty? ? @styles : @styles.sort_by{|s| @style_order.index(s.first)}
styles_in_order.each do |name, args|
styles.each do |name, args|
begin
raise RuntimeError.new("Style #{name} has no processors defined.") if args[:processors].blank?
@queued_for_write[name] = args[:processors].inject(@queued_for_write[:original]) do |file, processor|

View File

@@ -1,11 +1,14 @@
module Paperclip
module CallbackCompatability
module Rails21
def self.included(base)
base.extend(Defining)
base.send(:include, Running)
end
module_function
def install_to(base)
mod = base.respond_to?(:set_callback) ? Rails3 : Rails21
base.extend(mod::Defining)
base.send(:include, mod::Running)
end
module Rails21
module Defining
def define_paperclip_callbacks(*args)
args.each do |callback|
@@ -28,29 +31,24 @@ module Paperclip
end
module Rails3
def self.included(base)
base.extend(Defining)
base.send(:include, Running)
end
module Defining
TERMINATOR =
if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('4.1')
->(target, result) { result == false }
else
'result == false'
end
def define_paperclip_callbacks(*callbacks)
terminator =
if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('4.1')
->(target, result) { result == false }
else
'result == false'
define_callbacks *[callbacks, {terminator: TERMINATOR}].flatten
callbacks.map(&:to_sym).each do |callback|
define_singleton_method "before_#{callback}" do |*args, &blk|
set_callback(callback, :before, *args, &blk)
end
define_singleton_method "after_#{callback}" do |*args, &blk|
set_callback(callback, :after, *args, &blk)
end
define_callbacks *[callbacks, {terminator: terminator}].flatten
callbacks.each do |callback|
eval <<-end_callbacks
def before_#{callback}(*args, &blk)
set_callback(:#{callback}, :before, *args, &blk)
end
def after_#{callback}(*args, &blk)
set_callback(:#{callback}, :after, *args, &blk)
end
end_callbacks
end
end
end
@@ -60,9 +58,7 @@ module Paperclip
run_callbacks(callback, &block)
end
end
end
end
end

View File

@@ -14,9 +14,8 @@ module Paperclip
end
def parse_credentials creds
return @parsed_credentials if @parsed_credentials
creds = find_credentials(creds).stringify_keys
@parsed_credentials ||= (creds[Rails.env] || creds).symbolize_keys
(creds[Rails.env] || creds).symbolize_keys
end
def find_credentials creds
@@ -33,12 +32,6 @@ module Paperclip
end
end
class WriteToS3Job < Struct.new(:class_name, :name, :id)
def perform
WriteToS3Worker.new.perform(class_name, name, id)
end
end
class UploadWorker
include ::Sidekiq::Worker
sidekiq_options queue: :paperclip
@@ -81,10 +74,6 @@ module Paperclip
@s3_credentials = Delayeds3.parse_credentials(@options[:s3_credentials])
@bucket = @options[:bucket] || @s3_credentials[:bucket]
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
@s3_permissions = @options[:s3_permissions] || 'public-read'
@s3_protocol = @options[:s3_protocol] || (@s3_permissions == 'public-read' ? 'http' : 'https')
@s3_host_alias = @options[:s3_host_alias]
@fog_provider = @options[:fog_provider]
@fog_directory = @options[:fog_directory]
@@ -141,10 +130,6 @@ module Paperclip
@bucket
end
def s3_host_alias
@s3_host_alias
end
def synced_to_s3_field
@synced_to_s3_field ||= "#{name}_synced_to_s3".freeze
end
@@ -166,10 +151,6 @@ module Paperclip
alias_method :to_io, :to_file
def s3_protocol
@s3_protocol
end
def exists?(style = default_style)
File.exist?(filesystem_path(style))
end
@@ -181,7 +162,8 @@ module Paperclip
def filesystem_paths
h = {}
[:original, *@styles.keys].uniq.map do |style|
h[style] = filesystem_path(style) if File.exist?(filesystem_path(style))
path = filesystem_path(style)
h[style] = path if File.exist?(path)
end
h
end
@@ -237,8 +219,9 @@ module Paperclip
end
end
def flush_writes #:nodoc:
return if @queued_for_write.empty?
@queued_for_write.each do |style, file|
file.close
FileUtils.mkdir_p(File.dirname(filesystem_path(style)))
@@ -247,7 +230,7 @@ module Paperclip
FileUtils.chmod(0644, filesystem_path(style))
end
unless @queued_for_write.empty? || (delay_processing? && dirty?)
unless delay_processing? && dirty?
instance.update_column(synced_to_s3_field, false) if instance_read(:synced_to_s3)
if instance.respond_to?(synced_to_fog_field) && instance_read(:synced_to_fog)
instance.update_column(synced_to_fog_field, false)
@@ -285,10 +268,9 @@ module Paperclip
def flush_deletes #:nodoc:
# если мы картинку заливали в облака, значит мы скорее всего ее уже удалили
# и можно не нагружать хранилище проверками
if !instance.is_a?(AccountFile) && instance_read(:synced_to_fog) &&
instance_read(:synced_to_s3)
@queued_for_delete = []
return
if instance_read(:synced_to_fog) && instance_read(:synced_to_s3)
@queued_for_delete = []
return
end
@queued_for_delete.each do |path|
@@ -299,7 +281,6 @@ module Paperclip
end
def delete_local_files!
return if instance.is_a?(AccountFile)
instance.reload
if instance_read(:synced_to_fog) && instance_read(:synced_to_s3)
filesystem_paths.values.each do |filename|

View File

@@ -34,10 +34,11 @@ module Paperclip
def flush_writes #:nodoc:
@queued_for_write.each do |style, file|
file.close
FileUtils.mkdir_p(File.dirname(path(style)))
log("saving #{path(style)}")
FileUtils.mv(file.path, path(style))
FileUtils.chmod(0644, path(style))
filename = path(style)
FileUtils.mkdir_p(File.dirname(filename))
log("saving #{filename}")
FileUtils.mv(file.path, filename)
FileUtils.chmod(0644, filename)
end
@queued_for_write = {}
end

View File

@@ -0,0 +1,42 @@
module Paperclip
class StylesParser
attr_reader :styles, :convert_options, :processors, :whiny
def initialize(options)
@styles = options[:styles]
@convert_options = options[:convert_options] || {}
@processors = options[:processors] || [:thumbnail]
@whiny = options[:whiny_thumbnails] || options[:whiny]
normalize_style_definition
end
def normalize_style_definition #:nodoc:
styles.each do |name, args|
styles[name] =
if args.is_a? Hash
{
processors: processors,
whiny: whiny,
convert_options: extra_options_for(name)
}.merge(args)
else
dimensions, format = args
{
processors: processors,
geometry: dimensions,
format: format.presence,
whiny: whiny,
convert_options: extra_options_for(name)
}
end
end
end
def extra_options_for(style) #:nodoc:
all_options = convert_options[:all]
style_options = convert_options[style]
[style_options, all_options].compact.join(' ')
end
end
end

View File

@@ -17,5 +17,6 @@ Gem::Specification.new do |s|
s.rubygems_version = %q{1.3.1}
s.summary = %q{File attachments as attributes for ActiveRecord}
s.add_dependency 'activesupport'
s.add_dependency 'fastimage'
end