trusty-cms 7.0.49 → 7.1.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/assets/builds/trusty_cms/ckeditor5.css +459 -81
  4. data/app/assets/builds/trusty_cms/ckeditor5.css.map +3 -3
  5. data/app/assets/builds/trusty_cms/ckeditor5.js +11247 -7722
  6. data/app/assets/builds/trusty_cms/ckeditor5.js.map +4 -4
  7. data/app/assets/stylesheets/admin/assets.scss +5 -0
  8. data/app/controllers/admin/assets_controller.rb +7 -14
  9. data/app/javascript/plugins/asset_tags/asset_tag_builder.js +7 -2
  10. data/app/models/asset.rb +144 -48
  11. data/app/models/asset_type.rb +29 -25
  12. data/app/views/admin/assets/_search_results.html.haml +2 -3
  13. data/app/views/admin/assets/edit.html.haml +2 -2
  14. data/app/views/admin/assets/remove.html.haml +1 -1
  15. data/app/views/admin/configuration/_clipped_edit.html.haml +1 -0
  16. data/app/views/admin/configuration/_clipped_show.html.haml +2 -0
  17. data/config/database.yml +30 -0
  18. data/config/initializers/trusty_cms_config.rb +3 -50
  19. data/config/locales/en.yml +6 -1
  20. data/config/routes.rb +0 -2
  21. data/db/migrate/20110606111250_update_configuration.rb +0 -16
  22. data/lib/trusty_cms/geometry.rb +117 -0
  23. data/lib/trusty_cms/version.rb +1 -1
  24. data/spec/dummy/log/development.log +345 -0
  25. data/spec/dummy/log/test.log +0 -0
  26. data/spec/dummy/tmp/cache/747/A70/TrustyCms%3A%3AConfig +0 -0
  27. data/spec/dummy/tmp/cache/85C/FA0/TrustyCms.cache_mtime +0 -0
  28. data/spec/dummy/tmp/local_secret.txt +1 -0
  29. data/spec/dummy/tmp/trusty_config_cache.txt +0 -0
  30. data/spec/lib/trusty_cms/geometry_spec.rb +28 -0
  31. data/spec/models/asset_spec.rb +235 -12
  32. data/trusty_cms.gemspec +1 -1
  33. data/vendor/extensions/clipped-extension/clipped_extension.rb +4 -9
  34. data/vendor/extensions/clipped-extension/lib/asset_tags.rb +10 -4
  35. data/vendor/extensions/clipped-extension/lib/generators/templates/clipped_config.rb +11 -35
  36. data/vendor/extensions/clipped-extension/lib/tasks/active_storage_tasks.rake +66 -0
  37. data/vendor/extensions/clipped-extension/lib/tasks/clipped_extension_tasks.rake +5 -2
  38. data/vendor/extensions/clipped-extension/lib/trusty_cms_clipped_extension/cloud.rb +32 -27
  39. data/yarn.lock +9 -9
  40. metadata +21 -8
  41. data/lib/trusty_cms/deprecation.rb +0 -15
  42. data/vendor/extensions/clipped-extension/lib/paperclip/frame_grab.rb +0 -73
  43. data/vendor/extensions/clipped-extension/lib/paperclip/geometry_transformation.rb +0 -80
  44. data/vendor/extensions/clipped-extension/lib/tasks/paperclip_tasks.rake +0 -79
@@ -1,3 +1,8 @@
1
+ img.preview {
2
+ max-width: 300px;
3
+ max-height: 300px;
4
+ }
5
+
1
6
  .ck-content .asset-image-tag {
2
7
  background-color: #dcdcdc;
3
8
  display: inline-flex;
@@ -1,7 +1,6 @@
1
1
  class Admin::AssetsController < Admin::ResourceController
2
2
  paginate_models(per_page: 50)
3
3
  COMPRESS_FILE_TYPE = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'].freeze
4
- APPROVED_CONTENT_TYPES = Asset::APPROVED_CONTENT_TYPES
5
4
 
6
5
  def index
7
6
  assets = Asset.order('created_at DESC')
@@ -40,7 +39,7 @@ class Admin::AssetsController < Admin::ResourceController
40
39
  @page_attachments << (@page_attachment = @asset.page_attachments.build(page: @page))
41
40
  end
42
41
 
43
- render json: { url: @asset.asset.url }
42
+ render json: { url: @asset.public_url }
44
43
  else
45
44
  flash[result.fetch(:flash_type, :error)] = result[:error]
46
45
  render json: { error: result[:error] }, status: result.fetch(:status, :unprocessable_entity)
@@ -52,6 +51,7 @@ class Admin::AssetsController < Admin::ResourceController
52
51
  @page_attachments = []
53
52
  uploads = Array(asset_params.dig('asset', 'asset')).reject(&:blank?)
54
53
 
54
+
55
55
  uploads.each do |uploaded_asset|
56
56
  result = process_uploaded_asset(uploaded_asset)
57
57
 
@@ -64,27 +64,20 @@ class Admin::AssetsController < Admin::ResourceController
64
64
  @assets << @asset
65
65
  else
66
66
  flash[result.fetch(:flash_type, :error)] = result[:error]
67
+ @errors = result[:error]
67
68
  end
68
69
  end
69
70
 
70
71
  if asset_params[:for_attachment]
71
72
  render partial: 'admin/page_attachments/attachment', collection: @page_attachments
73
+ elsif @errors.present?
74
+ flash[:error] = @errors
75
+ redirect_to new_admin_asset_path
72
76
  else
73
77
  response_for :create
74
78
  end
75
79
  end
76
80
 
77
- def refresh
78
- if asset_params[:id]
79
- @asset = Asset.find(params[:id])
80
- @asset.asset.reprocess!
81
- flash[:notice] = t('clipped_extension.thumbnails_refreshed')
82
- redirect_to edit_admin_asset_path(@asset)
83
- else
84
- render
85
- end
86
- end
87
-
88
81
  private
89
82
 
90
83
  def process_uploaded_asset(uploaded_asset)
@@ -94,7 +87,7 @@ class Admin::AssetsController < Admin::ResourceController
94
87
  return failure_response('Please only upload assets that have a valid extension in the name.', :unprocessable_entity, :notice)
95
88
  end
96
89
 
97
- unless APPROVED_CONTENT_TYPES.include?(uploaded_asset.content_type)
90
+ unless Asset.approved_content_types.include?(uploaded_asset.content_type)
98
91
  return failure_response('Unsupported file type.', :unsupported_media_type, :error)
99
92
  end
100
93
 
@@ -20,13 +20,12 @@ export default class AssetTagBuilder extends Plugin {
20
20
  allowWhere: '$text',
21
21
  isInline: true,
22
22
  isObject: true,
23
- allowAttributes: [ 'id', 'size', 'alt', 'height', 'width' ]
23
+ allowAttributes: [ 'id', 'class', 'size', 'alt', 'height', 'width', 'linkHref', 'linkTarget', 'linkRel' ]
24
24
  } );
25
25
  }
26
26
 
27
27
  _defineConverters() {
28
28
  const conversion = this.editor.conversion;
29
-
30
29
  const upcast = conversion.for( 'upcast' );
31
30
  const dataDowncast = conversion.for( 'dataDowncast' );
32
31
  const editingDowncast = conversion.for( 'editingDowncast' );
@@ -38,12 +37,14 @@ export default class AssetTagBuilder extends Plugin {
38
37
  model: ( viewElement, { writer } ) => {
39
38
  const attrs = {};
40
39
  const id = viewElement.getAttribute( 'id' );
40
+ const klass = viewElement.getAttribute( 'class' );
41
41
  const size = viewElement.getAttribute( 'size' );
42
42
  const alt = viewElement.getAttribute( 'alt' );
43
43
  const height = viewElement.getAttribute( 'height' );
44
44
  const width = viewElement.getAttribute( 'width' );
45
45
 
46
46
  if ( id ) attrs.id = id;
47
+ if ( klass ) attrs.class = klass;
47
48
  if ( size ) attrs.size = size;
48
49
  if ( alt ) attrs.alt = alt;
49
50
  if ( height ) attrs.height = height;
@@ -60,12 +61,14 @@ export default class AssetTagBuilder extends Plugin {
60
61
  view: ( modelElement, { writer } ) => {
61
62
  const attrs = {};
62
63
  const id = modelElement.getAttribute( 'id' );
64
+ const klass = modelElement.getAttribute( 'class' );
63
65
  const size = modelElement.getAttribute( 'size' );
64
66
  const alt = modelElement.getAttribute( 'alt' );
65
67
  const height = modelElement.getAttribute( 'height' );
66
68
  const width = modelElement.getAttribute( 'width' );
67
69
 
68
70
  if ( id ) attrs.id = id;
71
+ if ( klass ) attrs.class = klass;
69
72
  if ( size ) attrs.size = size;
70
73
  if ( alt ) attrs.alt = alt;
71
74
  if ( height ) attrs.height = height;
@@ -81,12 +84,14 @@ export default class AssetTagBuilder extends Plugin {
81
84
  view: ( modelElement, { writer } ) => {
82
85
  const attrs = {};
83
86
  const id = modelElement.getAttribute( 'id' );
87
+ const klass = modelElement.getAttribute( 'class' );
84
88
  const size = modelElement.getAttribute( 'size' );
85
89
  const alt = modelElement.getAttribute( 'alt' );
86
90
  const height = modelElement.getAttribute( 'height' );
87
91
  const width = modelElement.getAttribute( 'width' );
88
92
 
89
93
  if ( id ) attrs.id = id;
94
+ if ( klass ) attrs.class = klass;
90
95
  if ( size ) attrs.size = size;
91
96
  if ( alt ) attrs.alt = alt;
92
97
  if ( height ) attrs.height = height;
data/app/models/asset.rb CHANGED
@@ -1,6 +1,6 @@
1
- class Asset < ActiveRecord::Base
2
- APPROVED_CONTENT_TYPES = %w[application/zip image/jpg image/jpeg image/png image/gif application/pdf text/css text/calendar].freeze
1
+ require 'trusty_cms/geometry'
3
2
 
3
+ class Asset < ActiveRecord::Base
4
4
  has_many :page_attachments, dependent: :destroy
5
5
  has_many :pages, through: :page_attachments
6
6
  has_site if respond_to? :has_site
@@ -16,11 +16,13 @@ class Asset < ActiveRecord::Base
16
16
 
17
17
  scope :of_types, lambda { |types|
18
18
  mimes = AssetType.slice(*types).map(&:mime_types).flatten
19
- Asset.select { |x| mimes.include?(x.asset_content_type) }
19
+ return none if mimes.empty?
20
+
21
+ joins(asset_attachment: :blob).where(active_storage_blobs: { content_type: mimes })
20
22
  }
21
23
 
22
24
  scope :matching, lambda { |term|
23
- where(['LOWER(assets.asset_file_name) LIKE (:term) OR LOWER(title) LIKE (:term) OR LOWER(caption) LIKE (:term)', { term: "%#{term.downcase}%" }])
25
+ joins(asset_attachment: :blob).where(['LOWER(active_storage_blobs.filename) LIKE (:term) OR LOWER(title) LIKE (:term) OR LOWER(caption) LIKE (:term)', { term: "%#{term.downcase}%" }])
24
26
  }
25
27
 
26
28
  scope :excepting, lambda { |assets|
@@ -33,72 +35,121 @@ class Asset < ActiveRecord::Base
33
35
  end
34
36
  }
35
37
 
38
+ def self.approved_content_types
39
+ AssetType.known_mimetypes
40
+ end
41
+
36
42
  has_one_attached :asset
37
- validates :asset,
38
- presence: true,
39
- blob:
40
- {
41
- content_type: APPROVED_CONTENT_TYPES,
42
- size_range: 1..10.megabytes,
43
- }
43
+ validates :asset, presence: true
44
+ validate :asset_within_configured_size, if: -> { asset.attached? }
45
+ validate :approved_content_type, if: -> { asset.attached? }
46
+ before_validation :sync_attachment_metadata
44
47
  before_save :assign_title
45
48
  before_save :assign_uuid
46
49
 
50
+ def asset_within_configured_size
51
+ limit_mb =
52
+ if video_content_type?
53
+ TrustyCms.config['assets.max_video_size'].to_i
54
+ else
55
+ TrustyCms.config['assets.max_asset_size'].to_i
56
+ end
57
+
58
+ limit_bytes = limit_mb.megabytes
59
+ return if asset.blob.byte_size.between?(1, limit_bytes)
60
+
61
+ errors.add(:asset, :wrong_size_error, limit_mb: limit_mb)
62
+ end
63
+
47
64
  def asset_type
48
65
  AssetType.for(asset)
49
66
  end
50
67
 
51
- delegate :paperclip_processors, :paperclip_styles, :active_storage_styles, :style_dimensions, :style_format,
68
+ def filename
69
+ return asset.filename.to_s if asset.attached?
70
+
71
+ self[:asset_file_name]
72
+ end
73
+
74
+ def content_type
75
+ return asset.content_type if asset.attached?
76
+
77
+ self[:asset_content_type]
78
+ end
79
+
80
+ def byte_size
81
+ return asset.blob.byte_size if asset.attached?
82
+
83
+ self[:asset_file_size]
84
+ end
85
+
86
+ delegate :active_storage_styles, :style_dimensions, :style_format,
52
87
  to: :asset_type
53
88
 
54
- def thumbnail(style_name = 'original')
55
- return asset.url if style_name.to_s == 'original' || render_original(style_name)
56
- return asset_variant(style_name.to_s).processed.url if asset.variable?
89
+ def thumbnail(style_name = 'normal')
90
+ return rewrite_cloud_url(asset.url) if asset.attached? && content_type == 'application/pdf'
91
+
92
+ variant = asset_variant(style_name.to_s)
93
+ return rewrite_cloud_url(variant.processed.url) if variant
57
94
 
58
95
  asset_type.icon(style_name.to_s)
59
96
  end
60
97
 
98
+ def public_url(style_name = 'normal')
99
+ if style_name.to_s == 'original' || render_original(style_name)
100
+ return rewrite_cloud_url(asset.url)
101
+ end
102
+
103
+ variant = asset_variant(style_name.to_s)
104
+ return rewrite_cloud_url(variant.processed.url) if variant
105
+
106
+ rewrite_cloud_url(asset.url)
107
+ end
108
+
61
109
  def self.ransackable_attributes(auth_object = nil)
62
110
  %w[asset_content_type asset_file_name asset_file_size caption created_at created_by_id id original_extension original_height original_width title updated_at updated_by_id uuid]
63
111
  end
64
112
 
65
- def render_original(style_name)
66
- style_name.to_s == 'original' && asset.key.include?('culturaldistrict')
113
+ def render_original(_style_name)
114
+ return false unless asset.attached?
115
+
116
+ prefix = TrustyCms::Config['assets.storage.prefix'].presence
117
+ prefix ? asset.key.start_with?(prefix) : asset.key.include?('/')
67
118
  end
68
119
 
69
120
  def asset_variant(style_name)
70
- case style_name
71
- when 'thumbnail'
72
- asset.variant(gravity: 'Center', resize: '100x100^', crop: '100x100+0+0')
73
- when 'small'
74
- asset.variant(gravity: 'Center', resize: '320x320^')
75
- when 'normal'
76
- asset.variant(gravity: 'Center', resize_to_limit: [asset.metadata[:width], asset.metadata[:height]])
77
- when 'icon'
78
- asset.variant(gravity: 'Center', resize: '50x50^')
121
+ style = active_storage_styles[style_name.to_sym]
122
+ return unless style
123
+
124
+ transformations = active_storage_transformations(style[:geometry])
125
+ transformations[:format] = style[:format] if style[:format]
126
+ if asset.variable?
127
+ asset.variant(transformations)
128
+ elsif asset.previewable?
129
+ asset.preview(transformations)
79
130
  end
80
131
  end
81
132
 
82
133
  def style?(style_name = 'original')
83
- style_name == 'original' || paperclip_styles.keys.include?(style_name.to_sym)
134
+ style_name == 'original' || active_storage_styles.keys.include?(style_name.to_sym)
84
135
  end
85
136
 
86
137
  def basename
87
- File.basename(asset_file_name, '.*') if asset_file_name
138
+ File.basename(filename, '.*') if filename
88
139
  end
89
140
 
90
141
  def extension(style_name = 'original')
91
142
  if style_name == 'original'
92
143
  original_extension
93
- elsif style = paperclip_styles[style_name.to_sym]
94
- style.format
144
+ elsif style = active_storage_styles[style_name.to_sym]
145
+ style[:format]
95
146
  else
96
147
  original_extension
97
148
  end
98
149
  end
99
150
 
100
151
  def original_extension
101
- return asset_file_name.split('.').last.downcase if asset_file_name
152
+ return filename.split('.').last.downcase if filename
102
153
  end
103
154
 
104
155
  def attached_to?(page)
@@ -106,12 +157,12 @@ class Asset < ActiveRecord::Base
106
157
  end
107
158
 
108
159
  def original_geometry
109
- @original_geometry ||= Paperclip::Geometry.new(original_width, original_height)
160
+ @original_geometry ||= TrustyCms::Geometry.new(*original_dimensions)
110
161
  end
111
162
 
112
163
  def geometry(style_name = 'original')
113
164
  unless style?(style_name)
114
- raise Paperclip::StyleError,
165
+ raise TrustyCms::StyleError,
115
166
  "Requested style #{style_name} is not defined for this asset."
116
167
  end
117
168
 
@@ -120,11 +171,11 @@ class Asset < ActiveRecord::Base
120
171
  @geometry[style_name] ||= if style_name.to_s == 'original'
121
172
  original_geometry
122
173
  else
123
- style = asset.styles[style_name.to_sym]
124
- original_geometry.transformed_by(style.geometry)
174
+ style = active_storage_styles[style_name.to_sym]
175
+ original_geometry.transformed_by(style[:geometry])
125
176
  # this can return dimensions for fully specified style sizes but not for relative sizes when there are no original dimensions
126
177
  end
127
- rescue Paperclip::TransformationError => e
178
+ rescue TrustyCms::TransformationError => e
128
179
  Rails.logger.warn "geometry transformation error: #{e}"
129
180
  original_geometry # returns a blank geometry if the real geometry cannot be calculated
130
181
  end
@@ -168,26 +219,65 @@ class Asset < ActiveRecord::Base
168
219
  end
169
220
 
170
221
  def dimensions_known?
171
- original_width? && original_height?
222
+ original_dimensions.all?(&:positive?)
172
223
  end
173
224
 
174
225
  private
175
226
 
176
- # at this point the file queue will not have been written
177
- # but the upload should be in place. We read dimensions from the
178
- # original file and calculate thumbnail dimensions later, on demand.
227
+ def original_dimensions
228
+ width = original_width.presence
229
+ height = original_height.presence
230
+ if asset.attached?
231
+ width ||= asset.metadata[:width] || asset.metadata['width']
232
+ height ||= asset.metadata[:height] || asset.metadata['height']
233
+ end
234
+ [width.to_i, height.to_i]
235
+ end
236
+
237
+ def active_storage_transformations(geometry)
238
+ return {} unless geometry.present?
239
+
240
+ parsed = TrustyCms::Geometry.parse(geometry)
241
+ width = parsed.width.positive? ? parsed.width : nil
242
+ height = parsed.height.positive? ? parsed.height : nil
243
+ return {} unless width && height
244
+
245
+ case parsed.modifier
246
+ when '#', '^', '!'
247
+ { resize_to_fill: [width, height].compact }
248
+ when '>', '<'
249
+ { resize_to_limit: [width, height].compact }
250
+ else
251
+ { resize_to_limit: [width, height].compact }
252
+ end
253
+ end
254
+
255
+ def video_content_type?
256
+ AssetType.known?(:video) && AssetType.find(:video).mime_types.include?(content_type)
257
+ end
258
+
259
+ def approved_content_type
260
+ return if Asset.approved_content_types.include?(asset.content_type)
261
+
262
+ errors.add(:asset, :content_type, filename: asset.filename.to_s)
263
+ end
264
+
265
+ def sync_attachment_metadata
266
+ return unless asset.attached?
179
267
 
180
- def read_dimensions
181
- if image? && file = asset.queued_for_write[:original]
182
- geometry = Paperclip::Geometry.from_file(file)
183
- self.original_width = geometry.width
184
- self.original_height = geometry.height
185
- self.original_extension = File.extname(file.path)
268
+ self.asset_file_name = asset.filename.to_s
269
+ self.asset_content_type = asset.content_type
270
+ self.asset_file_size = asset.blob.byte_size
271
+ self.original_extension = asset.filename.extension&.downcase
272
+ if asset.metadata[:width].present? && asset.metadata[:height].present?
273
+ self.original_width = asset.metadata[:width]
274
+ self.original_height = asset.metadata[:height]
186
275
  end
187
- true
188
276
  end
189
277
 
190
278
  def assign_title
279
+ return unless asset.attached?
280
+
191
281
  self.title = asset.filename.base
192
282
  end
193
283
 
@@ -195,6 +285,12 @@ class Asset < ActiveRecord::Base
195
285
  self.uuid = SecureRandom.uuid unless uuid?
196
286
  end
197
287
 
288
+ def rewrite_cloud_url(url)
289
+ return url unless defined?(TrustyCmsClippedExtension::Cloud)
290
+
291
+ TrustyCmsClippedExtension::Cloud.rewrite_url(url)
292
+ end
293
+
198
294
  class << self
199
295
  def known_types
200
296
  AssetType.known_types
@@ -230,7 +326,7 @@ class Asset < ActiveRecord::Base
230
326
 
231
327
  # for backwards compatibility
232
328
  def self.thumbnail_sizes
233
- AssetType.find(:image).paperclip_styles
329
+ AssetType.find(:image).active_storage_styles
234
330
  end
235
331
 
236
332
  def self.thumbnail_names
@@ -3,8 +3,7 @@ class AssetType
3
3
  # Conventionally this would a sensible category like 'image' or 'video'
4
4
  # that should be processed and presented in a particular way.
5
5
  # An AssetType currently provides:
6
- # * processor definitions for paperclip
7
- # * styles definitions for paperclip
6
+ # * processing and variant definitions for ActiveStorage
8
7
  # * mime type list for file recognition
9
8
  # * selectors and scopes for retrieving this (or not this) category of asset
10
9
  # * radius tags for those subsets of assets (temporarily removed pending discussion of interface)
@@ -30,7 +29,7 @@ class AssetType
30
29
  @mimes.each { |mimetype| @@mime_lookup[mimetype] ||= self }
31
30
 
32
31
  this = self
33
- Asset.send :define_method, "#{name}?".intern do this.mime_types.include?(asset_content_type) end
32
+ Asset.send :define_method, "#{name}?".intern do this.mime_types.include?(content_type) end
34
33
  Asset.send :define_class_method, "#{name}_condition".intern do this.condition; end
35
34
  Asset.send :define_class_method, "not_#{name}_condition".intern do this.non_condition; end
36
35
  Asset.send :scope, plural.to_sym, -> { where(conditions: condition) }
@@ -85,27 +84,22 @@ class AssetType
85
84
  @mimes
86
85
  end
87
86
 
88
- def paperclip_processors
89
- TrustyCms.config["assets.create_#{name}_thumbnails?"] ? processors : []
87
+ def processing_enabled?
88
+ TrustyCms.config["assets.create_#{name}_thumbnails?"]
90
89
  end
91
90
 
92
- # Parses and combines the various ways in which paperclip styles can be defined, and normalises them into
93
- # the format that paperclip expects. Note that :styles => :standard has already been replaced with the
91
+ # Parses and combines the various ways in which ActiveStorage styles can be defined, and normalises them into
92
+ # the format that ActiveStorage expects. Note that :styles => :standard has already been replaced with the
94
93
  # results of a call to standard_styles.
95
- # Styles are passed to paperclip as a hash and arbitrary keys can be passed through from configuration.
94
+ # Styles are passed as a hash and arbitrary keys can be passed through from configuration.
96
95
  #
97
- def paperclip_styles
98
- # Styles are not relevant if processors are not defined.
99
- @paperclip_styles ||= if paperclip_processors.any?
100
- normalize_style_rules(configured_styles.merge(styles))
101
- else
102
- {}
103
- end
104
- @paperclip_styles
105
- end
106
-
107
96
  def active_storage_styles
108
- @active_storage_styles ||= normalize_style_rules(configured_styles.merge(styles))
97
+ @active_storage_styles ||= if processing_enabled?
98
+ normalize_style_rules(configured_styles.merge(styles))
99
+ else
100
+ {}
101
+ end
102
+ @active_storage_styles
109
103
  end
110
104
 
111
105
  # Takes a motley collection of differently-defined styles and renders them into the standard hash-of-hashes format.
@@ -128,13 +122,15 @@ class AssetType
128
122
 
129
123
  def standard_styles
130
124
  {
125
+ icon: { geometry: '50x50#', format: :png },
131
126
  thumbnail: { geometry: '100x100#', format: :png },
127
+ original: {},
132
128
  }
133
129
  end
134
130
 
135
- # Paperclip styles are defined in the config entry `assets.thumbnails.asset_type`, with the format:
131
+ # ActiveStorage styles are defined in the config entry `assets.thumbnails.asset_type`, with the format:
136
132
  # foo:key-x,key=y,key=z|bar:key-x,key=y,key=z
137
- # where 'key' can be any parameter understood by your paperclip processors. Usually they include :geometry and :format.
133
+ # where 'key' can be any parameter understood by your variant processor. Usually they include :geometry and :format.
138
134
  # A typical entry would be:
139
135
  #
140
136
  # standard:geometry=640x640>,format=jpg
@@ -153,8 +149,14 @@ class AssetType
153
149
  end
154
150
 
155
151
  def style_dimensions(style_name)
156
- if style = paperclip_styles[style_name.to_sym]
157
- style[:size]
152
+ if style = active_storage_styles[style_name.to_sym]
153
+ style[:geometry]
154
+ end
155
+ end
156
+
157
+ def style_format(style_name)
158
+ if style = active_storage_styles[style_name.to_sym]
159
+ style[:format]
158
160
  end
159
161
  end
160
162
 
@@ -173,8 +175,10 @@ class AssetType
173
175
  # class methods
174
176
 
175
177
  def self.for(attachment)
176
- extension = attachment.record.original_extension
177
- from_extension(extension) || from_mimetype(attachment.content_type) || catchall
178
+ return catchall unless attachment&.attached?
179
+
180
+ extension = attachment.blob&.filename&.extension&.downcase || attachment.record.original_extension
181
+ from_extension(extension) || from_mimetype(attachment.blob&.content_type) || catchall
178
182
  end
179
183
 
180
184
  def self.from_extension(extension)
@@ -1,8 +1,7 @@
1
1
  %ul#search_list
2
2
  - unless @assets.empty?
3
3
  - @assets.each do |asset|
4
- =# render :partial => 'asset', :locals => { :asset => asset, :page => @page }
5
- = render :partial => 'admin/assets/asset', :locals => { :asset_url => asset.asset.url, :asset_id => asset.id, :asset_type => 'image', :asset_title => asset.title, :asset_thumbnail => asset.thumbnail(:thumbnail), :page => @page }
4
+ = render :partial => 'admin/assets/asset', :locals => { :asset_url => asset.public_url, :asset_id => asset.id, :asset_type => 'image', :asset_title => asset.title, :asset_thumbnail => asset.thumbnail(:thumbnail), :page => @page }
6
5
 
7
6
  - else
8
7
  %li
@@ -12,4 +11,4 @@
12
11
  %script
13
12
  Asset.MakeDroppables();
14
13
  Asset.MakeDraggables();
15
- Event.addBehavior({ '.asset a' : Asset.DisableLinks, 'a.add_asset' : Asset.AddToPage });
14
+ Event.addBehavior({ '.asset a' : Asset.DisableLinks, 'a.add_asset' : Asset.AddToPage });
@@ -14,10 +14,10 @@
14
14
  %div.content
15
15
  %fieldset
16
16
  %label.filename
17
- = "#{t("clipped_extension.filename")}: #{@asset.asset_file_name unless @asset.new_record?}"
17
+ = "#{t("clipped_extension.filename")}: #{@asset.filename unless @asset.new_record?}"
18
18
  %br
19
19
  %label.url
20
- = "#{t("clipped_extension.asset_url")}: #{image_path @asset.asset.url unless @asset.new_record?}"
20
+ = "#{t("clipped_extension.asset_url")}: #{@asset.public_url unless @asset.new_record?}"
21
21
  %br
22
22
  %label.id
23
23
  = "#{t("clipped_extension.asset_id")}: #{@asset.id unless @asset.new_record?}"
@@ -7,7 +7,7 @@
7
7
  %table.index#assets{:cellpadding => "0", :cellspacing => "0", :border => "0"}
8
8
  %tbody
9
9
  %tr[@asset]
10
- %td.icon= image_tag @asset.thumbnail(:icon), :title => @asset.asset_file_name
10
+ %td.icon= image_tag @asset.thumbnail(:icon), :title => @asset.filename
11
11
  %td.name= @asset.title
12
12
 
13
13
  = form_for [:admin, @asset], :html => { :method => 'delete' } do
@@ -2,6 +2,7 @@
2
2
  %h3
3
3
  = t('clipped_extension.assets')
4
4
  %p= edit_config 'assets.max_asset_size'
5
+ %p= edit_config 'assets.max_video_size'
5
6
  %p= edit_config 'assets.display_size'
6
7
  %p= edit_config 'assets.insertion_size'
7
8
  - %w{image video pdf}.each do |type|
@@ -2,6 +2,8 @@
2
2
  = t('clipped_extension.assets')
3
3
  %p.ruled
4
4
  = show_config 'assets.max_asset_size'
5
+ %p.ruled
6
+ = show_config 'assets.max_video_size'
5
7
  %p.ruled
6
8
  = show_config 'assets.display_size'
7
9
  %p.ruled
@@ -0,0 +1,30 @@
1
+ #
2
+ # This is only an example configuration. Please see the Rails
3
+ # documentation for more details.
4
+ #
5
+ defaults: &defaults
6
+ adapter: mysql
7
+ db: localhost
8
+
9
+ development:
10
+ adapter: mysql2
11
+ database: trusty_cms_dev
12
+ username: root
13
+ password:
14
+
15
+ test: &TEST
16
+ adapter: mysql2
17
+ database: trusty_cms_test
18
+ username: root
19
+ password: ''
20
+ db: '127.0.0.1'
21
+ port: 0
22
+ encoding: utf8mb4
23
+ charset: utf8mb4
24
+ collation: utf8mb4_bin
25
+
26
+ production:
27
+ adapter: mysql2
28
+ database: trusty_cms_live
29
+ username: root
30
+ password: