attachs 4.0.0.2 → 4.0.0.3

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 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