effective_resources 2.26.5 → 2.27.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bddc24c74eb0d2e435dde9fd9db596d4bd9f84712122d5b29193164d0e3074d
4
- data.tar.gz: b70b54824daeaa93e75b4fdcfccc0ba6c19a3506ce50938645b1825175aa8f7f
3
+ metadata.gz: 0a8d7a783095b227ca8e11253cb186f4b06c2fb7ec8b42511251d925bfddf7e0
4
+ data.tar.gz: 53038ae639dc8fe0b9aa0764232b0ba4af4b94afe8f6f686c516bbfbbf153d82
5
5
  SHA512:
6
- metadata.gz: 752c5d16966bcce3f11a685709fbbbb913f7c9169b4a3b796211ac2f0b6ea4bebfc8c24450a1faaa14b9e2c1490c6e3f4333914c078f1f71769dabb3781086a6
7
- data.tar.gz: 28ca623466c6fc2672e5ab2ee80c91feb3523cff88ef3367d5d5d1976d0da4d95a266579609a2e201097112dcdc7a8e65c2e735514ca3208b0f8797b05471631
6
+ metadata.gz: ff8d6145dc5cbbfb86170194d60e295a1c31face8480be9b3cd893afb17bd96b785bf2f886457e5082fb7c37f952d5f2842b551cafc98f493e3f4209b6adc1a9
7
+ data.tar.gz: f2e4c9e106f3a16490807df977089f1a40f51eb3f9abc6d9dc09dc85c863d818113035769417923384b43ea5c278685dc81de7108c3fe1d912c9862b8853cd91
@@ -0,0 +1,111 @@
1
+ # ActsAsJobStatus
2
+ #
3
+ # Tracks the status of background jobs. Intended to be used in a wizard.
4
+ #
5
+ # Mark your model with 'acts_as_job_status'
6
+ #
7
+ # Add the the following columns
8
+ #
9
+ # job_status :string
10
+ # job_started_at :datetime
11
+ # job_ended_at :datetime
12
+ # job_error :text
13
+ #
14
+ # Use with_job_status in your background job
15
+
16
+ module ActsAsJobStatus
17
+ extend ActiveSupport::Concern
18
+
19
+ module Base
20
+ def acts_as_job_status(options = nil)
21
+ include ::ActsAsJobStatus
22
+ end
23
+ end
24
+
25
+ included do
26
+ end
27
+
28
+ module ClassMethods
29
+ def acts_as_job_status?; true; end
30
+ end
31
+
32
+ # Instance Methods
33
+
34
+ def perform_with_job_status!(&block)
35
+ assign_attributes(job_status: nil, job_started_at: nil, job_ended_at: nil, job_error: nil)
36
+
37
+ after_commit { yield }
38
+
39
+ save!
40
+ end
41
+
42
+ def job_status_display_item_counts?
43
+ job_status_completed_items_count.present? && job_status_total_items_count.present?
44
+ end
45
+
46
+ def job_status_completed_items_count
47
+ nil
48
+ end
49
+
50
+ def job_status_total_items_count
51
+ nil
52
+ end
53
+
54
+ def job_status_enqueued?
55
+ job_status == 'enqueued'
56
+ end
57
+
58
+ def job_status_running?
59
+ job_status == 'running'
60
+ end
61
+
62
+ def job_status_completed?
63
+ job_status == 'completed'
64
+ end
65
+
66
+ def job_status_error?
67
+ job_status == 'error'
68
+ end
69
+
70
+ def with_job_status(&block)
71
+ self.class.where(id: id).update_all(
72
+ job_status: :running,
73
+ job_started_at: Time.zone.now,
74
+ job_ended_at: nil,
75
+ job_error: nil
76
+ )
77
+
78
+ exception = nil
79
+ job_status = nil
80
+ job_error = nil
81
+
82
+ begin
83
+ success = yield
84
+ raise('Unexpected error') unless success
85
+
86
+ job_status = :completed
87
+ rescue Exception => e
88
+ exception = e
89
+ job_status = :error
90
+ job_error = e.message.presence || 'Unexpected error'
91
+ end
92
+
93
+ self.class.where(id: id).update_all(
94
+ job_status: job_status,
95
+ job_ended_at: Time.zone.now,
96
+ job_error: job_error
97
+ )
98
+
99
+ if job_status == :error
100
+ EffectiveLogger.error(exception.message, associated: self) if defined?(EffectiveLogger)
101
+ ExceptionNotifier.notify_exception(exception, data: { id: id, class_name: self.class.name }) if defined?(ExceptionNotifier)
102
+ end
103
+
104
+ if job_status == :error && !ENV['TESTING_ACTS_AS_JOB_STATUS']
105
+ raise(exception) unless Rails.env.production? || Rails.env.staging?
106
+ end
107
+
108
+ true
109
+ end
110
+
111
+ end
@@ -23,7 +23,7 @@ module ActsAsPublished
23
23
  attr_writer :save_as_draft
24
24
 
25
25
  before_validation(if: -> { EffectiveResources.falsey?(@save_as_draft) && (@save_as_draft.present? || new_record?) }) do
26
- self.published_start_at ||= Time.zone.now
26
+ self.published_start_at ||= Time.zone.now.beginning_of_day
27
27
  end
28
28
 
29
29
  before_validation(if: -> { EffectiveResources.truthy?(@save_as_draft) }) do
@@ -48,6 +48,24 @@ module ActsAsPublished
48
48
  end
49
49
 
50
50
  # Instance Methods
51
+ def publish!
52
+ now = Time.zone.now
53
+
54
+ if published_start_at.blank? || published_start_at > now
55
+ assign_attributes(published_start_at: now.beginning_of_day)
56
+ end
57
+
58
+ if published_end_at.present? && (published_end_at <= now || published_end_at <= published_start_at)
59
+ assign_attributes(published_end_at: nil)
60
+ end
61
+
62
+ save!
63
+ end
64
+
65
+ def draft!
66
+ update!(published_start_at: nil, published_end_at: nil)
67
+ end
68
+
51
69
  def published?
52
70
  return false if published_start_at.blank? || published_start_at > Time.zone.now
53
71
  return false if published_end_at.present? && published_end_at <= Time.zone.now
@@ -0,0 +1,48 @@
1
+ - if [nil, 'enqueued', 'running'].include?(resource.job_status)
2
+ %p The background job is running. Please wait.
3
+
4
+ %p.text-center
5
+ = icon('spinner')
6
+
7
+ - if resource.job_status_display_item_counts?
8
+ - completed = resource.job_status_completed_items_count
9
+ - total = resource.job_status_total_items_count
10
+ - percent = ((completed * 100).to_f / [total, 1].max).round(0)
11
+
12
+ .progress
13
+ .progress-bar{role: 'progressbar', 'aria-valuenow': completed, 'aria-valuemin': 0, 'aria-valuemax': total, style: "width: #{percent}%"}
14
+
15
+ %p.text-center
16
+ Completed #{completed} out of #{pluralize(total, 'item')} so far
17
+
18
+ :javascript
19
+ setTimeout(function() { window.location.reload(true) }, 5000);
20
+
21
+ %p.text-center
22
+ = link_to 'Refresh', wizard_path(step), class: 'btn btn-secondary'
23
+
24
+ %p.text-center
25
+ %small
26
+ %em This page will auto refresh every 5 seconds.
27
+
28
+ - if resource.job_status_error?
29
+ %p The following error was encountered when running the background job:
30
+
31
+ .alert.alert-danger.my-4
32
+ = resource.job_error.html_safe
33
+
34
+ %p Please fix any error, then try again.
35
+
36
+ %p.text-center
37
+ = link_to 'Try Again', wizard_path(resource.previous_step(step)), class: 'btn btn-secondary'
38
+
39
+ - if resource.job_status_completed?
40
+ %p.text-center
41
+ = icon('check')
42
+
43
+ %p.text-center
44
+ Job complete!
45
+
46
+ - if resource.job_status_display_item_counts?
47
+ = pluralize(resource.job_status_completed_items_count, 'item')
48
+ have been completed.
@@ -86,9 +86,23 @@ module EffectiveGem
86
86
  raise('gem does not respond to mailer_class') unless respond_to?(:mailer_class)
87
87
  raise('expected args to be an Array') unless args.kind_of?(Array)
88
88
 
89
- mailer_class.send(email, *args).send(deliver_method)
90
- end
89
+ begin
90
+ mailer_class.send(email, *args).send(deliver_method)
91
+ rescue => e
92
+ associated = args.first
93
+
94
+ if associated.kind_of?(ActiveRecord::Base)
95
+ EffectiveLogger.error(e.message, associated: associated, details: { email: email }) if defined?(EffectiveLogger)
96
+ ExceptionNotifier.notify_exception(e, data: { email: email, associated_id: associated.id, associated_type: associated.class.name }) if defined?(ExceptionNotifier)
97
+ else
98
+ args_to_s = args.to_s.gsub('<', '').gsub('>', '')
99
+ EffectiveLogger.error(e.message, details: { email: email, args: args_to_s }) if defined?(EffectiveLogger)
100
+ ExceptionNotifier.notify_exception(e, data: { email: email, args: args_to_s }) if defined?(ExceptionNotifier)
101
+ end
91
102
 
103
+ raise(e) unless Rails.env.production? || Rails.env.staging?
104
+ end
105
+ end
92
106
  end
93
107
 
94
108
  end
@@ -23,6 +23,7 @@ module EffectiveResources
23
23
  initializer 'effective_resources.active_record' do |app|
24
24
  app.config.to_prepare do
25
25
  ActiveRecord::Base.extend(ActsAsArchived::Base)
26
+ ActiveRecord::Base.extend(ActsAsJobStatus::Base)
26
27
  ActiveRecord::Base.extend(ActsAsEmailForm::Base)
27
28
  ActiveRecord::Base.extend(ActsAsEmailNotification::Base)
28
29
  ActiveRecord::Base.extend(ActsAsTokened::Base)
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '2.26.5'.freeze
2
+ VERSION = '2.27.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.26.5
4
+ version: 2.27.0
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: 2024-12-09 00:00:00.000000000 Z
11
+ date: 2025-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: effective_developer
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: haml
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -202,6 +216,7 @@ files:
202
216
  - app/models/concerns/acts_as_archived.rb
203
217
  - app/models/concerns/acts_as_email_form.rb
204
218
  - app/models/concerns/acts_as_email_notification.rb
219
+ - app/models/concerns/acts_as_job_status.rb
205
220
  - app/models/concerns/acts_as_paginable.rb
206
221
  - app/models/concerns/acts_as_published.rb
207
222
  - app/models/concerns/acts_as_purchasable_wizard.rb
@@ -259,6 +274,7 @@ files:
259
274
  - app/views/application/update.js.erb
260
275
  - app/views/effective/acts_as_email_form/_fields.html.haml
261
276
  - app/views/effective/acts_as_email_notification/_fields.html.haml
277
+ - app/views/effective/acts_as_job_status/_wizard_step.html.haml
262
278
  - app/views/effective/acts_as_published/_fields.html.haml
263
279
  - app/views/effective/acts_as_slugged/_fields.html.haml
264
280
  - app/views/effective/acts_as_wizard/_wizard_step.html.haml