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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/assets/builds/trusty_cms/ckeditor5.css +459 -81
- data/app/assets/builds/trusty_cms/ckeditor5.css.map +3 -3
- data/app/assets/builds/trusty_cms/ckeditor5.js +11247 -7722
- data/app/assets/builds/trusty_cms/ckeditor5.js.map +4 -4
- data/app/assets/stylesheets/admin/assets.scss +5 -0
- data/app/controllers/admin/assets_controller.rb +7 -14
- data/app/javascript/plugins/asset_tags/asset_tag_builder.js +7 -2
- data/app/models/asset.rb +144 -48
- data/app/models/asset_type.rb +29 -25
- data/app/views/admin/assets/_search_results.html.haml +2 -3
- data/app/views/admin/assets/edit.html.haml +2 -2
- data/app/views/admin/assets/remove.html.haml +1 -1
- data/app/views/admin/configuration/_clipped_edit.html.haml +1 -0
- data/app/views/admin/configuration/_clipped_show.html.haml +2 -0
- data/config/database.yml +30 -0
- data/config/initializers/trusty_cms_config.rb +3 -50
- data/config/locales/en.yml +6 -1
- data/config/routes.rb +0 -2
- data/db/migrate/20110606111250_update_configuration.rb +0 -16
- data/lib/trusty_cms/geometry.rb +117 -0
- data/lib/trusty_cms/version.rb +1 -1
- data/spec/dummy/log/development.log +345 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/dummy/tmp/cache/747/A70/TrustyCms%3A%3AConfig +0 -0
- data/spec/dummy/tmp/cache/85C/FA0/TrustyCms.cache_mtime +0 -0
- data/spec/dummy/tmp/local_secret.txt +1 -0
- data/spec/dummy/tmp/trusty_config_cache.txt +0 -0
- data/spec/lib/trusty_cms/geometry_spec.rb +28 -0
- data/spec/models/asset_spec.rb +235 -12
- data/trusty_cms.gemspec +1 -1
- data/vendor/extensions/clipped-extension/clipped_extension.rb +4 -9
- data/vendor/extensions/clipped-extension/lib/asset_tags.rb +10 -4
- data/vendor/extensions/clipped-extension/lib/generators/templates/clipped_config.rb +11 -35
- data/vendor/extensions/clipped-extension/lib/tasks/active_storage_tasks.rake +66 -0
- data/vendor/extensions/clipped-extension/lib/tasks/clipped_extension_tasks.rake +5 -2
- data/vendor/extensions/clipped-extension/lib/trusty_cms_clipped_extension/cloud.rb +32 -27
- data/yarn.lock +9 -9
- metadata +21 -8
- data/lib/trusty_cms/deprecation.rb +0 -15
- data/vendor/extensions/clipped-extension/lib/paperclip/frame_grab.rb +0 -73
- data/vendor/extensions/clipped-extension/lib/paperclip/geometry_transformation.rb +0 -80
- data/vendor/extensions/clipped-extension/lib/tasks/paperclip_tasks.rake +0 -79
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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 = '
|
|
55
|
-
return asset.url if
|
|
56
|
-
|
|
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(
|
|
66
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
asset.variant(
|
|
77
|
-
|
|
78
|
-
asset.
|
|
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' ||
|
|
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(
|
|
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 =
|
|
94
|
-
style
|
|
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
|
|
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 ||=
|
|
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
|
|
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 =
|
|
124
|
-
original_geometry.transformed_by(style
|
|
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
|
|
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
|
-
|
|
222
|
+
original_dimensions.all?(&:positive?)
|
|
172
223
|
end
|
|
173
224
|
|
|
174
225
|
private
|
|
175
226
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
self.
|
|
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).
|
|
329
|
+
AssetType.find(:image).active_storage_styles
|
|
234
330
|
end
|
|
235
331
|
|
|
236
332
|
def self.thumbnail_names
|
data/app/models/asset_type.rb
CHANGED
|
@@ -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
|
-
# *
|
|
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?(
|
|
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
|
|
89
|
-
TrustyCms.config["assets.create_#{name}_thumbnails?"]
|
|
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
|
|
93
|
-
# the format that
|
|
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
|
|
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 ||=
|
|
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
|
-
#
|
|
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
|
|
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 =
|
|
157
|
-
style[:
|
|
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
|
-
|
|
177
|
-
|
|
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
|
-
|
|
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.
|
|
17
|
+
= "#{t("clipped_extension.filename")}: #{@asset.filename unless @asset.new_record?}"
|
|
18
18
|
%br
|
|
19
19
|
%label.url
|
|
20
|
-
= "#{t("clipped_extension.asset_url")}: #{
|
|
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.
|
|
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
|
data/config/database.yml
ADDED
|
@@ -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:
|