picture_handler 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +32 -0
- data/lib/picture_handler/configuration.rb +11 -0
- data/lib/picture_handler/exceptions.rb +61 -0
- data/lib/picture_handler/mounter.rb +124 -0
- data/lib/picture_handler/uploader/base.rb +162 -0
- data/lib/picture_handler/uploader/file_system/file.rb +52 -0
- data/lib/picture_handler/uploader/file_system/s3.rb +39 -0
- data/lib/picture_handler/uploader/img_version.rb +78 -0
- data/lib/picture_handler/uploader/mini_magick.rb +51 -0
- data/lib/picture_handler/version.rb +3 -0
- data/lib/picture_handler.rb +31 -0
- metadata +125 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'PictureHandler'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Exceptions
|
3
|
+
|
4
|
+
class CustomMessage < StandardError
|
5
|
+
alias :orig_to_s :to_s
|
6
|
+
def to_s
|
7
|
+
@data
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
@data
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class CustomError < CustomMessage
|
17
|
+
def initialize(error_description)
|
18
|
+
@data = "#{error_description}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class VersionError < CustomMessage
|
23
|
+
def initialize(version_name)
|
24
|
+
@data = "The Version: \"#{version_name}\" is use as a FROM but doesn't exist."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class InitError < CustomMessage
|
29
|
+
def initialize(uploader_name)
|
30
|
+
@data = "The Uploader: \"#{uploader_name}\" have not been initialized."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class WrongArgument < CustomMessage
|
35
|
+
def initialize(method)
|
36
|
+
@data = "The argument(s) you provided for the method: \"#{method}\" are incomplete or wrong."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class NoMethodError < CustomMessage
|
41
|
+
def initialize(method)
|
42
|
+
@data = "The minimagick method: \"#{method}\" is not a minimagick supported method."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class OpenError < CustomMessage
|
47
|
+
def initialize(source)
|
48
|
+
@data = "The image at source: \"#{source}\" could not be open."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class WriteError < CustomMessage
|
53
|
+
def initialize(path)
|
54
|
+
@data = "The image could not be write at \"#{path}\" path."
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
|
3
|
+
module Mounter
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
|
7
|
+
base.extend ClassMethods
|
8
|
+
base.class_eval do
|
9
|
+
cattr_accessor :column
|
10
|
+
cattr_reader :uploaders
|
11
|
+
|
12
|
+
attr_accessor :remote_path
|
13
|
+
attr_reader :model_filename, :uploader, :old_record, :populated
|
14
|
+
end
|
15
|
+
base.class_variable_set('@@uploaders', {})
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
# Choose the field to action the image with
|
23
|
+
def storage_field(column, picture_handler)
|
24
|
+
|
25
|
+
before_save :picture_store
|
26
|
+
before_destroy :picture_delete
|
27
|
+
|
28
|
+
# Save the COLUMN !
|
29
|
+
self.column = column
|
30
|
+
|
31
|
+
# Put this uploader in the uploader list
|
32
|
+
self.uploaders[column] = picture_handler
|
33
|
+
|
34
|
+
# Inside this class_eval, we are in the instance so you can access Model.picture
|
35
|
+
class_eval <<-RUBY
|
36
|
+
|
37
|
+
# Overwrite the field 'storage field' so you can return a formated object instead
|
38
|
+
def #{column}
|
39
|
+
get_object_or_string(self[__method__.to_sym], __method__)
|
40
|
+
end
|
41
|
+
|
42
|
+
RUBY
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end # ClassMethod
|
47
|
+
|
48
|
+
private # -------- #
|
49
|
+
|
50
|
+
# Every time model.picture is called
|
51
|
+
def get_object_or_string(attribute, column)
|
52
|
+
|
53
|
+
build_picture_handler_object(attribute, column) if !@uploader
|
54
|
+
@uploader
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# CREATE an instance of PictureUploader::Base if the Object has not been created yet
|
59
|
+
def build_picture_handler_object(attribute, column)
|
60
|
+
|
61
|
+
@populated = false
|
62
|
+
@column = self.class.column.to_s
|
63
|
+
attribute = self.class.uploaders[column].new(self)
|
64
|
+
@uploader = attribute
|
65
|
+
@model_filename = ""
|
66
|
+
|
67
|
+
@old_record = !self.id.blank?
|
68
|
+
# If the record already exist, populate the name
|
69
|
+
if @old_record
|
70
|
+
# Active Record, write as attribute for Model.#{column}
|
71
|
+
@model_filename = read_attribute(@column)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def register_active_record_attribute
|
78
|
+
|
79
|
+
# If there is no image, it means it is an old record that haven't changed yet (not populated yet)
|
80
|
+
raise PictureHandler::Exceptions::CustomError.new(
|
81
|
+
"Trying to save ActiveRecord attribute, but there is no image populated yet.") if !@populated || @uploader.image.nil?
|
82
|
+
|
83
|
+
# This return either the filename chosen by the dev or the default filename of PictureUploader::Base class method filename
|
84
|
+
@model_filename = @uploader.real_filename + "." + @uploader.image.type.downcase
|
85
|
+
|
86
|
+
# Active Record, write as attribute for Model.#{column}
|
87
|
+
write_attribute(@column, @model_filename)
|
88
|
+
@model_filename
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# Trigger when ActiveRecord Model.destroy
|
93
|
+
def picture_delete
|
94
|
+
|
95
|
+
# Call Model.column field
|
96
|
+
column = self.class.column.to_s
|
97
|
+
self.send(column) if @uploader.nil?
|
98
|
+
|
99
|
+
@uploader.delete_all
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# Trigger when ActiveRecord Model.save
|
104
|
+
def picture_store
|
105
|
+
|
106
|
+
# Call Model.column field
|
107
|
+
column = self.class.column.to_s
|
108
|
+
self.send(column) if @uploader.nil?
|
109
|
+
|
110
|
+
# If we are in an already existing record a no remote_path have been given prior to save
|
111
|
+
return if @old_record && self.remote_path.blank?
|
112
|
+
|
113
|
+
# STORE IT
|
114
|
+
@uploader.store
|
115
|
+
@populated = true
|
116
|
+
|
117
|
+
# Ask for a write inside the ActiveRecord Attribute field
|
118
|
+
register_active_record_attribute
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Uploader
|
3
|
+
|
4
|
+
class Base
|
5
|
+
|
6
|
+
include PictureHandler::Uploader::MiniMagick
|
7
|
+
include PictureHandler::Uploader::ImgVersion
|
8
|
+
include ('PictureHandler::Uploader::FileSystem::' + PictureHandler.configuration.file_sys.to_s.camelize).constantize
|
9
|
+
|
10
|
+
attr_accessor :image, :model, :versions
|
11
|
+
attr_reader :real_filename
|
12
|
+
|
13
|
+
def initialize(model=nil)
|
14
|
+
# Set once
|
15
|
+
@image = nil
|
16
|
+
@model = model
|
17
|
+
@versions = {}
|
18
|
+
register_versions
|
19
|
+
|
20
|
+
# Changing runtime
|
21
|
+
@current_version = nil
|
22
|
+
@info_built = false
|
23
|
+
@infos = {}
|
24
|
+
@real_filename
|
25
|
+
end
|
26
|
+
|
27
|
+
def filename
|
28
|
+
"unamed"
|
29
|
+
end
|
30
|
+
|
31
|
+
def store_dir
|
32
|
+
"public/ph_pictures/"
|
33
|
+
end
|
34
|
+
|
35
|
+
def remote_path
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def register_versions
|
40
|
+
# Create different versions of your uploaded files:
|
41
|
+
version :thumbnail do
|
42
|
+
process resize_to_fill: [200, 200], quality: 80
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# ----------------------------- #
|
47
|
+
# ------ Public Method -------- #
|
48
|
+
# ----------------------------- #
|
49
|
+
|
50
|
+
def info
|
51
|
+
build_infos unless @info_built
|
52
|
+
@infos
|
53
|
+
end
|
54
|
+
|
55
|
+
# When a Model.save is done
|
56
|
+
def store
|
57
|
+
|
58
|
+
# Get the filename once and will use the same for all futur save
|
59
|
+
@real_filename = filename
|
60
|
+
# Is the model new ? delete old record if true
|
61
|
+
delete_all if @model.old_record
|
62
|
+
|
63
|
+
process_original_image
|
64
|
+
apply_versions
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete_all
|
69
|
+
delete_all_with_file_system
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# -------------------------- #
|
75
|
+
# ------ INFOS ------ #
|
76
|
+
# -------------------------- #
|
77
|
+
|
78
|
+
# At creation or called once before .info ?
|
79
|
+
def build_infos
|
80
|
+
model_filename = @model.model_filename
|
81
|
+
infos = @infos
|
82
|
+
|
83
|
+
infos[:filename] = model_filename
|
84
|
+
infos[:position] = model_filename.split('_').first.to_i
|
85
|
+
infos[:store_dir] = store_dir
|
86
|
+
infos[:original_path] = store_dir + model_filename
|
87
|
+
infos[:versions] = []
|
88
|
+
infos[:paths] = []
|
89
|
+
infos[:paths] << { key: infos[:original_path] }
|
90
|
+
# Get infos for each version
|
91
|
+
@versions.each_key do |version|
|
92
|
+
infos[:versions] << version
|
93
|
+
version_path = store_dir + version.to_s + '_' + model_filename
|
94
|
+
infos[:paths] << { key: version_path }
|
95
|
+
infos[version] = version_path
|
96
|
+
end
|
97
|
+
|
98
|
+
@info_built = true
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# -------------------------- #
|
103
|
+
# ------ CREATE ------ #
|
104
|
+
# -------------------------- #
|
105
|
+
|
106
|
+
|
107
|
+
def process_original_image
|
108
|
+
|
109
|
+
# Call the "SpecialUploader" remote_path method or the Uploader::Base one as default
|
110
|
+
source_path = remote_path
|
111
|
+
@image = self.class.open_source(source_path)
|
112
|
+
|
113
|
+
path_to_original = store_dir + @real_filename + "." + @image.type.downcase
|
114
|
+
write_file(@image, path_to_original)
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
def apply_versions
|
119
|
+
|
120
|
+
# Get the different wanted versions
|
121
|
+
@versions.each do |key, value|
|
122
|
+
@current_version = key
|
123
|
+
create_image_and_process( &(value[:block]) )
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# Create a new image for each versions or inherit it from the "from" if specified
|
129
|
+
def create_image_and_process
|
130
|
+
|
131
|
+
# Get if there is a from_version for this version
|
132
|
+
from = @versions[@current_version][:from_version]
|
133
|
+
|
134
|
+
# create a new image from original OR from another to be used for this version
|
135
|
+
if from
|
136
|
+
raise PictureHandler::Exceptions::VersionError.new(from) if @versions[from].blank? || @versions[from][:image].blank?
|
137
|
+
# Put the version_image to our version also so both reference the same one
|
138
|
+
image = @versions[from][:image]
|
139
|
+
@versions[@current_version].merge!( {image: image} )
|
140
|
+
|
141
|
+
else # Else create a new instance for this version
|
142
|
+
# Open a new image from the local tmp location
|
143
|
+
local_path = @image.path
|
144
|
+
image = self.class.open_source(local_path)
|
145
|
+
# Add the Image to this @versions[:version_name][:image]
|
146
|
+
@versions[@current_version].merge!( {image: image} )
|
147
|
+
end
|
148
|
+
|
149
|
+
# Apply the options through the 'process' method
|
150
|
+
yield if block_given?
|
151
|
+
|
152
|
+
# Save the current version
|
153
|
+
version_path = store_dir + @current_version.to_s + "_" + @real_filename + "." + image.type.downcase
|
154
|
+
# Write this file new version
|
155
|
+
write_file(image, version_path)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Uploader
|
3
|
+
module FileSystem
|
4
|
+
module File
|
5
|
+
|
6
|
+
# -------------------------- #
|
7
|
+
# ------ WRITE ------ #
|
8
|
+
# -------------------------- #
|
9
|
+
|
10
|
+
def write_file(image, path_to_write)
|
11
|
+
|
12
|
+
# Create path if it doesn't exist
|
13
|
+
self.class.create_directories_for_path( self.class.split_dirname_path(path_to_write) )
|
14
|
+
|
15
|
+
image.write(path_to_write)
|
16
|
+
|
17
|
+
# Raise an exception if the image is not written at the expected location
|
18
|
+
unless ::File.exist?(path_to_write)
|
19
|
+
raise PictureHandler::Exceptions::WriteError.new(path_to_write)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# -------------------------- #
|
24
|
+
# ------ DELETE ------ #
|
25
|
+
# -------------------------- #
|
26
|
+
|
27
|
+
def delete_all_with_file_system
|
28
|
+
|
29
|
+
infos = info
|
30
|
+
|
31
|
+
#Delete files and directory
|
32
|
+
infos[:paths].each { |hash| delete_from_path(hash[:key]) }
|
33
|
+
# Delete directory
|
34
|
+
Dir.rmdir(infos[:store_dir])
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def delete_from_path(path)
|
41
|
+
path = (Rails.root + path).to_s
|
42
|
+
if ::File.exist?(path)
|
43
|
+
::File.delete(path)
|
44
|
+
else
|
45
|
+
puts "ErrorDeletingFile: The file at path: '#{path}' could not be found."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Uploader
|
3
|
+
module FileSystem
|
4
|
+
module S3
|
5
|
+
|
6
|
+
require 'aws-sdk'
|
7
|
+
|
8
|
+
# -------------------------- #
|
9
|
+
# ------ WRITE ------ #
|
10
|
+
# -------------------------- #
|
11
|
+
|
12
|
+
def write_file(image, path_to_write)
|
13
|
+
|
14
|
+
s3_client = Aws::S3::Client.new
|
15
|
+
s3_resource = Aws::S3::Resource.new( client: s3_client )
|
16
|
+
|
17
|
+
s3_resource.bucket(PictureHandler.configuration.s3_bucket).object(path_to_write).upload_file(image.path)
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# -------------------------- #
|
22
|
+
# ------ DELETE ------ #
|
23
|
+
# -------------------------- #
|
24
|
+
|
25
|
+
def delete_all_with_file_system
|
26
|
+
|
27
|
+
infos = info
|
28
|
+
s3_client = Aws::S3::Client.new
|
29
|
+
|
30
|
+
# Get all the objects to delete and delete then in ONE http request
|
31
|
+
paths_to_delete = infos[:paths]
|
32
|
+
s3_client.delete_objects( bucket: PictureHandler.configuration.s3_bucket, delete: { objects: paths_to_delete } )
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Uploader
|
3
|
+
module ImgVersion
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def version(sym, options={}, &block)
|
7
|
+
# If the version already exist, the new one will overwrite the old one
|
8
|
+
p "You already have a version named \"#{sym.to_s}\". Old one is being replaced" if @versions[sym] && @versions[sym][:block]
|
9
|
+
|
10
|
+
# Fill the versions[:version_name][:block] with the block to be executed later
|
11
|
+
@versions[sym] = { block: block } if block_given?
|
12
|
+
|
13
|
+
# Fill the versions[:version_name][:from_version] with the symbol of the version from witch it should inherit
|
14
|
+
@versions[sym].merge!( {from_version: options[:from_version]} )
|
15
|
+
end
|
16
|
+
|
17
|
+
# The process is the function called inside the versions declared by the user
|
18
|
+
def process(args)
|
19
|
+
image = @versions[@current_version][:image]
|
20
|
+
|
21
|
+
args.each do |key, value|
|
22
|
+
case key
|
23
|
+
when :resize_to_fill
|
24
|
+
self.class.resize_to_fill(image, value)
|
25
|
+
when :quality
|
26
|
+
self.class.quality(image, value)
|
27
|
+
# when :rounded
|
28
|
+
# self.class.rounded(image, value)
|
29
|
+
else
|
30
|
+
raise PictureHandler::Exceptions::NoMethodError.new(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
|
37
|
+
# -------------------------------------------------------------- #
|
38
|
+
# ------------- Method accepted into a version ---------------- #
|
39
|
+
# -------------------------------------------------------------- #
|
40
|
+
|
41
|
+
def resize_to_fill(image, value)
|
42
|
+
width = value.first
|
43
|
+
height = value.last
|
44
|
+
gravity = 'Center'
|
45
|
+
raise PictureHandler::Exceptions::WrongArgument.new(key),
|
46
|
+
"You need to specify a width and height as argument of 'resize_to_fill' method." if width.blank? || height.blank?
|
47
|
+
|
48
|
+
cols, rows = image[:dimensions]
|
49
|
+
image.combine_options do |cmd|
|
50
|
+
if width != cols || height != rows
|
51
|
+
scale_x = width/cols.to_f
|
52
|
+
scale_y = height/rows.to_f
|
53
|
+
if scale_x >= scale_y
|
54
|
+
cols = (scale_x * (cols + 0.5)).round
|
55
|
+
rows = (scale_x * (rows + 0.5)).round
|
56
|
+
cmd.resize "#{cols}"
|
57
|
+
else
|
58
|
+
cols = (scale_y * (cols + 0.5)).round
|
59
|
+
rows = (scale_y * (rows + 0.5)).round
|
60
|
+
cmd.resize "x#{rows}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
cmd.gravity gravity
|
64
|
+
cmd.background "rgba(255,255,255,0.0)"
|
65
|
+
cmd.extent "#{width}x#{height}" if cols != width || rows != height
|
66
|
+
end
|
67
|
+
# image = yield(image) if block_given?
|
68
|
+
end
|
69
|
+
|
70
|
+
def quality(image, value)
|
71
|
+
image.quality(value)
|
72
|
+
end
|
73
|
+
|
74
|
+
end # ClassMethod
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module PictureHandler
|
2
|
+
module Uploader
|
3
|
+
module MiniMagick
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
base.class_eval do
|
9
|
+
begin
|
10
|
+
require "mini_magick"
|
11
|
+
rescue LoadError => e
|
12
|
+
e.message << " (You may need to install the mini_magick gem)"
|
13
|
+
raise e
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Common method for all file_system
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
# Open the source File/path/ or URL, raise an error if blank
|
22
|
+
def open_source(source_path)
|
23
|
+
raise PictureHandler::Exceptions::OpenError.new("nil") if source_path.blank?
|
24
|
+
|
25
|
+
image = ::MiniMagick::Image.open(source_path)
|
26
|
+
if image.blank?
|
27
|
+
raise PictureHandler::Exceptions::OpenError.new(source_path)
|
28
|
+
end
|
29
|
+
image
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_directories_for_path(dir_tokens)
|
33
|
+
1.upto(dir_tokens.size) do |n|
|
34
|
+
dir = dir_tokens[0...n]
|
35
|
+
dir_str = dir.join("/")
|
36
|
+
Dir.mkdir(dir_str) unless Dir.exist?(dir_str)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Works for Windows C:\Files\etc or Linux /usr/app/etc
|
41
|
+
def split_dirname_path(some_path)
|
42
|
+
dirname = File.dirname(some_path)
|
43
|
+
tokens = dirname.split(/[\/\\]/)
|
44
|
+
tokens
|
45
|
+
end
|
46
|
+
|
47
|
+
end # ClassMethods
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'picture_handler/version'
|
2
|
+
|
3
|
+
module PictureHandler
|
4
|
+
autoload :Exceptions, 'picture_handler/exceptions'
|
5
|
+
autoload :Configuration, 'picture_handler/configuration'
|
6
|
+
autoload :Mounter, 'picture_handler/mounter'
|
7
|
+
module Uploader
|
8
|
+
autoload :Base, 'picture_handler/uploader/base'
|
9
|
+
autoload :MiniMagick, 'picture_handler/uploader/mini_magick'
|
10
|
+
autoload :ImgVersion, 'picture_handler/uploader/img_version'
|
11
|
+
module FileSystem
|
12
|
+
autoload :File, 'picture_handler/uploader/file_system/file'
|
13
|
+
autoload :S3, 'picture_handler/uploader/file_system/s3'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
|
19
|
+
attr_writer :configuration
|
20
|
+
|
21
|
+
def configuration
|
22
|
+
@configuration ||= Configuration.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure
|
26
|
+
yield configuration
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: picture_handler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Flavien Hello
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mini_magick
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: aws-sdk
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: This module will push it to a S3 bucket, crop, resize and keep track
|
79
|
+
of all the different version available for a single image.
|
80
|
+
email:
|
81
|
+
- flavien@prettyfuntherapy.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- lib/picture_handler/configuration.rb
|
87
|
+
- lib/picture_handler/exceptions.rb
|
88
|
+
- lib/picture_handler/mounter.rb
|
89
|
+
- lib/picture_handler/uploader/base.rb
|
90
|
+
- lib/picture_handler/uploader/file_system/file.rb
|
91
|
+
- lib/picture_handler/uploader/file_system/s3.rb
|
92
|
+
- lib/picture_handler/uploader/img_version.rb
|
93
|
+
- lib/picture_handler/uploader/mini_magick.rb
|
94
|
+
- lib/picture_handler/version.rb
|
95
|
+
- lib/picture_handler.rb
|
96
|
+
- MIT-LICENSE
|
97
|
+
- Rakefile
|
98
|
+
- README.rdoc
|
99
|
+
homepage: http://prettyfuntherapy.com
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.8.23
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Handle the upload and retrieving of your pictures for you.
|
124
|
+
test_files: []
|
125
|
+
has_rdoc:
|