photofy 0.1.9 → 0.2.0
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.
- checksums.yaml +4 -4
- data/lib/photofy.rb +5 -175
- data/lib/photofy/core.rb +248 -0
- data/lib/photofy/s3methods.rb +85 -0
- metadata +44 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14eee2b1ea2cb277ec084051f1b81e2d321331f2
|
4
|
+
data.tar.gz: 5bc86c40171e5064e21b9a38bca3bfa1d82411b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c274d763143150232d4cd57c5d8c647ea2ffe2c5d4dd627cf511778b96febfb89ee614daf7a8a89a5933ee8b0e2d42869c93b663d41809c4a75ff9e3ee41f4f
|
7
|
+
data.tar.gz: 215ad048cdda3153926a926284241f9e2b111065b8106e8baaae1153da64a37b4d12071986ad9d7936fd1146ea42e70c74b49230853a9dfe74956c0db42d7f62
|
data/lib/photofy.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'photofy/s3methods'
|
2
|
+
require 'photofy/core'
|
3
|
+
require 'tempfile'
|
1
4
|
begin
|
2
5
|
require "RMagick"
|
3
6
|
rescue Exception => e
|
@@ -6,182 +9,9 @@ end
|
|
6
9
|
|
7
10
|
module Photofy
|
8
11
|
def self.included(base)
|
9
|
-
base.extend(
|
12
|
+
base.extend(S3Methods)
|
13
|
+
base.extend(Core)
|
10
14
|
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
attr_accessor :photofied_flag
|
14
|
-
attr_accessor :photo_fields
|
15
|
-
attr_accessor :photos_repository
|
16
|
-
attr_accessor :photo_formats
|
17
|
-
|
18
|
-
#Getter to check if model is enabled with file_folder
|
19
|
-
def is_photofied?
|
20
|
-
@photofied_flag.nil? ? false : @photofied_flag
|
21
|
-
end
|
22
|
-
|
23
|
-
#Generates photo field which can be used to store a post processed image(using rmagick) of parent photo field.
|
24
|
-
#Takes three arguments:
|
25
|
-
#1. parent photo field name
|
26
|
-
#2. field name
|
27
|
-
#3. Proc with rmagick img object
|
28
|
-
#return value should be an object of rmagick's image object
|
29
|
-
#
|
30
|
-
#Example usage..
|
31
|
-
#after_photofy :profile, :stamp, Proc.new{|img| img.scale(25, 25)}
|
32
|
-
#will give a 'stamp' attribute which on save of 'profile' photo field will scale it to 25 x 25 dimensions
|
33
|
-
#after_photofy :profile, :portfolio, Proc.new{|img| img.scale(150, 250)}
|
34
|
-
#will give a 'portfolio' attribute which on save of 'profile' photo field will scale it to 150 x 250 dimensions
|
35
|
-
def after_photofy(parent_photo_field, photo_field, proc = Proc.new { |img| puts "Rmagick image: #{img.inspect}" })
|
36
|
-
photofy(photo_field, image_processor: proc, parent_photo_field: parent_photo_field)
|
37
|
-
end
|
38
|
-
|
39
|
-
#Example
|
40
|
-
#photofy(:door)
|
41
|
-
#photofy(:small_door, {parent_photo_field: :door})
|
42
|
-
#photofy(:window, {image_processor: Proc.new { |img| img.scale(25, 25) }})
|
43
|
-
#after_photofy :door, :ventilator, Proc.new { |img| img.scale(25, 25) }
|
44
|
-
#
|
45
|
-
#Generates photo filed from photo_field arguments and provides methods like
|
46
|
-
#if photo_filed is "collage" then it provides methods on top of it as
|
47
|
-
#collage >> Getter,
|
48
|
-
#collage? >> Returns true if assignment is having value other than nil else false,
|
49
|
-
#collage = >> Setter. Acceptable inputs are file upload(ActionDispatch::Http::UploadedFile), filer handle and String(format validation is ignored),
|
50
|
-
#collage_path >> File path of assignment,
|
51
|
-
#collage_path_to_write >> File path of assignment to write (specific to writing. Used internally),
|
52
|
-
#collage_persisted? >> true if provided file/data is stored on disk,
|
53
|
-
#collage_store! >> to store provided file/data on disk,
|
54
|
-
#collage_destroy! >> to store destroy stored file/data from disk
|
55
|
-
#
|
56
|
-
#Options:
|
57
|
-
#image_processor: a proc for image processing like Proc.new { |img| img.scale(25, 25) }
|
58
|
-
#parent_photo_field: a parent photo field name to be used as source
|
59
|
-
def photofy(photo_field, options = {})
|
60
|
-
collect_photo_formats(photo_field, options)
|
61
|
-
|
62
|
-
@photo_fields ||=[]
|
63
|
-
@photo_fields << photo_field
|
64
|
-
|
65
|
-
define_method 'initialize_photo_buffers' do
|
66
|
-
@photo_file_buffer ||= {}
|
67
|
-
@photo_file_ofn ||= {}
|
68
|
-
end
|
69
|
-
|
70
|
-
#Defining getter
|
71
|
-
define_method "#{photo_field}" do
|
72
|
-
send('initialize_photo_buffers')
|
73
|
-
|
74
|
-
if @photo_file_buffer[photo_field].nil?
|
75
|
-
send("#{photo_field}_persisted?") ? File.read(send("#{photo_field}_path")) : nil
|
76
|
-
else
|
77
|
-
@photo_file_buffer[photo_field]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
define_method "#{photo_field}?" do
|
82
|
-
send("#{photo_field}").nil? ? false : true
|
83
|
-
end
|
84
|
-
|
85
|
-
#Defining setter
|
86
|
-
define_method "#{photo_field}=" do |file_upload|
|
87
|
-
send('initialize_photo_buffers')
|
88
|
-
|
89
|
-
if file_upload.class == ActionDispatch::Http::UploadedFile
|
90
|
-
return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload.original_filename).downcase)
|
91
|
-
@photo_file_buffer[photo_field] = File.read(file_upload.path)
|
92
|
-
@photo_file_ofn[photo_field] = File.basename(file_upload.original_filename)
|
93
|
-
|
94
|
-
elsif file_upload.class == File
|
95
|
-
return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload.path).downcase)
|
96
|
-
@photo_file_buffer[photo_field] = file_upload.read
|
97
|
-
@photo_file_ofn[photo_field] = File.basename(file_upload.path)
|
98
|
-
|
99
|
-
file_upload.rewind
|
100
|
-
elsif file_upload.class == String
|
101
|
-
#return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload).downcase)
|
102
|
-
@photo_file_buffer[photo_field] = file_upload
|
103
|
-
#@photo_file_ofn[photo_field] = File.basename(file_upload.path) #As there is nothing like original_file_name for a string :)
|
104
|
-
end
|
105
|
-
|
106
|
-
file_upload
|
107
|
-
end
|
108
|
-
|
109
|
-
define_method "#{photo_field}_path" do
|
110
|
-
directory_path = FileUtils.mkdir_p File.join(self.class.photos_repository, photo_field.to_s)
|
111
|
-
(guessed_file = Dir[File.join(directory_path, "#{self.send(self.class.primary_key).to_s}_*")].first).nil? ?
|
112
|
-
File.join(directory_path, self.send(self.class.primary_key).to_s) : guessed_file
|
113
|
-
end
|
114
|
-
|
115
|
-
define_method "#{photo_field}_path_to_write" do |overload_dir = nil|
|
116
|
-
directoy_path = FileUtils.mkdir_p File.join(self.class.photos_repository, photo_field.to_s, overload_dir.to_s)
|
117
|
-
File.join(directoy_path, "#{self.send(self.class.primary_key).to_s}#{(@photo_file_ofn[photo_field].nil?) ? "_" : "_#{@photo_file_ofn[photo_field]}" }")
|
118
|
-
end
|
119
|
-
|
120
|
-
define_method "#{photo_field}_persisted?" do
|
121
|
-
send('initialize_photo_buffers')
|
122
|
-
(@photo_file_buffer[photo_field].nil? and File.file?(send("#{photo_field}_path")))
|
123
|
-
end
|
124
|
-
|
125
|
-
define_method "#{photo_field}_store" do |proc, parent_photo_field|
|
126
|
-
return unless self.class.is_photofied?
|
127
|
-
|
128
|
-
send('initialize_photo_buffers')
|
129
|
-
|
130
|
-
#Loading content from parent_photo_field if specified
|
131
|
-
unless parent_photo_field.nil?
|
132
|
-
send("#{photo_field}=", File.open(send("#{parent_photo_field}_path"))) if File.exist?(send("#{parent_photo_field}_path"))
|
133
|
-
end
|
134
|
-
|
135
|
-
unless @photo_file_buffer[photo_field].nil?
|
136
|
-
File.delete(send("#{photo_field}_path")) if File.exist?(send("#{photo_field}_path")) #Clearing any existing existence
|
137
|
-
File.open(send("#{photo_field}_path_to_write"), "wb+") { |f| f.puts(@photo_file_buffer[photo_field]) }
|
138
|
-
|
139
|
-
unless proc.nil?
|
140
|
-
FileUtils.copy(send("#{photo_field}_path_to_write"), send("#{photo_field}_path_to_write", "original_source"))
|
141
|
-
img = Magick::Image.read(send("#{photo_field}_path")).first
|
142
|
-
img = proc.call(img)
|
143
|
-
img.write(send("#{photo_field}_path_to_write"))
|
144
|
-
end
|
145
|
-
|
146
|
-
@photo_file_buffer[photo_field] = nil
|
147
|
-
@photo_file_ofn[photo_field] = nil
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
define_method "#{photo_field}_store!" do
|
152
|
-
send("#{photo_field}_store", options[:image_processor], options[:parent_photo_field])
|
153
|
-
end
|
154
|
-
|
155
|
-
define_method "#{photo_field}_destroy!" do
|
156
|
-
return unless self.class.is_photofied?
|
157
|
-
|
158
|
-
send('initialize_photo_buffers')
|
159
|
-
@photo_file_buffer[photo_field] = nil
|
160
|
-
File.delete(send("#{photo_field}_path")) if File.exist?(send("#{photo_field}_path"))
|
161
|
-
end
|
162
|
-
|
163
|
-
send(:after_save, "#{photo_field}_store!")
|
164
|
-
send(:after_destroy, "#{photo_field}_destroy!")
|
165
|
-
|
166
|
-
@photofied_flag = true
|
167
|
-
end
|
168
|
-
|
169
|
-
def photos_repository
|
170
|
-
@photos_repository ||= FileUtils.mkdir_p File.join(Rails.root, "photofy", self.name)
|
171
|
-
end
|
172
|
-
|
173
|
-
#Collects valid photo formats specific to photo fields
|
174
|
-
def collect_photo_formats(photo_field, options)
|
175
|
-
if options.is_a?(Hash)
|
176
|
-
@photo_formats ||= {}
|
177
|
-
@photo_formats[photo_field] = options[:formats].is_a?(Array) ? options[:formats].collect { |x| x.starts_with?(".") ? x : ".#{x}" } : [".jpeg", ".jpg", ".gif", ".png", ".bmp"]
|
178
|
-
else
|
179
|
-
raise 'InvalidArguments'
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
end
|
184
|
-
|
185
15
|
end
|
186
16
|
|
187
17
|
ActiveRecord::Base.send(:include, Photofy)
|
data/lib/photofy/core.rb
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
module Photofy
|
2
|
+
module Core
|
3
|
+
attr_accessor :photofied_flag
|
4
|
+
attr_accessor :photo_fields
|
5
|
+
attr_accessor :photos_repository
|
6
|
+
attr_accessor :photo_formats
|
7
|
+
|
8
|
+
#Getter to check if model is enabled with file_folder
|
9
|
+
def is_photofied?
|
10
|
+
@photofied_flag.nil? ? false : @photofied_flag
|
11
|
+
end
|
12
|
+
|
13
|
+
#Generates photo field which can be used to store a post processed image(using rmagick) of parent photo field.
|
14
|
+
#Takes three arguments:
|
15
|
+
#1. parent photo field name
|
16
|
+
#2. field name
|
17
|
+
#3. Proc with rmagick img object
|
18
|
+
#return value should be an object of rmagick's image object
|
19
|
+
#
|
20
|
+
#Example usage..
|
21
|
+
#after_photofy :profile, :stamp, Proc.new{|img| img.scale(25, 25)}
|
22
|
+
#will give a 'stamp' attribute which on save of 'profile' photo field will scale it to 25 x 25 dimensions
|
23
|
+
#after_photofy :profile, :portfolio, Proc.new{|img| img.scale(150, 250)}
|
24
|
+
#will give a 'portfolio' attribute which on save of 'profile' photo field will scale it to 150 x 250 dimensions
|
25
|
+
def after_photofy(parent_photo_field, photo_field, proc = Proc.new { |img| puts "Rmagick image: #{img.inspect}" })
|
26
|
+
photofy(photo_field, image_processor: proc, parent_photo_field: parent_photo_field)
|
27
|
+
end
|
28
|
+
|
29
|
+
#Example
|
30
|
+
#photofy(:door)
|
31
|
+
#photofy(:small_door, {parent_photo_field: :door})
|
32
|
+
#photofy(:window, {image_processor: Proc.new { |img| img.scale(25, 25) }})
|
33
|
+
#after_photofy :door, :ventilator, Proc.new { |img| img.scale(25, 25) }
|
34
|
+
#
|
35
|
+
#Generates photo filed from photo_field arguments and provides methods like
|
36
|
+
#if photo_filed is "collage" then it provides methods on top of it as
|
37
|
+
#collage >> Getter,
|
38
|
+
#collage? >> Returns true if assignment is having value other than nil else false,
|
39
|
+
#collage = >> Setter. Acceptable inputs are file upload(ActionDispatch::Http::UploadedFile), filer handle and String(format validation is ignored),
|
40
|
+
#collage_path >> File path of assignment,
|
41
|
+
#collage_s3publicpath >> Public aws s3 url provider if (aws s3 is used as storage)
|
42
|
+
#collage_path_to_write >> File path of assignment to write (specific to writing. Used internally),
|
43
|
+
#collage_persisted? >> true if provided file/data is stored on disk,
|
44
|
+
#collage_store! >> to store provided file/data on disk,
|
45
|
+
#collage_destroy! >> to store destroy stored file/data from disk
|
46
|
+
#
|
47
|
+
#Options:
|
48
|
+
#image_processor: a proc for image processing like Proc.new { |img| img.scale(25, 25) }
|
49
|
+
#parent_photo_field: a parent photo field name to be used as source
|
50
|
+
def photofy(photo_field, options = {})
|
51
|
+
collect_photo_formats(photo_field, options)
|
52
|
+
|
53
|
+
@photo_fields ||=[]
|
54
|
+
@photo_fields << photo_field
|
55
|
+
|
56
|
+
define_method 'initialize_photo_buffers' do
|
57
|
+
@photo_file_buffer ||= {}
|
58
|
+
@photo_file_ofn ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
define_method "#{photo_field}_path" do
|
62
|
+
directory_path = FileUtils.mkdir_p File.join(self.class.photos_repository, photo_field.to_s)
|
63
|
+
if s3_connected?
|
64
|
+
_path = File.join(directory_path, self.send(self.class.primary_key).to_s)
|
65
|
+
_path.gsub!(/^#{Rails.root}\//, "")
|
66
|
+
|
67
|
+
(_s3_objects = s3_bucket.objects.with_prefix("#{_path}_")).count > 0 ? _s3_objects.collect(&:key)[0] : nil
|
68
|
+
else
|
69
|
+
(guessed_file = Dir[File.join(directory_path, "#{self.send(self.class.primary_key).to_s}_*")].first).nil? ?
|
70
|
+
nil : guessed_file.to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
define_method "#{photo_field}_s3publicpath" do
|
75
|
+
s3_bucket.objects[send("#{photo_field}_path")].url_for(:read).try(:to_s) if send("#{photo_field}_persisted?")
|
76
|
+
end if s3_connected?
|
77
|
+
|
78
|
+
define_method "#{photo_field}_path_to_write" do |overload_dir = nil|
|
79
|
+
directoy_path = FileUtils.mkdir_p File.join(self.class.photos_repository, photo_field.to_s, overload_dir.to_s)
|
80
|
+
_path = File.join(directoy_path, "#{self.send(self.class.primary_key).to_s}#{(@photo_file_ofn[photo_field].nil?) ? "_" : "_#{@photo_file_ofn[photo_field]}" }")
|
81
|
+
_path.gsub!(/^#{Rails.root}\//, "") if s3_connected?
|
82
|
+
_path
|
83
|
+
end
|
84
|
+
|
85
|
+
#Defining getter
|
86
|
+
define_method "#{photo_field}" do
|
87
|
+
send('initialize_photo_buffers')
|
88
|
+
|
89
|
+
if @photo_file_buffer[photo_field].nil?
|
90
|
+
if s3_connected?
|
91
|
+
if send("#{photo_field}_persisted?")
|
92
|
+
_file = nil
|
93
|
+
file = Tempfile.new('foo', :encoding => 'ascii-8bit')
|
94
|
+
s3_bucket.objects[send("#{photo_field}_path")].read { |chunk| file.write(chunk) }
|
95
|
+
file.rewind
|
96
|
+
_file = file.read
|
97
|
+
file.close
|
98
|
+
file.unlink # deletes the temp file
|
99
|
+
_file
|
100
|
+
else
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
else
|
104
|
+
send("#{photo_field}_persisted?") ? File.read(send("#{photo_field}_path")) : nil
|
105
|
+
end
|
106
|
+
else
|
107
|
+
@photo_file_buffer[photo_field]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
define_method "#{photo_field}?" do
|
112
|
+
send("#{photo_field}").nil? ? false : true
|
113
|
+
end
|
114
|
+
|
115
|
+
#Defining setter
|
116
|
+
define_method "#{photo_field}=" do |file_upload|
|
117
|
+
send('initialize_photo_buffers')
|
118
|
+
|
119
|
+
if file_upload.class == ActionDispatch::Http::UploadedFile
|
120
|
+
return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload.original_filename).downcase)
|
121
|
+
@photo_file_buffer[photo_field] = File.read(file_upload.path)
|
122
|
+
@photo_file_ofn[photo_field] = File.basename(file_upload.original_filename)
|
123
|
+
|
124
|
+
elsif file_upload.class == File
|
125
|
+
return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload.path).downcase)
|
126
|
+
@photo_file_buffer[photo_field] = file_upload.read
|
127
|
+
@photo_file_ofn[photo_field] = File.basename(file_upload.path)
|
128
|
+
|
129
|
+
file_upload.rewind
|
130
|
+
elsif file_upload.class == String
|
131
|
+
#return false unless self.class.photo_formats[photo_field].include?(File.extname(file_upload).downcase)
|
132
|
+
@photo_file_buffer[photo_field] = file_upload
|
133
|
+
#@photo_file_ofn[photo_field] = File.basename(file_upload.path) #As there is nothing like original_file_name for a string :)
|
134
|
+
end
|
135
|
+
|
136
|
+
file_upload
|
137
|
+
end
|
138
|
+
|
139
|
+
define_method "#{photo_field}_persisted?" do
|
140
|
+
send('initialize_photo_buffers')
|
141
|
+
if s3_connected?
|
142
|
+
directory_path = FileUtils.mkdir_p File.join(self.class.photos_repository, photo_field.to_s)
|
143
|
+
_path = File.join(directory_path, self.send(self.class.primary_key).to_s)
|
144
|
+
_path.gsub!(/^#{Rails.root}\//, "")
|
145
|
+
|
146
|
+
(@photo_file_buffer[photo_field].nil? and ((s3_bucket.objects.with_prefix("#{_path}_")).count > 0))
|
147
|
+
else
|
148
|
+
(@photo_file_buffer[photo_field].nil? and File.file?(send("#{photo_field}_path")))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
define_method "#{photo_field}_store" do |proc, parent_photo_field|
|
153
|
+
return unless self.class.is_photofied?
|
154
|
+
|
155
|
+
send('initialize_photo_buffers')
|
156
|
+
|
157
|
+
#Loading content from parent_photo_field if specified
|
158
|
+
unless parent_photo_field.nil?
|
159
|
+
if s3_connected?
|
160
|
+
unless send("#{parent_photo_field}_path").nil?
|
161
|
+
_parent_file_path = send("#{parent_photo_field}_path")
|
162
|
+
_temp_file_path = File.join(Rails.root, File.basename(_parent_file_path))
|
163
|
+
file = File.open(_temp_file_path, 'wb')
|
164
|
+
s3_bucket.objects[_parent_file_path].read { |chunk| file.write(chunk) }
|
165
|
+
file.close
|
166
|
+
file = File.open(_temp_file_path)
|
167
|
+
send("#{photo_field}=", file)
|
168
|
+
file.close
|
169
|
+
File.delete(file.path)
|
170
|
+
end
|
171
|
+
else
|
172
|
+
send("#{photo_field}=", File.open(send("#{parent_photo_field}_path"))) unless send("#{parent_photo_field}_path").nil?
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
unless @photo_file_buffer[photo_field].nil?
|
177
|
+
|
178
|
+
if s3_connected?
|
179
|
+
s3_bucket.objects[send("#{photo_field}_path")].try(:delete) if (not send("#{photo_field}_path").nil?) and (s3_bucket.objects.with_prefix(send("#{photo_field}_path")).count > 0)
|
180
|
+
s3_bucket.objects[send("#{photo_field}_path_to_write")].write(@photo_file_buffer[photo_field])
|
181
|
+
|
182
|
+
unless proc.nil?
|
183
|
+
file = Tempfile.new('foo', :encoding => 'ascii-8bit')
|
184
|
+
s3_bucket.objects[send("#{photo_field}_path")].read { |chunk| file.write(chunk) }
|
185
|
+
file.rewind
|
186
|
+
|
187
|
+
img = Magick::Image.read(file.path).first
|
188
|
+
img = proc.call(img)
|
189
|
+
s3_bucket.objects[send("#{photo_field}_path_to_write")].write(img.to_blob)
|
190
|
+
|
191
|
+
file.close
|
192
|
+
file.unlink # deletes the temp file
|
193
|
+
end
|
194
|
+
else
|
195
|
+
File.delete(send("#{photo_field}_path")) if ((not send("#{photo_field}_path").nil?) and File.exist?(send("#{photo_field}_path"))) #Clearing any existing file at the path
|
196
|
+
File.open(send("#{photo_field}_path_to_write"), "wb+") { |f| f.puts(@photo_file_buffer[photo_field]) }
|
197
|
+
|
198
|
+
unless proc.nil?
|
199
|
+
FileUtils.copy(send("#{photo_field}_path_to_write"), send("#{photo_field}_path_to_write", "original_source"))
|
200
|
+
img = Magick::Image.read(send("#{photo_field}_path")).first
|
201
|
+
img = proc.call(img)
|
202
|
+
img.write(send("#{photo_field}_path_to_write"))
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
@photo_file_buffer[photo_field] = nil
|
207
|
+
@photo_file_ofn[photo_field] = nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
define_method "#{photo_field}_store!" do
|
212
|
+
send("#{photo_field}_store", options[:image_processor], options[:parent_photo_field])
|
213
|
+
end
|
214
|
+
|
215
|
+
define_method "#{photo_field}_destroy!" do
|
216
|
+
return unless self.class.is_photofied?
|
217
|
+
|
218
|
+
send('initialize_photo_buffers')
|
219
|
+
@photo_file_buffer[photo_field] = nil
|
220
|
+
if s3_connected?
|
221
|
+
s3_bucket.objects[send("#{photo_field}_path")].try(:delete)
|
222
|
+
else
|
223
|
+
File.delete(send("#{photo_field}_path")) if File.exist?(send("#{photo_field}_path"))
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
send(:after_save, "#{photo_field}_store!")
|
228
|
+
send(:after_destroy, "#{photo_field}_destroy!")
|
229
|
+
|
230
|
+
@photofied_flag = true
|
231
|
+
end
|
232
|
+
|
233
|
+
def photos_repository
|
234
|
+
@photos_repository ||= FileUtils.mkdir_p(File.join(Rails.root, "photofy", self.name))[0]
|
235
|
+
end
|
236
|
+
|
237
|
+
#Collects valid photo formats specific to photo fields
|
238
|
+
def collect_photo_formats(photo_field, options)
|
239
|
+
if options.is_a?(Hash)
|
240
|
+
@photo_formats ||= {}
|
241
|
+
@photo_formats[photo_field] = options[:formats].is_a?(Array) ? options[:formats].collect { |x| x.starts_with?(".") ? x : ".#{x}" } : [".jpeg", ".jpg", ".gif", ".png", ".bmp"]
|
242
|
+
else
|
243
|
+
raise 'InvalidArguments'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'aws-sdk'
|
3
|
+
|
4
|
+
module Photofy
|
5
|
+
|
6
|
+
class S3Setting
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
attr_accessor :s3_setup
|
10
|
+
attr_accessor :s3_bucket
|
11
|
+
end
|
12
|
+
|
13
|
+
module S3Methods
|
14
|
+
def self.extended(base)
|
15
|
+
base.include(InstanceMethods)
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def s3_connected?
|
20
|
+
self.class.s3_connected?
|
21
|
+
end
|
22
|
+
|
23
|
+
def s3_bucket
|
24
|
+
S3Setting.instance.s3_bucket
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def s3_connected?
|
29
|
+
(S3Setting.instance.s3_bucket.class == AWS::S3::Bucket)
|
30
|
+
end
|
31
|
+
|
32
|
+
#Enables aws s3 as backend storage.
|
33
|
+
#Takes two arguments:
|
34
|
+
#1. aws_settings. Hash with access_key_id and secret_access_key from aws s3
|
35
|
+
#2. instance_settings. Hash with bucket as valid aws s3 bucket to be
|
36
|
+
#
|
37
|
+
#Example usage:
|
38
|
+
#photofy_s3_storage({access_key_id: 'xxxxxxxx',secret_access_key: 'xxxxxxxx'}, {bucket: 'test_bucket'})
|
39
|
+
def photofy_s3_storage(aws_settings = {}, instance_settings = {})
|
40
|
+
instance_settings[:bucket] ||= 'photofy'
|
41
|
+
(S3Setting.instance.s3_setup ||= {}).merge!(aws_settings: aws_settings, instance_settings: instance_settings)
|
42
|
+
|
43
|
+
try_connect
|
44
|
+
end
|
45
|
+
|
46
|
+
def try_connect
|
47
|
+
if try_accessing_existing_awsconfig
|
48
|
+
setup_bucket
|
49
|
+
else
|
50
|
+
begin
|
51
|
+
AWS.config(S3Setting.instance.s3_setup[:aws_settings])
|
52
|
+
setup_bucket
|
53
|
+
rescue AWS::Errors::MissingCredentialsError => e
|
54
|
+
puts 'Photofy:S3: AWS credentials not provided.'
|
55
|
+
puts e.message
|
56
|
+
rescue AWS::S3::Errors::SignatureDoesNotMatch => e
|
57
|
+
puts 'Photofy:S3: AWS credentials is most probably not correct.'
|
58
|
+
puts e.message
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup_bucket
|
64
|
+
s3 = AWS::S3.new
|
65
|
+
_bucket_name = S3Setting.instance.s3_setup[:instance_settings][:bucket]
|
66
|
+
S3Setting.instance.s3_bucket = if s3.buckets.collect { |x| x.name }.include?(_bucket_name)
|
67
|
+
s3.buckets[_bucket_name]
|
68
|
+
else
|
69
|
+
s3.buckets.create(_bucket_name)
|
70
|
+
end
|
71
|
+
S3Setting.instance.s3_bucket
|
72
|
+
end
|
73
|
+
|
74
|
+
def try_accessing_existing_awsconfig
|
75
|
+
begin
|
76
|
+
setup_bucket
|
77
|
+
rescue AWS::Errors::MissingCredentialsError => e
|
78
|
+
puts 'Photofy:S3: No existing aws config found.'
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: photofy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Praveen Kumar Sinha
|
@@ -10,30 +10,56 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
date: 2014-07-31 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: aws-sdk
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.49'
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.49.0
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - "~>"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '1.49'
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.49.0
|
35
|
+
description: |2
|
36
|
+
A gem to provide simple method to do file upload of pictures and provides getter setter methods of it and save on model object commit.
|
37
|
+
|
38
|
+
#Generates photo filed from photo_field arguments and provides methods like
|
39
|
+
#if photo_filed is "collage" then it provides methods on top of it as
|
40
|
+
#collage >> Getter,
|
41
|
+
#collage? >> Returns true if assignment is having value other than nil else false,
|
42
|
+
#collage = >> Setter. Acceptable inputs are file upload(ActionDispatch::Http::UploadedFile), filer handle and String(format validation is ignored),
|
43
|
+
#collage_path >> File path of assignment,
|
44
|
+
collage_s3publicpath >> Public aws s3 url provider if (aws s3 is used as storage),
|
45
|
+
#collage_path_to_write >> File path of assignment to write (specific to writing. Used internally),
|
46
|
+
#collage_persisted? >> true if provided file/data is stored on disk,
|
47
|
+
#collage_store! >> to store provided file/data on disk,
|
48
|
+
#collage_destroy! >> to store destroy stored file/data from disk
|
27
49
|
email: praveen.kumar.sinha@gmail.com
|
28
50
|
executables: []
|
29
51
|
extensions: []
|
30
52
|
extra_rdoc_files: []
|
31
53
|
files:
|
32
54
|
- lib/photofy.rb
|
55
|
+
- lib/photofy/core.rb
|
56
|
+
- lib/photofy/s3methods.rb
|
33
57
|
homepage: http://praveenkumarsinha.github.io/Photofy
|
34
|
-
licenses:
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
- GPL-2
|
35
61
|
metadata: {}
|
36
|
-
post_install_message:
|
62
|
+
post_install_message: Thanks for installing Photofy.
|
37
63
|
rdoc_options: []
|
38
64
|
require_paths:
|
39
65
|
- lib
|
@@ -49,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
75
|
version: '0'
|
50
76
|
requirements: []
|
51
77
|
rubyforge_project:
|
52
|
-
rubygems_version: 2.2.
|
78
|
+
rubygems_version: 2.2.2
|
53
79
|
signing_key:
|
54
80
|
specification_version: 4
|
55
81
|
summary: Photofy
|