trusty-cms 7.0.48 → 7.1.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/Gemfile.lock +1 -1
- data/README.md +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/controllers/admin/assets_controller.rb +1 -12
- data/app/javascript/plugins/asset_tags/asset_tag_builder.js +7 -2
- data/app/models/asset.rb +107 -38
- 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/config/initializers/trusty_cms_config.rb +1 -49
- data/config/locales/en.yml +1 -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/package.json +1 -1
- data/spec/lib/trusty_cms/geometry_spec.rb +28 -0
- data/spec/models/asset_spec.rb +66 -0
- data/vendor/extensions/clipped-extension/clipped_extension.rb +3 -7
- data/vendor/extensions/clipped-extension/lib/asset_tags.rb +10 -4
- data/vendor/extensions/clipped-extension/lib/generators/templates/clipped_config.rb +9 -34
- 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 +731 -727
- metadata +6 -6
- 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
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
module TrustyCms
|
|
2
|
+
class StyleError < StandardError; end
|
|
3
|
+
class TransformationError < StandardError; end
|
|
4
|
+
|
|
5
|
+
class Geometry
|
|
6
|
+
attr_reader :width, :height, :modifier
|
|
7
|
+
|
|
8
|
+
def self.parse(value)
|
|
9
|
+
return value if value.is_a?(Geometry)
|
|
10
|
+
|
|
11
|
+
match = value.to_s.strip.match(/\A(\d*)x(\d*)([%<>#^!@])?\z/)
|
|
12
|
+
raise StyleError, "Unrecognized geometry: #{value.inspect}" unless match
|
|
13
|
+
|
|
14
|
+
width = match[1].to_s.empty? ? 0 : match[1].to_i
|
|
15
|
+
height = match[2].to_s.empty? ? 0 : match[2].to_i
|
|
16
|
+
modifier = match[3]
|
|
17
|
+
new(width, height, modifier)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(width, height = nil, modifier = nil)
|
|
21
|
+
@width = width.to_i
|
|
22
|
+
@height = height.to_i
|
|
23
|
+
@modifier = modifier
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def without_modifier
|
|
27
|
+
Geometry.new(width, height)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def transformed_by(other)
|
|
31
|
+
other = Geometry.parse(other)
|
|
32
|
+
return other.without_modifier if self =~ other || ['#', '!', '^'].include?(other.modifier)
|
|
33
|
+
|
|
34
|
+
raise TransformationError, 'geometry is not transformable without both width and height' if height.zero? || width.zero?
|
|
35
|
+
|
|
36
|
+
case other.modifier
|
|
37
|
+
when '>'
|
|
38
|
+
(other.width < width || other.height < height) ? scaled_to_fit(other) : self
|
|
39
|
+
when '<'
|
|
40
|
+
(other.width > width && other.height > height) ? scaled_to_fit(other) : self
|
|
41
|
+
when '%'
|
|
42
|
+
scaled_by(other)
|
|
43
|
+
when '@'
|
|
44
|
+
scaled_by((other.width * 100).fdiv(width * height))
|
|
45
|
+
else
|
|
46
|
+
scaled_to_fit(other)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
alias * transformed_by
|
|
50
|
+
|
|
51
|
+
def ==(other)
|
|
52
|
+
to_s == other.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def =~(other)
|
|
56
|
+
height.to_i == other.height.to_i && width.to_i == other.width.to_i
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def scaled_to_fit(other)
|
|
60
|
+
if other.width.positive? && other.height.zero?
|
|
61
|
+
Geometry.new(other.width, height * other.width / width)
|
|
62
|
+
elsif other.width.zero? && other.height.positive?
|
|
63
|
+
Geometry.new(width * other.height / height, other.height)
|
|
64
|
+
else
|
|
65
|
+
product_width = other.width * height
|
|
66
|
+
product_height = other.height * width
|
|
67
|
+
if product_width == product_height
|
|
68
|
+
other.without_modifier
|
|
69
|
+
elsif product_width > product_height
|
|
70
|
+
scaled_width = (width * other.height.fdiv(height)).round
|
|
71
|
+
Geometry.new(scaled_width, other.height)
|
|
72
|
+
else
|
|
73
|
+
scaled_height = (height * other.width.fdiv(width)).round
|
|
74
|
+
Geometry.new(other.width, scaled_height)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def scaled_by(other)
|
|
80
|
+
if other.is_a?(Numeric)
|
|
81
|
+
scaled_width = (width * other.fdiv(100)).round
|
|
82
|
+
scaled_height = (height * other.fdiv(100)).round
|
|
83
|
+
return Geometry.new(scaled_width, scaled_height)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
other = Geometry.new("#{other}%") unless other.is_a?(Geometry)
|
|
87
|
+
if other.height.positive?
|
|
88
|
+
Geometry.new(width * other.width / 100, height * other.height / 100)
|
|
89
|
+
else
|
|
90
|
+
Geometry.new(width * other.width / 100, height * other.width / 100)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def aspect
|
|
95
|
+
return nil if width.to_f == 0.0 || height.to_f == 0.0
|
|
96
|
+
|
|
97
|
+
width.to_f / height.to_f
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def square?
|
|
101
|
+
width.to_i == height.to_i
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def vertical?
|
|
105
|
+
height.to_i > width.to_i
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def horizontal?
|
|
109
|
+
width.to_i > height.to_i
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def to_s
|
|
113
|
+
suffix = modifier.to_s
|
|
114
|
+
"#{width}x#{height}#{suffix}"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/trusty_cms/version.rb
CHANGED
data/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe TrustyCms::Geometry do
|
|
4
|
+
describe '.parse' do
|
|
5
|
+
it 'parses basic geometry strings' do
|
|
6
|
+
geom = described_class.parse('100x200')
|
|
7
|
+
expect(geom.width).to eq(100)
|
|
8
|
+
expect(geom.height).to eq(200)
|
|
9
|
+
expect(geom.modifier).to be_nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'parses geometry modifiers' do
|
|
13
|
+
geom = described_class.parse('640x480@')
|
|
14
|
+
expect(geom.width).to eq(640)
|
|
15
|
+
expect(geom.height).to eq(480)
|
|
16
|
+
expect(geom.modifier).to eq('@')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#transformed_by' do
|
|
21
|
+
it 'scales to fit preserving aspect ratio' do
|
|
22
|
+
source = described_class.new(400, 200)
|
|
23
|
+
result = source.transformed_by('100x100')
|
|
24
|
+
expect(result.width).to eq(100)
|
|
25
|
+
expect(result.height).to eq(50)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/spec/models/asset_spec.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'rack/test'
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'stringio'
|
|
3
5
|
|
|
4
6
|
RSpec.describe Asset, type: :model do
|
|
5
7
|
let(:fixtures_path) { TrustyCms::Engine.root.join('spec', 'fixtures', 'files') }
|
|
@@ -36,4 +38,68 @@ RSpec.describe Asset, type: :model do
|
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
end
|
|
41
|
+
describe 'active storage metadata' do
|
|
42
|
+
before do
|
|
43
|
+
AssetType.new :image, :styles => :standard, :extensions => %w[png], :mime_types => %w[image/png] unless AssetType.known?(:image)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
let(:png_data) do
|
|
47
|
+
Base64.decode64('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def png_io
|
|
51
|
+
io = StringIO.new(png_data)
|
|
52
|
+
io.set_encoding(Encoding::BINARY)
|
|
53
|
+
io.rewind
|
|
54
|
+
io
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'exposes filename, content type, and size from the attachment' do
|
|
58
|
+
asset = described_class.new(caption: '')
|
|
59
|
+
asset.asset.attach(io: png_io, filename: 'pixel.png', content_type: 'image/png')
|
|
60
|
+
asset.save!
|
|
61
|
+
|
|
62
|
+
expect(asset.filename).to eq('pixel.png')
|
|
63
|
+
expect(asset.content_type).to eq('image/png')
|
|
64
|
+
expect(asset.byte_size).to eq(png_data.bytesize)
|
|
65
|
+
expect(asset.original_extension).to eq('png')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'reports styles and extensions from active storage styles' do
|
|
69
|
+
asset = described_class.new(caption: '')
|
|
70
|
+
asset.asset.attach(io: png_io, filename: 'pixel.png', content_type: 'image/png')
|
|
71
|
+
asset.save!
|
|
72
|
+
|
|
73
|
+
expect(asset.style?('thumbnail')).to be(true)
|
|
74
|
+
expect(asset.extension('thumbnail').to_s).to eq('png')
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe 'thumbnails' do
|
|
79
|
+
before do
|
|
80
|
+
AssetType.new :image, :styles => :standard, :extensions => %w[png], :mime_types => %w[image/png] unless AssetType.known?(:image)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
let(:png_data) do
|
|
84
|
+
Base64.decode64('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==')
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def png_io
|
|
88
|
+
io = StringIO.new(png_data)
|
|
89
|
+
io.set_encoding(Encoding::BINARY)
|
|
90
|
+
io.rewind
|
|
91
|
+
io
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'returns a variant url for known styles' do
|
|
95
|
+
asset = described_class.new(caption: '')
|
|
96
|
+
asset.asset.attach(io: png_io, filename: 'pixel.png', content_type: 'image/png')
|
|
97
|
+
asset.save!
|
|
98
|
+
|
|
99
|
+
variant = instance_double(ActiveStorage::Variant, processed: instance_double(ActiveStorage::Variant, url: '/rails/active_storage/variant/test'))
|
|
100
|
+
allow(asset).to receive(:asset_variant).with('thumbnail').and_return(variant)
|
|
101
|
+
|
|
102
|
+
expect(asset.thumbnail('thumbnail')).to eq('/rails/active_storage/variant/test')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
39
105
|
end
|
|
@@ -9,10 +9,10 @@ class ClippedExtension < TrustyCms::Extension
|
|
|
9
9
|
TrustyCms::AdminUI.send :include, ClippedAdminUI unless defined? admin.asset # defines shards for extension of the asset-admin interface
|
|
10
10
|
Admin::PagesController.send :helper, Admin::AssetsHelper # currently only provides a description of asset sizes
|
|
11
11
|
Page.send :include, AssetTags # radius tags for selecting sets of assets and presenting each one
|
|
12
|
-
AssetType.new :image, :icon => 'image', :default_radius_tag => 'image', :
|
|
13
|
-
AssetType.new :video, :icon => 'video', :
|
|
12
|
+
AssetType.new :image, :icon => 'image', :default_radius_tag => 'image', :styles => :standard, :extensions => %w[jpg jpeg png gif], :mime_types => %w[image/png image/x-png image/jpeg image/pjpeg image/jpg image/gif]
|
|
13
|
+
AssetType.new :video, :icon => 'video', :styles => :standard, :mime_types => %w[application/x-mp4 video/mpeg video/quicktime video/x-la-asf video/x-ms-asf video/x-msvideo video/x-sgi-movie video/x-flv flv-application/octet-stream video/3gpp video/3gpp2 video/3gpp-tt video/BMPEG video/BT656 video/CelB video/DV video/H261 video/H263 video/H263-1998 video/H263-2000 video/H264 video/JPEG video/MJ2 video/MP1S video/MP2P video/MP2T video/mp4 video/MP4V-ES video/MPV video/mpeg4 video/mpeg4-generic video/nv video/parityfec video/pointer video/raw video/rtx video/ogg video/webm]
|
|
14
14
|
AssetType.new :audio, :icon => 'audio', :mime_types => %w[audio/mpeg audio/mpg audio/ogg application/ogg audio/x-ms-wma audio/vnd.rn-realaudio audio/x-wav]
|
|
15
|
-
AssetType.new :pdf, :icon => 'pdf', :
|
|
15
|
+
AssetType.new :pdf, :icon => 'pdf', :extensions => %w{pdf}, :mime_types => %w[application/pdf application/x-pdf], :styles => :standard
|
|
16
16
|
AssetType.new :document, :icon => 'document', :mime_types => %w[application/msword application/rtf application/vnd.ms-excel application/vnd.ms-powerpoint application/vnd.ms-project application/vnd.ms-works text/plain text/html]
|
|
17
17
|
AssetType.new :other, :icon => 'unknown'
|
|
18
18
|
|
|
@@ -23,10 +23,6 @@ class ClippedExtension < TrustyCms::Extension
|
|
|
23
23
|
admin.configuration.show.add :trusty_config, 'admin/configuration/clipped_show', :after => 'defaults'
|
|
24
24
|
admin.configuration.edit.add :form, 'admin/configuration/clipped_edit', :after => 'edit_defaults'
|
|
25
25
|
|
|
26
|
-
if TrustyCms::Config.table_exists? && TrustyCms::config["paperclip.command_path"] # This is needed for testing if you are using mod_rails
|
|
27
|
-
Paperclip.options[:command_path] = TrustyCms::config["paperclip.command_path"]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
26
|
tab "Assets", :after => "Content" do
|
|
31
27
|
add_item "All", "/admin/assets"
|
|
32
28
|
end
|
|
@@ -181,17 +181,24 @@ module AssetTags
|
|
|
181
181
|
options = tag.attr.dup
|
|
182
182
|
# XXX build_regexp_for comes from StandardTags
|
|
183
183
|
regexp = build_regexp_for(tag, options)
|
|
184
|
-
asset_content_type = tag.locals.asset.
|
|
184
|
+
asset_content_type = tag.locals.asset.content_type
|
|
185
185
|
tag.expand unless asset_content_type.match(regexp).nil?
|
|
186
186
|
end
|
|
187
187
|
|
|
188
|
+
attribute_mappings = {
|
|
189
|
+
asset_file_name: :filename,
|
|
190
|
+
asset_content_type: :content_type,
|
|
191
|
+
asset_file_size: :byte_size,
|
|
192
|
+
}
|
|
193
|
+
|
|
188
194
|
[:title, :caption, :asset_file_name, :extension, :asset_content_type, :asset_file_size, :id].each do |method|
|
|
189
195
|
desc %{
|
|
190
196
|
Renders the @#{method.to_s}@ attribute of the asset
|
|
191
197
|
}
|
|
192
198
|
tag "asset:#{method.to_s}" do |tag|
|
|
193
199
|
asset, options = asset_and_options(tag)
|
|
194
|
-
|
|
200
|
+
mapped = attribute_mappings.fetch(method, method)
|
|
201
|
+
asset.send(mapped) rescue nil
|
|
195
202
|
end
|
|
196
203
|
end
|
|
197
204
|
|
|
@@ -201,7 +208,7 @@ module AssetTags
|
|
|
201
208
|
|
|
202
209
|
tag 'asset:filename' do |tag|
|
|
203
210
|
asset, options = asset_and_options(tag)
|
|
204
|
-
asset.
|
|
211
|
+
asset.filename rescue nil
|
|
205
212
|
end
|
|
206
213
|
|
|
207
214
|
desc %{
|
|
@@ -308,4 +315,3 @@ module AssetTags
|
|
|
308
315
|
}
|
|
309
316
|
end
|
|
310
317
|
end
|
|
311
|
-
|
|
@@ -3,10 +3,6 @@ TrustyCms.config do |config|
|
|
|
3
3
|
# Uncomment and change the settings below to customize the Clipped extension
|
|
4
4
|
|
|
5
5
|
# The default settings
|
|
6
|
-
# config["paperclip.url"] = "/system/:attachment/:id/:style/:basename:no_original_style.:extension"
|
|
7
|
-
# config["paperclip.path"] = ":rails_root/public/system/:attachment/:id/:style/:basename:no_original_style.:extension"
|
|
8
|
-
# config["paperclip.storage"] = "filesystem"
|
|
9
|
-
# config["paperclip.skip_filetype_validation"] = true
|
|
10
6
|
# config["assets.max_asset_size"] = 5 # megabytes
|
|
11
7
|
# config["assets.display_size"] = "normal"
|
|
12
8
|
# config["assets.insertion_size"] = "normal"
|
|
@@ -19,35 +15,14 @@ TrustyCms.config do |config|
|
|
|
19
15
|
# config["assets.thumbnails.video"] = "normal:size=640x640>,format=jpg|small:size=320x320>,format=jpg"
|
|
20
16
|
# config["assets.thumbnails.pdf"] = "normal:size=640x640>,format=jpg|small:size=320x320>,format=jpg"
|
|
21
17
|
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# config["
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# config["paperclip.fog.host"] = "http://assets.example.com"
|
|
32
|
-
# optionally set the S3 region of your bucket; defaults to US East
|
|
33
|
-
# Asia North East => ap-northeast-1
|
|
34
|
-
# Asia South East => ap-southeast-1
|
|
35
|
-
# EU West => eu-west-1
|
|
36
|
-
# US East => us-east-1
|
|
37
|
-
# US West => us-west-1
|
|
38
|
-
# config["paperclip.s3.region"] = "us-east-1"
|
|
39
|
-
|
|
40
|
-
# An example of using Rackspace Cloud Files
|
|
41
|
-
# add `gem "fog", "~> 1.0"` to your Gemfile and run `bundle install`
|
|
42
|
-
# config["paperclip.storage"] = "fog"
|
|
43
|
-
# config["paperclip.path"] = ":attachment/:id/:style/:basename:no_original_style.:extension"
|
|
44
|
-
# config["paperclip.fog.provider"] = "Rackspace"
|
|
45
|
-
# config["paperclip.fog.directory"] = "container-name"
|
|
46
|
-
# config["paperclip.rackspace.username"] = "RACKSPACE_USERNAME"
|
|
47
|
-
# config["paperclip.rackspace.api_key"] = "RACKSPACE_API_KEY"
|
|
48
|
-
# paperclip.fog.host is your Cloud Files CDN URL
|
|
49
|
-
# config["paperclip.fog.host"] = "http://a.b.c.rackcdn.com"
|
|
50
|
-
# optionally use a custom domain name; requires a CNAME DNS record
|
|
51
|
-
# config["paperclip.fog.host"] = "http://assets.example.com"
|
|
18
|
+
# ActiveStorage configuration is handled in config/storage.yml and
|
|
19
|
+
# config.active_storage.service (per environment). For S3 or other
|
|
20
|
+
# cloud providers, configure the appropriate ActiveStorage service.
|
|
21
|
+
#
|
|
22
|
+
# Optional CDN host override for ActiveStorage URLs:
|
|
23
|
+
# config["assets.cdn.host"] = "https://assets.example.com"
|
|
24
|
+
#
|
|
25
|
+
# Or provide a dynamic host in an initializer:
|
|
26
|
+
# TrustyCmsClippedExtension::Cloud.host_provider = -> { AssetBucket.current&.asset_host }
|
|
52
27
|
|
|
53
28
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
def obtain_class
|
|
2
|
+
class_name = ENV['CLASS'] || ENV['class']
|
|
3
|
+
raise "Must specify CLASS" unless class_name
|
|
4
|
+
Object.const_get(class_name)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def obtain_attachments(klass)
|
|
8
|
+
name = ENV['ATTACHMENT'] || ENV['attachment']
|
|
9
|
+
attachment_names = if klass.respond_to?(:reflect_on_all_attachments)
|
|
10
|
+
klass.reflect_on_all_attachments.map(&:name)
|
|
11
|
+
else
|
|
12
|
+
[]
|
|
13
|
+
end
|
|
14
|
+
raise "Class #{klass.name} has no ActiveStorage attachments" if attachment_names.empty?
|
|
15
|
+
if name.present? && attachment_names.include?(name.to_sym)
|
|
16
|
+
[name.to_sym]
|
|
17
|
+
else
|
|
18
|
+
attachment_names
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def for_all_attachments
|
|
23
|
+
klass = obtain_class
|
|
24
|
+
names = obtain_attachments(klass)
|
|
25
|
+
|
|
26
|
+
klass.find_each do |instance|
|
|
27
|
+
names.each do |name|
|
|
28
|
+
attachment = instance.public_send(name)
|
|
29
|
+
result = if attachment.attached?
|
|
30
|
+
yield(instance, name, attachment)
|
|
31
|
+
else
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
print result ? "." : "x"; $stdout.flush
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
puts " Done."
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
namespace :active_storage do
|
|
41
|
+
desc "Refreshes both metadata and variants."
|
|
42
|
+
task :refresh => ["active_storage:refresh:metadata", "active_storage:refresh:variants"]
|
|
43
|
+
|
|
44
|
+
namespace :refresh do
|
|
45
|
+
desc "Regenerates variants for a given CLASS (and optional ATTACHMENT)."
|
|
46
|
+
task :variants => :environment do
|
|
47
|
+
for_all_attachments do |instance, name, attachment|
|
|
48
|
+
if instance.respond_to?(:refresh_variants!) && name == :asset
|
|
49
|
+
instance.refresh_variants!
|
|
50
|
+
else
|
|
51
|
+
attachment.preview if attachment.previewable?
|
|
52
|
+
end
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc "Re-analyzes metadata for a given CLASS (and optional ATTACHMENT)."
|
|
58
|
+
task :metadata => :environment do
|
|
59
|
+
for_all_attachments do |instance, name, attachment|
|
|
60
|
+
attachment.analyze unless attachment.analyzed?
|
|
61
|
+
instance.save(validate: false)
|
|
62
|
+
true
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -52,8 +52,11 @@ namespace :trusty do
|
|
|
52
52
|
asset_path = File.join(Rails.root, "assets")
|
|
53
53
|
mkdir_p asset_path
|
|
54
54
|
Asset.find(:all).each do |asset|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
next unless asset.asset.attached?
|
|
56
|
+
puts "Exporting #{asset.filename}"
|
|
57
|
+
asset.asset.open do |file|
|
|
58
|
+
cp file.path, File.join(asset_path, asset.filename)
|
|
59
|
+
end
|
|
57
60
|
end
|
|
58
61
|
puts "Done."
|
|
59
62
|
end
|
|
@@ -1,41 +1,46 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
1
3
|
module TrustyCmsClippedExtension
|
|
2
4
|
|
|
3
5
|
module Cloud
|
|
6
|
+
mattr_accessor :host_provider
|
|
4
7
|
|
|
5
8
|
def self.credentials
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
:aws_access_key_id => TrustyCms.config["paperclip.s3.key"],
|
|
11
|
-
:aws_secret_access_key => TrustyCms.config["paperclip.s3.secret"],
|
|
12
|
-
:region => TrustyCms.config["paperclip.s3.region"],
|
|
13
|
-
}
|
|
14
|
-
when "Google"
|
|
15
|
-
{
|
|
16
|
-
:provider => "Google",
|
|
17
|
-
:rackspace_username => TrustyCms.config["paperclip.google_storage.access_key_id"],
|
|
18
|
-
:rackspace_api_key => TrustyCms.config["paperclip.google_storage.secret_access_key"]
|
|
19
|
-
}
|
|
20
|
-
when "Rackspace"
|
|
21
|
-
{
|
|
22
|
-
:provider => "Rackspace",
|
|
23
|
-
:rackspace_username => TrustyCms.config["paperclip.rackspace.username"],
|
|
24
|
-
:rackspace_api_key => TrustyCms.config["paperclip.rackspace.api_key"]
|
|
25
|
-
}
|
|
26
|
-
end
|
|
9
|
+
service = ActiveStorage::Blob.service
|
|
10
|
+
return {} unless service.respond_to?(:config)
|
|
11
|
+
|
|
12
|
+
service.config
|
|
27
13
|
end
|
|
28
14
|
|
|
29
15
|
def self.host
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
else
|
|
35
|
-
nil
|
|
16
|
+
if host_provider
|
|
17
|
+
host_provider.call
|
|
18
|
+
elsif defined?(TrustyCms::Config)
|
|
19
|
+
TrustyCms::Config['assets.cdn.host']
|
|
36
20
|
end
|
|
37
21
|
end
|
|
38
22
|
|
|
23
|
+
def self.rewrite_url(url)
|
|
24
|
+
return url unless url.present?
|
|
25
|
+
configured_host = host
|
|
26
|
+
return url if configured_host.blank?
|
|
27
|
+
|
|
28
|
+
uri = URI.parse(url)
|
|
29
|
+
return url unless uri.is_a?(URI::HTTP)
|
|
30
|
+
|
|
31
|
+
host_uri = URI.parse(configured_host.to_s.match?(/\Ahttps?:\/\//) ? configured_host.to_s : "https://#{configured_host}")
|
|
32
|
+
uri.scheme = host_uri.scheme if host_uri.scheme
|
|
33
|
+
uri.host = host_uri.host if host_uri.host
|
|
34
|
+
uri.port = host_uri.port if host_uri.port
|
|
35
|
+
|
|
36
|
+
if host_uri.path.present? && host_uri.path != '/'
|
|
37
|
+
uri.path = File.join(host_uri.path, uri.path.sub(%r{\A/}, ''))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
uri.to_s
|
|
41
|
+
rescue URI::InvalidURIError
|
|
42
|
+
url
|
|
43
|
+
end
|
|
39
44
|
end
|
|
40
45
|
|
|
41
46
|
end
|