panda_pal 4.1.0.beta3 → 5.0.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 +5 -5
- data/README.md +60 -71
- data/app/models/panda_pal/organization.rb +46 -17
- data/db/618eef7c0380ba654ad16f867a919e72.sqlite3 +0 -0
- data/db/9ff93d4f7e0e9dc80a43f68997caf4a1.sqlite3 +0 -0
- data/db/a3fda4044a7215bc2c9eb01a4b9e517a.sqlite3 +0 -0
- data/db/daa0e6378a5ec76fcce83b7070dad219.sqlite3 +0 -0
- data/lib/panda_pal/helpers/controller_helper.rb +38 -33
- data/lib/panda_pal/version.rb +1 -1
- data/panda_pal.gemspec +0 -3
- data/spec/dummy/config/application.rb +1 -7
- data/spec/dummy/config/environments/development.rb +14 -0
- data/spec/dummy/config/environments/production.rb +11 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +15058 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/models/panda_pal/organization_spec.rb +89 -0
- data/spec/spec_helper.rb +0 -4
- metadata +19 -41
- data/app/models/panda_pal/organization/settings_validation.rb +0 -111
- data/app/models/panda_pal/organization/task_scheduling.rb +0 -172
- data/app/views/panda_pal/lti/iframe_cookie_fix.html.erb +0 -12
- data/spec/models/panda_pal/organization/settings_validation_spec.rb +0 -175
- data/spec/models/panda_pal/organization/task_scheduling_spec.rb +0 -144
File without changes
|
@@ -2,6 +2,35 @@ require 'rails_helper'
|
|
2
2
|
|
3
3
|
module PandaPal
|
4
4
|
RSpec.describe Organization, type: :model do
|
5
|
+
|
6
|
+
def set_test_settings_structure
|
7
|
+
PandaPal.lti_options = {
|
8
|
+
title: 'Test App',
|
9
|
+
settings_structure: YAML.load("
|
10
|
+
canvas:
|
11
|
+
is_required: true
|
12
|
+
data_type: Hash
|
13
|
+
api_token:
|
14
|
+
is_required: true
|
15
|
+
data_type: String
|
16
|
+
base_url:
|
17
|
+
is_required: true
|
18
|
+
data_type: String
|
19
|
+
reports:
|
20
|
+
is_required: true
|
21
|
+
data_type: Hash
|
22
|
+
active_term_allowance:
|
23
|
+
submissions_report_time_length:
|
24
|
+
is_required: true
|
25
|
+
data_type: ActiveSupport::Duration
|
26
|
+
recheck_wait:
|
27
|
+
data_type: ActiveSupport::Duration
|
28
|
+
max_recheck_time:
|
29
|
+
is_required: true
|
30
|
+
").deep_symbolize_keys
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
5
34
|
it 'creates a schema upon creation' do
|
6
35
|
expect(Apartment::Tenant).to receive(:create)
|
7
36
|
create :panda_pal_organization
|
@@ -30,5 +59,65 @@ module PandaPal
|
|
30
59
|
org2 = build :panda_pal_organization, salesforce_id: 'salesforce'
|
31
60
|
expect(org2.valid?).to be_falsey
|
32
61
|
end
|
62
|
+
|
63
|
+
context 'settings validation' do
|
64
|
+
let!(:org) { create :panda_pal_organization }
|
65
|
+
|
66
|
+
it 'does not perform any validations if settings is not defined' do
|
67
|
+
PandaPal.lti_options = {}
|
68
|
+
expect_any_instance_of(PandaPal::Organization).not_to receive(:validate_level)
|
69
|
+
expect(org.valid?).to be_truthy
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'does not perform any validations if options is not defined' do
|
73
|
+
PandaPal.lti_options = nil
|
74
|
+
expect_any_instance_of(PandaPal::Organization).not_to receive(:validate_level)
|
75
|
+
expect(org.valid?).to be_truthy
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'does perform validations if settings_structure is defined' do
|
79
|
+
set_test_settings_structure
|
80
|
+
org.valid?
|
81
|
+
expect(org.valid?).to be_falsey
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'will fail if a required setting is not present' do
|
85
|
+
set_test_settings_structure
|
86
|
+
expect(org.valid?).to be_falsey
|
87
|
+
errors = org.errors.messages[:settings]
|
88
|
+
expect(errors[0]).to eq("PandaPal::Organization.settings requires key [:canvas]. It was not found.")
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'will fail if a setting is supplied but data_type is wrong' do
|
92
|
+
set_test_settings_structure
|
93
|
+
org.settings = {canvas: "Dog"}
|
94
|
+
expect(org.valid?).to be_falsey
|
95
|
+
errors = org.errors.messages[:settings]
|
96
|
+
expect(errors[0]).to eq("PandaPal::Organization.settings expected key [:canvas] to be Hash but it was instead String.")
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'will fail if a required subsetting is missing' do
|
100
|
+
set_test_settings_structure
|
101
|
+
org.settings = {canvas: {base_url: 'http://'}, reports: {}}
|
102
|
+
expect(org.valid?).to be_falsey
|
103
|
+
errors = org.errors.messages[:settings]
|
104
|
+
expect(errors[0]).to eq("PandaPal::Organization.settings requires key [:canvas][:api_token]. It was not found.")
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'will fail if extra options are specified' do
|
108
|
+
set_test_settings_structure
|
109
|
+
org.settings = {canvas: {base_url: 'http://'}, reports: {}, unknown_option: "WHAT IS THIS?"}
|
110
|
+
expect(org.valid?).to be_falsey
|
111
|
+
errors = org.errors.messages[:settings]
|
112
|
+
expect(errors[0]).to eq("PandaPal::Organization.settings had unexpected key: unknown_option. If settings have expanded please update your lti_options accordingly.")
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'will pass if all structure is maintained' do
|
116
|
+
set_test_settings_structure
|
117
|
+
org.settings = {canvas: {base_url: 'http://', api_token: 'TEST'}, reports: {submissions_report_time_length: 30.minutes, max_recheck_time: 10.hours}}
|
118
|
+
expect(org.valid?).to be_truthy
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
33
122
|
end
|
34
123
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panda_pal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Instructure ProServe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -114,34 +114,6 @@ dependencies:
|
|
114
114
|
- - "~>"
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: 6.1.2
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
|
-
name: sidekiq
|
119
|
-
requirement: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '0'
|
124
|
-
type: :development
|
125
|
-
prerelease: false
|
126
|
-
version_requirements: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '0'
|
131
|
-
- !ruby/object:Gem::Dependency
|
132
|
-
name: sidekiq-scheduler
|
133
|
-
requirement: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - ">="
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '0'
|
138
|
-
type: :development
|
139
|
-
prerelease: false
|
140
|
-
version_requirements: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - ">="
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: '0'
|
145
117
|
- !ruby/object:Gem::Dependency
|
146
118
|
name: rspec-rails
|
147
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,14 +163,15 @@ files:
|
|
191
163
|
- app/lib/lti_xml/bridge_platform.rb
|
192
164
|
- app/lib/lti_xml/canvas_platform.rb
|
193
165
|
- app/models/panda_pal/organization.rb
|
194
|
-
- app/models/panda_pal/organization/settings_validation.rb
|
195
|
-
- app/models/panda_pal/organization/task_scheduling.rb
|
196
166
|
- app/models/panda_pal/session.rb
|
197
167
|
- app/views/layouts/panda_pal/application.html.erb
|
198
|
-
- app/views/panda_pal/lti/iframe_cookie_fix.html.erb
|
199
168
|
- app/views/panda_pal/lti/launch.html.erb
|
200
169
|
- config/initializers/apartment.rb
|
201
170
|
- config/routes.rb
|
171
|
+
- db/618eef7c0380ba654ad16f867a919e72.sqlite3
|
172
|
+
- db/9ff93d4f7e0e9dc80a43f68997caf4a1.sqlite3
|
173
|
+
- db/a3fda4044a7215bc2c9eb01a4b9e517a.sqlite3
|
174
|
+
- db/daa0e6378a5ec76fcce83b7070dad219.sqlite3
|
202
175
|
- db/migrate/20160412205931_create_panda_pal_organizations.rb
|
203
176
|
- db/migrate/20160413135653_create_panda_pal_sessions.rb
|
204
177
|
- db/migrate/20160425130344_add_panda_pal_organization_to_session.rb
|
@@ -233,6 +206,7 @@ files:
|
|
233
206
|
- spec/dummy/config/environments/development.rb
|
234
207
|
- spec/dummy/config/environments/production.rb
|
235
208
|
- spec/dummy/config/environments/test.rb
|
209
|
+
- spec/dummy/config/initializers/assets.rb
|
236
210
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
237
211
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
238
212
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
@@ -243,15 +217,17 @@ files:
|
|
243
217
|
- spec/dummy/config/locales/en.yml
|
244
218
|
- spec/dummy/config/routes.rb
|
245
219
|
- spec/dummy/config/secrets.yml
|
220
|
+
- spec/dummy/db/development.sqlite3
|
246
221
|
- spec/dummy/db/schema.rb
|
222
|
+
- spec/dummy/db/test.sqlite3
|
223
|
+
- spec/dummy/log/development.log
|
224
|
+
- spec/dummy/log/test.log
|
247
225
|
- spec/dummy/public/404.html
|
248
226
|
- spec/dummy/public/422.html
|
249
227
|
- spec/dummy/public/500.html
|
250
228
|
- spec/dummy/public/favicon.ico
|
251
229
|
- spec/factories/panda_pal_organizations.rb
|
252
230
|
- spec/factories/panda_pal_sessions.rb
|
253
|
-
- spec/models/panda_pal/organization/settings_validation_spec.rb
|
254
|
-
- spec/models/panda_pal/organization/task_scheduling_spec.rb
|
255
231
|
- spec/models/panda_pal/organization_spec.rb
|
256
232
|
- spec/models/panda_pal/session_spec.rb
|
257
233
|
- spec/rails_helper.rb
|
@@ -271,12 +247,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
271
247
|
version: '0'
|
272
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
273
249
|
requirements:
|
274
|
-
- - "
|
250
|
+
- - ">="
|
275
251
|
- !ruby/object:Gem::Version
|
276
|
-
version:
|
252
|
+
version: '0'
|
277
253
|
requirements: []
|
278
|
-
|
279
|
-
rubygems_version: 2.6.11
|
254
|
+
rubygems_version: 3.1.2
|
280
255
|
signing_key:
|
281
256
|
specification_version: 4
|
282
257
|
summary: LTI mountable engine
|
@@ -306,6 +281,7 @@ test_files:
|
|
306
281
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
307
282
|
- spec/dummy/config/initializers/session_store.rb
|
308
283
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
284
|
+
- spec/dummy/config/initializers/assets.rb
|
309
285
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
310
286
|
- spec/dummy/config/initializers/inflections.rb
|
311
287
|
- spec/dummy/config.ru
|
@@ -315,9 +291,11 @@ test_files:
|
|
315
291
|
- spec/dummy/public/500.html
|
316
292
|
- spec/dummy/public/404.html
|
317
293
|
- spec/dummy/db/schema.rb
|
294
|
+
- spec/dummy/db/test.sqlite3
|
295
|
+
- spec/dummy/db/development.sqlite3
|
296
|
+
- spec/dummy/log/test.log
|
297
|
+
- spec/dummy/log/development.log
|
318
298
|
- spec/dummy/README.rdoc
|
319
|
-
- spec/models/panda_pal/organization/settings_validation_spec.rb
|
320
|
-
- spec/models/panda_pal/organization/task_scheduling_spec.rb
|
321
299
|
- spec/models/panda_pal/session_spec.rb
|
322
300
|
- spec/models/panda_pal/organization_spec.rb
|
323
301
|
- spec/factories/panda_pal_sessions.rb
|
@@ -1,111 +0,0 @@
|
|
1
|
-
module PandaPal
|
2
|
-
module OrganizationConcerns
|
3
|
-
module SettingsValidation
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
validate :validate_settings
|
8
|
-
end
|
9
|
-
|
10
|
-
class_methods do
|
11
|
-
def settings_structure
|
12
|
-
if PandaPal.lti_options&.[](:settings_structure).present?
|
13
|
-
normalize_settings_structure(PandaPal.lti_options[:settings_structure])
|
14
|
-
else
|
15
|
-
{
|
16
|
-
type: Hash,
|
17
|
-
allow_additional: true,
|
18
|
-
properties: {},
|
19
|
-
}
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def normalize_settings_structure(struc)
|
24
|
-
return {} unless struc.present?
|
25
|
-
return struc if struc[:properties] || struc[:type] || struc.key?(:required)
|
26
|
-
|
27
|
-
struc = struc.dup
|
28
|
-
nstruc = {}
|
29
|
-
|
30
|
-
nstruc[:type] = struc.delete(:data_type) if struc.key?(:data_type)
|
31
|
-
nstruc[:required] = struc.delete(:is_required) if struc.key?(:is_required)
|
32
|
-
nstruc[:properties] = struc.map { |k, sub| [k, normalize_settings_structure(sub)] }.to_h if struc.present?
|
33
|
-
|
34
|
-
nstruc
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def settings_structure
|
39
|
-
self.class.settings_structure
|
40
|
-
end
|
41
|
-
|
42
|
-
def validate_settings
|
43
|
-
validate_settings_level(settings || {}, settings_structure).each do |err|
|
44
|
-
errors[:settings] << err
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def validate_settings_level(settings, spec, path: [], errors: [])
|
51
|
-
human_path = "[:#{path.join('][:')}]"
|
52
|
-
|
53
|
-
if settings.nil?
|
54
|
-
errors << "Entry #{human_path} is required" if spec[:required]
|
55
|
-
return
|
56
|
-
end
|
57
|
-
|
58
|
-
if spec[:type]
|
59
|
-
resolved_type = spec[:type]
|
60
|
-
resolved_type = resolved_type.constantize if resolved_type.is_a?(String)
|
61
|
-
unless settings.is_a?(resolved_type)
|
62
|
-
errors << "Expected #{human_path} to be a #{spec[:type]}. Was a #{settings.class.to_s}"
|
63
|
-
return
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
if spec[:validate].present?
|
68
|
-
val_errors = []
|
69
|
-
if spec[:validate].is_a?(Symbol)
|
70
|
-
proc_result = send(spec[:validate], settings, spec, path: path, errors: val_errors)
|
71
|
-
elsif spec[:validate].is_a?(String)
|
72
|
-
split_val = spec[:validate].split?('.')
|
73
|
-
split_val << 'validate_settings' if split_val.count == 1
|
74
|
-
resolved_module = split_val[0].constantize
|
75
|
-
proc_result = resolved_module.send(split_val[1].to_sym, settings, spec, path: path, errors: val_errors)
|
76
|
-
elsif spec[:validate].is_a?(Proc)
|
77
|
-
proc_result = instance_exec(settings, spec, path: path, errors: val_errors, &spec[:validate])
|
78
|
-
end
|
79
|
-
val_errors << proc_result unless val_errors.present? || proc_result == val_errors
|
80
|
-
val_errors = val_errors.flatten.uniq.compact.map do |ve|
|
81
|
-
ve.gsub('<path>', human_path)
|
82
|
-
end
|
83
|
-
errors.concat(val_errors)
|
84
|
-
end
|
85
|
-
|
86
|
-
if settings.is_a?(Hash)
|
87
|
-
if spec[:properties] != nil
|
88
|
-
spec[:properties].each do |key, pspec|
|
89
|
-
validate_settings_level(settings[key], pspec, path: [*path, key], errors: errors)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if spec[:properties] != nil || spec[:allow_additional] != nil
|
94
|
-
extra_keys = settings.keys - (spec[:properties]&.keys || [])
|
95
|
-
if extra_keys.present?
|
96
|
-
if spec[:allow_additional].is_a?(Hash)
|
97
|
-
extra_keys.each do |key|
|
98
|
-
validate_settings_level(settings[key], spec[:allow_additional], path: [*path, key], errors: errors)
|
99
|
-
end
|
100
|
-
elsif !spec[:allow_additional]
|
101
|
-
errors << "Did not expect #{human_path} to contain [#{extra_keys.join(', ')}]"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
errors
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
return unless defined?(Sidekiq.schedule)
|
2
|
-
|
3
|
-
require_relative 'settings_validation'
|
4
|
-
|
5
|
-
module PandaPal
|
6
|
-
module OrganizationConcerns
|
7
|
-
module TaskScheduling
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
include OrganizationConcerns::SettingsValidation
|
10
|
-
|
11
|
-
included do
|
12
|
-
after_commit :sync_schedule, on: [:create, :update]
|
13
|
-
after_commit :unschedule_tasks, on: :destroy
|
14
|
-
end
|
15
|
-
|
16
|
-
class_methods do
|
17
|
-
def _schedule_descriptors
|
18
|
-
@_schedule_descriptors ||= {}
|
19
|
-
end
|
20
|
-
|
21
|
-
def settings_structure
|
22
|
-
return super unless _schedule_descriptors.present?
|
23
|
-
|
24
|
-
super.tap do |struc|
|
25
|
-
struc[:properties] ||= {}
|
26
|
-
|
27
|
-
struc[:properties][:timezone] ||= {
|
28
|
-
type: 'String',
|
29
|
-
required: false,
|
30
|
-
validate: ->(timezone, *args) {
|
31
|
-
ActiveSupport::TimeZone[timezone].present? ? nil : "<path> Invalid Timezone '#{timezone}'"
|
32
|
-
},
|
33
|
-
}
|
34
|
-
|
35
|
-
struc[:properties][:task_schedules] = {
|
36
|
-
type: 'Hash',
|
37
|
-
required: false,
|
38
|
-
properties: _schedule_descriptors.keys.reduce({}) do |hash, k|
|
39
|
-
hash.tap do |hash|
|
40
|
-
hash[k.to_sym] = hash[k.to_s] = {
|
41
|
-
required: false,
|
42
|
-
validate: ->(value, *args, errors:, **kwargs) {
|
43
|
-
begin
|
44
|
-
Rufus::Scheduler.parse(value) if value
|
45
|
-
nil
|
46
|
-
rescue ArgumentError
|
47
|
-
errors << "<path> must be false or a Crontab string"
|
48
|
-
end
|
49
|
-
}
|
50
|
-
}
|
51
|
-
end
|
52
|
-
end,
|
53
|
-
}
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def scheduled_task(cron_time, name_or_method = nil, worker: nil, queue: nil, &block)
|
58
|
-
task_key = (name_or_method.presence || "scheduled_task_#{caller_locations[0].lineno}").to_s
|
59
|
-
raise "Task key '#{task_key}' already taken!" if _schedule_descriptors.key?(task_key)
|
60
|
-
|
61
|
-
_schedule_descriptors[task_key] = {
|
62
|
-
key: task_key,
|
63
|
-
schedule: cron_time,
|
64
|
-
worker: worker || block || name_or_method.to_sym,
|
65
|
-
queue: queue || 'default',
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
def sync_schedules
|
70
|
-
# Ensure deleted Orgs are removed
|
71
|
-
existing_orgs = pluck(:name)
|
72
|
-
old_schedules = Sidekiq.get_schedule.select do |k, v|
|
73
|
-
m = k.match(/^org:([a-z0-9_]+)\-/i)
|
74
|
-
m.present? && !existing_orgs.include?(m[1])
|
75
|
-
end
|
76
|
-
old_schedules.keys.each do |k|
|
77
|
-
Sidekiq.remove_schedule(k)
|
78
|
-
end
|
79
|
-
|
80
|
-
find_each(&:sync_schedule)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def generate_schedule
|
85
|
-
schedule = {}
|
86
|
-
self.class._schedule_descriptors.values.each do |desc|
|
87
|
-
cron_time = schedule_task_cron_time(desc)
|
88
|
-
next unless cron_time.present?
|
89
|
-
|
90
|
-
schedule["org:#{name}-#{desc[:key]}"] = {
|
91
|
-
'cron' => cron_time,
|
92
|
-
'queue' => desc[:queue],
|
93
|
-
'class' => ScheduledTaskExecutor.to_s,
|
94
|
-
'args' => [name, desc[:key]],
|
95
|
-
}
|
96
|
-
end
|
97
|
-
schedule
|
98
|
-
end
|
99
|
-
|
100
|
-
def sync_schedule
|
101
|
-
new_schedules = generate_schedule
|
102
|
-
unschedule_tasks(new_schedules.keys)
|
103
|
-
new_schedules.each do |k, v|
|
104
|
-
Sidekiq.set_schedule(k, v)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
def unschedule_tasks(new_task_keys = nil)
|
111
|
-
current_schedules = Sidekiq.get_schedule.select { |k,v| k.starts_with?("org:#{name}-") }
|
112
|
-
del_tasks = current_schedules.keys
|
113
|
-
del_tasks -= new_task_keys if new_task_keys
|
114
|
-
del_tasks.each do |k|
|
115
|
-
Sidekiq.remove_schedule(k)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def schedule_task_cron_time(desc)
|
120
|
-
cron_time = nil
|
121
|
-
cron_time = settings&.dig(:task_schedules, desc[:key].to_s) if cron_time.nil?
|
122
|
-
cron_time = settings&.dig(:task_schedules, desc[:key].to_sym) if cron_time.nil?
|
123
|
-
cron_time = desc[:schedule] if cron_time.nil?
|
124
|
-
|
125
|
-
return nil unless cron_time.present?
|
126
|
-
|
127
|
-
cron_time = instance_exec(&cron_time) if cron_time.is_a?(Proc)
|
128
|
-
if !Rufus::Scheduler.parse(cron_time).zone.present? && settings && settings[:timezone]
|
129
|
-
cron_time += " #{settings[:timezone]}"
|
130
|
-
end
|
131
|
-
|
132
|
-
cron_time
|
133
|
-
end
|
134
|
-
|
135
|
-
class ScheduledTaskExecutor
|
136
|
-
include Sidekiq::Worker
|
137
|
-
|
138
|
-
def perform(org_name, task_key)
|
139
|
-
org = Organization.find_by!(name: org_name)
|
140
|
-
task = Organization._schedule_descriptors[task_key]
|
141
|
-
worker = task[:worker]
|
142
|
-
|
143
|
-
Apartment::Tenant.switch(org.name) do
|
144
|
-
if worker.is_a?(Proc)
|
145
|
-
org.instance_exec(&worker)
|
146
|
-
elsif worker.is_a?(Symbol)
|
147
|
-
org.send(worker)
|
148
|
-
elsif worker.is_a?(String)
|
149
|
-
worker.constantize.perform_async
|
150
|
-
elsif worker.is_a?(Class)
|
151
|
-
worker.perform_async
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
SidekiqScheduler::Scheduler.instance.dynamic = true
|
161
|
-
|
162
|
-
module SidekiqScheduler
|
163
|
-
module Schedule
|
164
|
-
original_schedule_setter = instance_method(:schedule=)
|
165
|
-
|
166
|
-
define_method :schedule= do |sched|
|
167
|
-
original_schedule_setter.bind(self).(sched).tap do
|
168
|
-
PandaPal::Organization.sync_schedules
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|