effective_assets 1.11.5 → 1.12.2

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
  SHA256:
3
- metadata.gz: 707e5ea1b01c0563aa8331e9fc33f374a455cbbd96da811cc1e760550018a3de
4
- data.tar.gz: 81b9a2f560e72c9a1000bc4b0f5838ab73a91a2f2b4994c6307958bd5c44250c
3
+ metadata.gz: 8fc2ceb913a834e2d5a6c163e8aeccac4fd57f116239b59f1956c51c3a90053a
4
+ data.tar.gz: 6f24ae8f628864f2da0ab6ef66fb3cd9737c99fc3769c11c02e3aa9b7977a1bf
5
5
  SHA512:
6
- metadata.gz: b817d4c9c537d44ed1b6533d9ae26e0965a2e0ac2067e9579df56a348a66e6d41d48b5c6bfec9b71e11c54cadb97214cf36d9ee563a4d9c94bbb711385d3c9f3
7
- data.tar.gz: c278a7b17cc5723a67a0799b3812239632a8a8ef2422a705e3bca6f4ff34433a6a80517ae03e60e8b2e7b4bcd19b16130bdc529294d6f5b2b24d20dbccb5b1ee
6
+ metadata.gz: 4fc658672d3da2b57f573d3c3558d68028df4924e8982c8ac068d5dabddefaa5cd87942afeffbc95a2b7930310b23e8adac8eb21226cb29cba60b7fdafb008cf
7
+ data.tar.gz: b9690fd04a64c874d37d34453776ef065293461eb67b01ad1fa4019275151ab73c15973376425e36d370df898d21cea2d8e348fad7289524e0715bc520337d54
@@ -0,0 +1,17 @@
1
+ module Effective
2
+ class AssetReplacerJob < ::ApplicationJob
3
+
4
+ queue_as :default
5
+
6
+ if defined?(Sidekiq)
7
+ # The retry setting works. But none of these waits seem to. Still getting exponential backoff.
8
+ sidekiq_options retry: 2, retry_in: 10, wait: 10
9
+ sidekiq_retry_in { |count, exception| 10 }
10
+ end
11
+
12
+ def perform(attachment, box)
13
+ Effective::AssetReplacer.new.replace_attachment!(attachment, box)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Effective
2
+ class SnippetReplacerJob < ::ApplicationJob
3
+
4
+ queue_as :default
5
+
6
+ if defined?(Sidekiq)
7
+ # The retry setting works. But none of these waits seem to. Still getting exponential backoff.
8
+ sidekiq_options retry: 2, retry_in: 10, wait: 10
9
+ sidekiq_retry_in { |count, exception| 10 }
10
+ end
11
+
12
+ def perform(region)
13
+ Effective::SnippetReplacer.new.replace_region!(region)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,157 @@
1
+ # Looks at the Effective::Asset and Effective::Attachments and converts to ActiveStorage
2
+ #
3
+ # 1. Put in the has_attached_files to each model to be upgraded
4
+ # 2. Remove the acts_as_asset_box
5
+
6
+ require 'timeout'
7
+ require 'cgi'
8
+
9
+ module Effective
10
+ class AssetReplacer
11
+ include ActiveStorage::Blob::Analyzable
12
+
13
+ BATCH_SIZE = 500
14
+ TIMEOUT = 120
15
+
16
+ def replace!(skip_existing: false)
17
+ verify!
18
+
19
+ attachments = attachments_to_process().to_a
20
+
21
+ while(true)
22
+ wait_for_active_job!
23
+
24
+ puts "\nEnqueuing #{attachments.length} attachments with ids #{attachments.first.id} to #{attachments.last.id}"
25
+
26
+ attachments.each do |attachment|
27
+ asset = attachment.asset
28
+ attachable = attachment.attachable
29
+ next if asset.blank? || attachable.blank?
30
+
31
+ box = attachment.box.singularize
32
+ boxes = attachment.box
33
+
34
+ one = attachable.respond_to?(box) && attachable.send(box).kind_of?(ActiveStorage::Attached::One)
35
+ many = attachable.respond_to?(boxes) && attachable.send(boxes).kind_of?(ActiveStorage::Attached::Many)
36
+ box = (one ? box : boxes)
37
+
38
+ if skip_existing
39
+ existing = Array(attachable.send(box))
40
+
41
+ if existing.any? { |obj| obj.respond_to?(:filename) && obj.filename.to_s == asset.file_name }
42
+ puts("Skipping existing #{attachable.class.name} #{attachable.id} #{box} #{asset.file_name}.")
43
+ next
44
+ end
45
+ end
46
+
47
+ Effective::AssetReplacerJob.perform_later(attachment, box)
48
+ end
49
+
50
+ attachments = attachments_to_process().where.not(id: attachments.map(&:id))
51
+ break if attachments.to_a.blank?
52
+
53
+ GC.start
54
+ end
55
+
56
+ puts "\nAll Done. Have a great day."
57
+ true
58
+ end
59
+
60
+ # This is called on the background by the AssetReplacerJob
61
+ def replace_attachment!(attachment, box)
62
+ raise('expected an Effective::Attachment') unless attachment.kind_of?(Effective::Attachment)
63
+ puts("Processing attachment ##{attachment.id}")
64
+
65
+ asset = attachment.asset
66
+ attachable = attachment.attachable
67
+
68
+ attachable.replacing_asset = true if attachable.respond_to?(:replacing_asset=)
69
+
70
+ Timeout.timeout(TIMEOUT) do
71
+ attachable.send(box).attach(
72
+ io: URI.open(asset.url),
73
+ filename: CGI.unescape(asset.file_name.to_s),
74
+ content_type: asset.content_type.presence,
75
+ identify: (asset.content_type.blank?)
76
+ )
77
+
78
+ attachment.update_column(:replaced, true)
79
+ end
80
+
81
+ true
82
+ end
83
+
84
+ def verify!
85
+ raise('expected effective assets') unless defined?(Effective::Asset)
86
+ raise('expected active storage') unless defined?(ActiveStorage)
87
+
88
+ unless Effective::Attachment.new.respond_to?(:replaced?)
89
+ raise('please add a replaced boolean to Effective::Attachment. add_column :attachments, :replaced, :boolean')
90
+ end
91
+
92
+ (Effective::Attachment.all.pluck(:attachable_type, :box).uniq).each do |name, boxes|
93
+ next if name.blank? || boxes.blank?
94
+
95
+ box = boxes.singularize
96
+
97
+ klass = name.safe_constantize
98
+ raise("invalid class #{klass}") unless klass.present?
99
+
100
+ instance = klass.new
101
+
102
+ if instance.respond_to?(:effective_assets)
103
+ raise("please remove acts_as_asset_box() from #{klass.name}")
104
+ end
105
+
106
+ unless instance.respond_to?(box) || instance.respond_to?(boxes)
107
+ raise("expected #{klass.name} to has_one_attached :#{box} or has_many_attached :#{boxes}")
108
+ end
109
+
110
+ one = instance.respond_to?(box) && instance.send(box).kind_of?(ActiveStorage::Attached::One)
111
+ many = instance.respond_to?(boxes) && instance.send(boxes).kind_of?(ActiveStorage::Attached::Many)
112
+
113
+ unless one.present? || many.present?
114
+ raise("expected #{klass.name} to has_one_attached :#{box} or has_many_attached :#{boxes}")
115
+ end
116
+ end
117
+
118
+ puts 'All attachment classes verified.'
119
+
120
+ true
121
+ end
122
+
123
+ def reset!
124
+ Effective::Attachment.update_all(replaced: false)
125
+ end
126
+
127
+ private
128
+
129
+ def wait_for_active_job!
130
+ while(true)
131
+ if(jobs = enqueued_jobs_count) > (BATCH_SIZE / 10)
132
+ print '.'; sleep(3)
133
+ else
134
+ break
135
+ end
136
+ end
137
+ end
138
+
139
+ # The last BATCH_SIZE attachments
140
+ def attachments_to_process
141
+ Effective::Attachment.all
142
+ .includes(:asset)
143
+ .where(replaced: [nil, false])
144
+ .reorder(id: :desc)
145
+ .limit(BATCH_SIZE)
146
+ end
147
+
148
+ def enqueued_jobs_count
149
+ if Rails.application.config.active_job.queue_adapter == :sidekiq
150
+ Sidekiq::Stats.new.enqueued.to_i
151
+ else
152
+ ActiveJob::Base.queue_adapter.enqueued_jobs.count
153
+ end
154
+ end
155
+
156
+ end
157
+ end
@@ -0,0 +1,67 @@
1
+ # Replaces the [snippet_x] in all effective regions with static content
2
+
3
+ module Effective
4
+ class SnippetReplacer
5
+ include ActiveStorage::Blob::Analyzable
6
+ include ActionView::Helpers::UrlHelper
7
+ include ActionView::Helpers::AssetTagHelper
8
+
9
+ def replace!
10
+ raise('expected effective regions') unless defined?(Effective::Region)
11
+ raise('expected effective assets') unless defined?(Effective::Asset)
12
+ raise('expected active storage') unless defined?(ActiveStorage)
13
+
14
+ Effective::Region.with_snippets.find_each do |region|
15
+ Effective::SnippetReplacerJob.perform_later(region)
16
+ end
17
+
18
+ puts 'All Done. Background jobs are running. Have a great day.'
19
+ true
20
+ end
21
+
22
+ def replace_region!(region)
23
+ region.snippet_objects.each do |snippet|
24
+ print('.')
25
+
26
+ begin
27
+ case snippet.class.name
28
+ when 'Effective::Snippets::EffectiveAsset'
29
+ replace_effective_asset(region, snippet)
30
+ else
31
+ raise("unsupported snippet: #{snippet.class.name}")
32
+ end
33
+ rescue => e
34
+ puts "\nError: #{e}\n"
35
+ remove_snippet(region, snippet)
36
+ end
37
+ end
38
+
39
+ region.save!
40
+ end
41
+
42
+ def replace_effective_asset(region, snippet)
43
+ asset = snippet.asset
44
+ raise("Effective:Asset id=#{snippet.asset_id || 'none'} does not exist") unless asset.present?
45
+
46
+ blob = ActiveStorage::Blob.create_and_upload!(io: URI.open(asset.url), filename: asset.file_name)
47
+ url = Rails.application.routes.url_helpers.rails_blob_url(blob, only_path: true)
48
+
49
+ content = if asset.image?
50
+ image_tag(url, class: snippet.html_class, alt: snippet.link_title)
51
+ else
52
+ link_to(snippet.link_title, url, class: snippet.html_class, title: snippet.link_title)
53
+ end
54
+
55
+ region.content.sub!("[#{snippet.id}]", content.to_s)
56
+ region.snippets.delete(snippet.id)
57
+
58
+ true
59
+ end
60
+
61
+ def remove_snippet(region, snippet)
62
+ region.content.sub!("[#{snippet.id}]", '')
63
+ region.snippets.delete(snippet.id)
64
+ end
65
+
66
+ end
67
+ end
@@ -8,14 +8,18 @@ module EffectiveAssets
8
8
 
9
9
  # Include acts_as_addressable concern and allow any ActiveRecord object to call it
10
10
  initializer 'effective_assets.active_record' do |app|
11
- ActiveSupport.on_load :active_record do
12
- ActiveRecord::Base.extend(ActsAsAssetBox::ActiveRecord)
11
+ app.config.to_prepare do
12
+ ActiveSupport.on_load :active_record do
13
+ ActiveRecord::Base.extend(ActsAsAssetBox::ActiveRecord)
14
+ end
13
15
  end
14
16
  end
15
17
 
16
18
  initializer 'effective_assets.action_view' do |app|
17
- ActiveSupport.on_load :action_view do
18
- ActionView::Helpers::FormBuilder.send(:include, AssetBoxFormInput)
19
+ app.config.to_prepare do
20
+ ActiveSupport.on_load :action_view do
21
+ ActionView::Helpers::FormBuilder.send(:include, AssetBoxFormInput)
22
+ end
19
23
  end
20
24
  end
21
25
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveAssets
2
- VERSION = '1.11.5'.freeze
2
+ VERSION = '1.12.2'.freeze
3
3
  end
@@ -0,0 +1,5 @@
1
+ # bundle exec rake replace_effective_assets
2
+ desc 'Replaces effective_assets with ActiveStorage'
3
+ task :replace_effective_assets => :environment do
4
+ Effective::AssetReplacer.new.replace!
5
+ end
@@ -0,0 +1,5 @@
1
+ # bundle exec rake replace_effective_snippets
2
+ desc 'Replaces effective_assets snippets with ActiveStorage uploads'
3
+ task :replace_effective_snippets => :environment do
4
+ Effective::SnippetReplacer.new.replace!
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.5
4
+ version: 1.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-22 00:00:00.000000000 Z
11
+ date: 2022-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -165,14 +165,17 @@ files:
165
165
  - app/controllers/effective/s3_uploads_controller.rb
166
166
  - app/helpers/effective_assets_helper.rb
167
167
  - app/helpers/effective_assets_s3_helper.rb
168
+ - app/jobs/effective/asset_replacer_job.rb
168
169
  - app/jobs/effective/process_with_active_job.rb
169
170
  - app/jobs/effective/process_with_sucker_punch_job.rb
171
+ - app/jobs/effective/snippet_replacer_job.rb
170
172
  - app/models/concerns/acts_as_asset_box.rb
171
173
  - app/models/effective/access_denied.rb
172
174
  - app/models/effective/asset.rb
175
+ - app/models/effective/asset_replacer.rb
173
176
  - app/models/effective/attachment.rb
174
177
  - app/models/effective/iframe_upload.rb
175
- - app/models/effective/snippets/effective_asset.rb
178
+ - app/models/effective/snippet_replacer.rb
176
179
  - app/uploaders/effective_assets_uploader.rb
177
180
  - app/uploaders/test_asset_uploader.rb
178
181
  - app/views/active_admin/effective_assets/_edit.html.haml
@@ -201,6 +204,8 @@ files:
201
204
  - lib/inputs/asset_box_input.rb
202
205
  - lib/inputs/asset_box_simple_form_input.rb
203
206
  - lib/tasks/effective_assets_tasks.rake
207
+ - lib/tasks/replace_effective_assets.rake
208
+ - lib/tasks/replace_effective_snippets.rake
204
209
  - lib/validators/asset_box_length_validator.rb
205
210
  - lib/validators/asset_box_presence_validator.rb
206
211
  homepage: https://github.com/code-and-effect/effective_assets
@@ -1,37 +0,0 @@
1
- if defined?(EffectiveRegions)
2
- module Effective
3
- module Snippets
4
- class EffectiveAsset < Snippet
5
- # attr_accessor :asset_id #, Integer
6
- # attr_accessor :html_class #, String
7
- # attr_accessor :link_title #, String
8
- # attr_accessor :private_url # , Boolean
9
-
10
- def snippet_attributes
11
- super + [:asset_id, :html_class, :link_title, :private_url]
12
- end
13
-
14
- def asset
15
- @asset ||= (Effective::Asset.where(:id => asset_id).first if asset_id)
16
- end
17
-
18
- def snippet_tag
19
- :span
20
- end
21
-
22
- def private_url
23
- super || aws_private?
24
- end
25
-
26
- def is_private?
27
- [true, 'true', '1'].include?(private_url)
28
- end
29
-
30
- def aws_private?
31
- (asset.try(:aws_acl) == EffectiveAssets::AWS_PRIVATE)
32
- end
33
-
34
- end
35
- end
36
- end
37
- end