attachs 4.0.0.2 → 4.0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 653b5fdf90ea9ec9f6640e1140049926559ef70d
4
- data.tar.gz: cfda202374b674b8ba19ff40c313d355df06bee8
3
+ metadata.gz: c16c8226d22e2d772ba2f3ee5aa32f5e9b0b18e0
4
+ data.tar.gz: aa8c1e0487680a41a7a97ac4ed9d0426948e3fb1
5
5
  SHA512:
6
- metadata.gz: dab6cee3cb044df3c5236d91098ff20b684a8115a24c37eae7f46677a2feaa8c6ec29c8e56931b5a1ccc2730b90c0a5aa8e5cc3d3e2f5ebb398817b47b5df0c5
7
- data.tar.gz: 57757e1bea0b292660d67d93ca3a3a0d48fedcb1c7c5c93f156e33995768fd1a10f5525461de2d3354d40c82ec67c583afa52f1a0bfe8157b0e5a4fdba82db42
6
+ metadata.gz: e0fa01842ed7f65ec104a4aed5cafa51427c432d319797b7048601ce20f7617657c0f32dafecef870bc7501a22958375c908a2039c30019922e147174ffab912
7
+ data.tar.gz: f841b2bb5bc391a640d6a46fe11232277b8cac77f66715007f2e105602a7ba00c0875fe527ec07a01498c561e61c8cd4298b53c682eadc82ec80662f05679ffb
@@ -1,3 +1,5 @@
1
+ require 'attachs/attachment/attributes'
2
+ require 'attachs/attachment/processing'
1
3
  require 'attachs/extensions/active_record/validations/attachment_validator'
2
4
  require 'attachs/extensions/active_record/validations/attachment_content_type_validator'
3
5
  require 'attachs/extensions/active_record/validations/attachment_presence_validator'
@@ -1,344 +1,9 @@
1
1
  module Attachs
2
2
  class Attachment
3
- include ActiveModel::Validations
4
-
5
- attr_reader :record, :record_attribute, :options, :attributes, :value, :original_attributes, :source
6
-
7
- def initialize(record, record_attribute, options={}, attributes={})
8
- @record = record
9
- @record_attribute = record_attribute
10
- @options = options
11
- @original_attributes = @attributes = normalize_attributes(attributes)
12
- end
13
-
14
- %i(id size filename content_type uploaded_at).each do |name|
15
- define_method name do
16
- attributes[name]
17
- end
18
- end
19
-
20
- def basename
21
- if filename
22
- File.basename filename, extension
23
- end
24
- end
25
-
26
- def extension
27
- if filename
28
- File.extname filename
29
- end
30
- end
31
-
32
- def present?
33
- filename.present? && content_type.present? && size.present?
34
- end
35
-
36
- def blank?
37
- !present?
38
- end
39
-
40
- def persisted?
41
- record.persisted? && paths.any? && uploaded_at
42
- end
43
-
44
- def changed?
45
- @original_attributes != @attributes
46
- end
47
-
48
- def type
49
- if content_type
50
- if content_type.starts_with?('image/')
51
- 'image'
52
- else
53
- 'file'
54
- end
55
- end
56
- end
57
-
58
- def url(style=:original)
59
- paths = attributes[:paths]
60
- if paths.has_key?(style)
61
- storage.url paths[style]
62
- elsif options.has_key?(:default_path)
63
- template = options[:default_path]
64
- path = generate_path(template, style)
65
- storage.url path
66
- end
67
- end
68
-
69
- def position
70
- if options[:multiple]
71
- attributes[:position]
72
- end
73
- end
74
-
75
- def position=(value)
76
- if options[:multiple]
77
- attributes[:position] = value
78
- write_record
79
- end
80
- end
81
-
82
- def assign(value)
83
- source, new_attributes = process_value(value)
84
- if new_attributes
85
- unless changed?
86
- @original_attributes = attributes
87
- end
88
- @attributes = new_attributes
89
- write_record
90
- @source = source
91
- @value = value
92
- end
93
- end
94
- alias_method :value=, :assign
95
-
96
- def _destroy=(value)
97
- if ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
98
- assign nil
99
- end
100
- end
101
-
102
- def save
103
- if changed?
104
- if original_attributes[:paths].any? || original_attributes[:old_paths].any?
105
- Jobs::DeleteJob.perform_later(
106
- original_attributes[:paths].values +
107
- original_attributes[:old_paths]
108
- )
109
- end
110
- case source.class.name
111
- when 'Attachs::Attachment'
112
- file = storage.get(source.paths[:original])
113
- storage.process file, paths, styles
114
- when 'Upload'
115
- source.file.paths.each do |style, path|
116
- storage.copy path, paths[style]
117
- end
118
- when 'ActionDispatch::Http::UploadedFile'
119
- storage.process source, paths, styles
120
- end
121
- @source = @value = nil
122
- @original_attributes = @attributes
123
- elsif present?
124
- if paths != generate_paths
125
- Jobs::UpdateJob.perform_later record, record_attribute.to_s
126
- end
127
- end
128
- end
129
-
130
- def update_paths
131
- if changed?
132
- raise 'Save attachment before update paths'
133
- else
134
- new_paths = generate_paths
135
- if paths != new_paths
136
- new_paths.each do |style, new_path|
137
- original_path = paths[style]
138
- if original_path != new_path
139
- unless storage.exists?(new_path)
140
- storage.copy original_path, new_path
141
- end
142
- attributes[:paths][style] = new_path
143
- attributes[:old_paths] |= [original_path]
144
- end
145
- end
146
- update_record
147
- end
148
- end
149
- end
150
-
151
- def reprocess
152
- if changed?
153
- raise 'Save attachment before reprocess'
154
- elsif present? && styles
155
- file = storage.get(paths[:original])
156
- paths.each do |style, path|
157
- if storage.exists?(path)
158
- storage.delete path
159
- end
160
- Rails.logger.info "Regenerating: #{style} => #{path}"
161
- end
162
- new_paths = generate_paths
163
- storage.process file, new_paths, styles
164
- attributes[:paths] = new_paths
165
- update_record
166
- end
167
- end
168
-
169
- def fix_missings
170
- if changed?
171
- raise 'Save attachment before fix missings'
172
- elsif present? && styles
173
- missings = paths.slice(:original)
174
- paths.except(:original).each do |style, path|
175
- unless storage.exists?(path)
176
- missings[style] = path
177
- Rails.logger.info "Generating: #{style} => #{path}"
178
- end
179
- end
180
- if missings.size > 1
181
- file = storage.get(paths[:original])
182
- storage.process file, missings, styles
183
- end
184
- end
185
- end
186
-
187
- def destroy
188
- assign nil
189
- save
190
- end
191
-
192
- def method_missing(name, *args, &block)
193
- if attributes.has_key?(name)
194
- attributes[name]
195
- else
196
- super
197
- end
198
- end
199
-
200
- def respond_to_missing?(name, include_private=false)
201
- attributes.has_key?(name) || super
202
- end
203
-
204
- def persist
205
- if changed? && present?
206
- new_paths = generate_paths
207
- if paths != new_paths
208
- attributes[:paths] = new_paths
209
- attributes[:uploaded_at] = Time.now
210
- write_record
211
- end
212
- end
213
- end
214
-
215
- def unpersist
216
- if changed? && present?
217
- attributes[:paths] = original_attributes[:paths]
218
- attributes[:uploaded_at] = original_attributes[:uploaded_at]
219
- write_record
220
- end
221
- end
222
-
223
- def styles
224
- case value = options[:styles]
225
- when Proc
226
- value.call(record) || {}
227
- when Hash
228
- value
229
- else
230
- {}
231
- end
232
- end
233
-
234
- private
235
-
236
- def storage
237
- Attachs.storage
238
- end
239
-
240
- def normalize_attributes(attributes)
241
- attributes.reverse_merge(paths: {}, old_paths: []).deep_symbolize_keys
242
- end
243
-
244
- def write_record(value=nil)
245
- unless record.destroyed?
246
- record.send "#{record_attribute}_will_change!"
247
- record.send :write_attribute, record_attribute, (value || raw_attributes)
248
- end
249
- end
250
-
251
- def raw_attributes
252
- if options[:multiple]
253
- record.send(:read_attribute, record_attribute).reject{ |h| h['id'] == id }.append attributes
254
- else
255
- attributes
256
- end
257
- end
258
-
259
- def update_record(value=nil)
260
- unless record.destroyed?
261
- record.update_column record_attribute, (value || raw_attributes)
262
- end
263
- end
264
-
265
- def generate_path(template, style)
266
- if path = template.try(:dup)
267
- path.gsub! ':style', style.to_s.gsub('_', '-')
268
- path.scan(/:[a-z_]+/).each do |token|
269
- name = token.from(1).to_sym
270
- path.gsub! token, interpolate(name).to_s.parameterize
271
- end
272
- path.squeeze! '-'
273
- path.squeeze! '/'
274
- path.gsub! '-.', '.'
275
- path.gsub! '/-', '/'
276
- path.gsub! '-/', '/'
277
- path.sub! /^\//, ''
278
- path
279
- end
280
- end
281
-
282
- def generate_paths
283
- template = options[:path]
284
- paths = { original: generate_path(template, :original) }
285
- styles.each do |style, geometry|
286
- paths[style] = generate_path(template, style)
287
- end
288
- paths
289
- end
290
-
291
- def interpolate(name)
292
- if %i(basename extension).include?(name)
293
- send name
294
- elsif name == :attribute
295
- record_attribute
296
- elsif attributes.except(:upload_at, :paths, :old_paths).has_key?(name)
297
- attributes[name]
298
- else
299
- Attachs.interpolations.find(name).call record
300
- end
301
- end
302
-
303
- def generate_id
304
- SecureRandom.uuid.gsub '-', ''
305
- end
306
-
307
- def process_value(value)
308
- case value.class.name
309
- when 'NilClass'
310
- [nil, {}]
311
- when 'Attachs::Attachment'
312
- [value, value.attributes.merge(id: generate_id)]
313
- when 'Upload'
314
- [value, value.file.attributes.merge(id: generate_id)]
315
- when 'String','Fixnum','Bignum'
316
- if Rails.configuration.cache_classes == false
317
- Rails.application.eager_load!
318
- end
319
- if defined?(Upload)
320
- upload = Upload.find(value)
321
- [upload, upload.file.attributes.merge(id: generate_id)]
322
- end
323
- when 'ActionDispatch::Http::UploadedFile'
324
- attributes = {
325
- id: generate_id,
326
- filename: value.original_filename,
327
- content_type: value.content_type,
328
- size: value.size.to_i,
329
- uploaded_at: Time.now,
330
- paths: {},
331
- old_paths: []
332
- }
333
- if value.content_type.starts_with?('image/')
334
- width, height = Console.find_dimensions(value.path)
335
- attributes[:width] = width
336
- attributes[:height] = height
337
- attributes[:ratio] = (height.to_d / width.to_d).to_f
338
- end
339
- [value, attributes]
340
- end
341
- end
342
-
3
+ include(
4
+ ActiveModel::Validations,
5
+ Attachs::Attachment::Attributes,
6
+ Attachs::Attachment::Processing
7
+ )
343
8
  end
344
9
  end
@@ -0,0 +1,118 @@
1
+ module Attachs
2
+ class Attachment
3
+ module Attributes
4
+ extend ActiveSupport::Concern
5
+
6
+ attr_reader :record, :record_attribute, :options, :attributes, :value, :original_attributes, :source
7
+
8
+ def initialize(record, record_attribute, options={}, attributes={})
9
+ @record = record
10
+ @record_attribute = record_attribute
11
+ @options = options
12
+ @original_attributes = @attributes = normalize_attributes(attributes)
13
+ end
14
+
15
+ %i(id size filename content_type uploaded_at).each do |name|
16
+ define_method name do
17
+ attributes[name]
18
+ end
19
+ end
20
+
21
+ def basename
22
+ if filename
23
+ File.basename filename, extension
24
+ end
25
+ end
26
+
27
+ def extension
28
+ if filename
29
+ File.extname filename
30
+ end
31
+ end
32
+
33
+ def present?
34
+ filename.present? && content_type.present? && size.present?
35
+ end
36
+
37
+ def blank?
38
+ !present?
39
+ end
40
+
41
+ def persisted?
42
+ record.persisted? && paths.any? && uploaded_at
43
+ end
44
+
45
+ def changed?
46
+ @original_attributes != @attributes
47
+ end
48
+
49
+ def type
50
+ if content_type
51
+ if content_type.starts_with?('image/')
52
+ 'image'
53
+ else
54
+ 'file'
55
+ end
56
+ end
57
+ end
58
+
59
+ def position
60
+ if options[:multiple]
61
+ attributes[:position]
62
+ end
63
+ end
64
+
65
+ def position=(value)
66
+ if options[:multiple]
67
+ attributes[:position] = value
68
+ write_record
69
+ end
70
+ end
71
+
72
+ def styles
73
+ case value = options[:styles]
74
+ when Proc
75
+ value.call(record) || {}
76
+ when Hash
77
+ value
78
+ else
79
+ {}
80
+ end
81
+ end
82
+
83
+ def respond_to_missing?(name, include_private=false)
84
+ attributes.has_key?(name) || super
85
+ end
86
+
87
+ def method_missing(name, *args, &block)
88
+ if attributes.has_key?(name)
89
+ attributes[name]
90
+ else
91
+ super
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def normalize_attributes(attributes)
98
+ attributes.reverse_merge(paths: {}, old_paths: []).deep_symbolize_keys
99
+ end
100
+
101
+ def write_record(value=nil)
102
+ unless record.destroyed?
103
+ record.send "#{record_attribute}_will_change!"
104
+ record.send :write_attribute, record_attribute, (value || raw_attributes)
105
+ end
106
+ end
107
+
108
+ def raw_attributes
109
+ if options[:multiple]
110
+ record.send(:read_attribute, record_attribute).reject{ |h| h['id'] == id }.append attributes
111
+ else
112
+ attributes
113
+ end
114
+ end
115
+
116
+ end
117
+ end
118
+ end