canvas_sync 0.17.27 → 0.17.30

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b85b5374a289fbab25718bb03812c9623065dc5c8b4e35fff67c79d220d7fda9
4
- data.tar.gz: 9a8d01f7a45bfe58339c8ba8a808a29d655711945ec7cf27a8e8fcd02205f343
3
+ metadata.gz: ef8cd570185754998d8c14cd67f87c6d60e3507f7996925bdc4a425cd7d43f1d
4
+ data.tar.gz: 931416870261971aaeccfc59bae91972c8d7a7277aab9da4ac18610c3352a7fe
5
5
  SHA512:
6
- metadata.gz: 73bf2bd012676ff339ccb3f2c7a2802e0752bc5623ccd301fc808d15ce139673be955ae4aee2b9ee842b18c2235cdbc843f197090c00b4caf6f57c6975d5c81a
7
- data.tar.gz: eed6e24b8f30396a2f09751d2b786527a7b039c8b6fa6fbdcc9bdf695449f6e90ca76e138aec9fefb3a905abdbefd45ca092a1e1b85b0f706f6ca0fc35ff9fde
6
+ metadata.gz: 7262c43e7395e4c9de96a9d5c4688ff85299fcab3f97abcea719b6f73c36fb519c23ccf7a224605a8552d0e547fe135ecc055ac7f664d240f0cc1dd8a932e2bf
7
+ data.tar.gz: 524b36471a7b135856c2e3bd935e8ab7e057616c1bd3ed4a6d5e7a6d66c98f3236cf87d041f946a5e4ac149bef9830100619ba9e61568971f0e17898ae2f44f3
data/README.md CHANGED
@@ -34,6 +34,7 @@ The following custom reports are required for the specified models:
34
34
  - assignment_groups = "Assignment Group Export" (proserv_assignment_group_export_csv)
35
35
  - context_modules = "Professional Services Context Modules Report" (proserv_context_modules_csv)
36
36
  - context_module_items = "Professional Services Context Module Items Report" (proserv_context_module_items_csv)
37
+ - content_migrations = "Professional Services Content Migrations Report" (proserv_content_migrations_csv)
37
38
 
38
39
  ## Prerequisites
39
40
 
@@ -0,0 +1,24 @@
1
+ # <%= autogenerated_migration_warning %>
2
+
3
+ class CreateContentMigrations < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :content_migrations do |t|
6
+ t.bigint :canvas_id
7
+ t.bigint :canvas_context_id
8
+ t.string :canvas_context_type
9
+ t.string :workflow_state
10
+ t.text :migration_settings
11
+ t.datetime :started_at
12
+ t.datetime :finished_at
13
+ t.float :progress
14
+ t.bigint :canvas_source_course_id
15
+ t.string :migration_type
16
+ t.bigint :canvas_child_subscription_id
17
+ t.bigint :canvas_root_account_id
18
+
19
+ t.timestamps
20
+ end
21
+
22
+ add_index :content_migrations, :canvas_id, unique: true
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ # <%= autogenerated_model_warning %>
2
+
3
+ class ContentMigration < ApplicationRecord
4
+ include CanvasSync::Record
5
+ include CanvasSync::Concerns::ApiSyncable
6
+
7
+ validates :canvas_id, uniqueness: true, presence: true
8
+ belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
9
+
10
+ end
@@ -242,7 +242,7 @@ module CanvasSync
242
242
  _, pending, failed, children, complete, parent_bid = redis do |r|
243
243
  return unless r.exists?("BID-#{bid}")
244
244
 
245
- r.multi do
245
+ r.multi do |r|
246
246
  r.sadd("BID-#{bid}-failed", jid)
247
247
 
248
248
  r.hincrby("BID-#{bid}", "pending", 0)
@@ -260,29 +260,19 @@ module CanvasSync
260
260
  end
261
261
  end
262
262
 
263
+ # Dead jobs are a Sidekiq feature.
264
+ # If this is called for a job, process_failed_job was also called
263
265
  def process_dead_job(bid, jid)
264
- _, failed, children, complete, parent_bid = redis do |r|
266
+ _, dead_count = redis do |r|
265
267
  return unless r.exists?("BID-#{bid}")
266
268
 
267
- r.multi do
269
+ r.multi do |r|
268
270
  r.sadd("BID-#{bid}-dead", jid)
269
-
270
271
  r.scard("BID-#{bid}-dead")
271
- r.hincrby("BID-#{bid}", "children", 0)
272
- r.scard("BID-#{bid}-batches-complete")
273
- r.hget("BID-#{bid}", "parent_bid")
274
-
275
272
  r.expire("BID-#{bid}-dead", BID_EXPIRE_TTL)
276
273
  end
277
274
  end
278
275
 
279
- if parent_bid
280
- redis.multi do
281
- r.sadd("BID-#{parent_bid}-dead", jid)
282
- r.expire("BID-#{parent_bid}-dead", BID_EXPIRE_TTL)
283
- end
284
- end
285
-
286
276
  enqueue_callbacks(:death, bid)
287
277
  end
288
278
 
@@ -290,7 +280,7 @@ module CanvasSync
290
280
  _, failed, pending, children, complete, success, parent_bid, keep_open = redis do |r|
291
281
  return unless r.exists?("BID-#{bid}")
292
282
 
293
- r.multi do
283
+ r.multi do |r|
294
284
  r.srem("BID-#{bid}-failed", jid)
295
285
 
296
286
  r.scard("BID-#{bid}-failed")
@@ -323,7 +313,7 @@ module CanvasSync
323
313
  return unless r.exists?(batch_key)
324
314
  return if r.hget(batch_key, 'keep_open') == 'true'
325
315
 
326
- r.multi do
316
+ r.multi do |r|
327
317
  r.smembers(callback_key)
328
318
  r.hget(batch_key, "callback_queue")
329
319
  r.hget(batch_key, "parent_bid")
@@ -442,12 +432,8 @@ module CanvasSync
442
432
  class RedisProxy
443
433
  def multi(*args, &block)
444
434
  Batch.redis do |r|
445
- if block.arity == 1
446
- r.multi(*args) do
447
- block.call(r)
448
- end
449
- else
450
- r.multi(*args, &block)
435
+ r.multi(*args) do |r|
436
+ block.call(r)
451
437
  end
452
438
  end
453
439
  end
@@ -69,7 +69,7 @@ module CanvasSync
69
69
  # This is a callback for a callback. In this case we need to check if we should cleanup the original bid.
70
70
  origin_bid = opts['origin']['for_bid']
71
71
  _, pending, success_ran = Batch.redis do |r|
72
- r.multi do
72
+ r.multi do |r|
73
73
  r.srem("BID-#{origin_bid}-pending_callbacks", opts['origin']['event'])
74
74
  r.scard("BID-#{origin_bid}-pending_callbacks")
75
75
  r.hget("BID-#{origin_bid}", "success")
@@ -88,7 +88,7 @@ module CanvasSync
88
88
  return unless parent_bid
89
89
 
90
90
  _, _, success, _, _, complete, pending, children, success, failure = Batch.redis do |r|
91
- r.multi do
91
+ r.multi do |r|
92
92
  r.sadd("BID-#{parent_bid}-batches-success", bid)
93
93
  r.expire("BID-#{parent_bid}-batches-success", Batch::BID_EXPIRE_TTL)
94
94
  r.scard("BID-#{parent_bid}-batches-success")
@@ -116,7 +116,7 @@ module CanvasSync
116
116
 
117
117
  def complete(bid, status, parent_bid)
118
118
  pending, children, success = Batch.redis do |r|
119
- r.multi do
119
+ r.multi do |r|
120
120
  r.hincrby("BID-#{bid}", "pending", 0)
121
121
  r.hincrby("BID-#{bid}", "children", 0)
122
122
  r.scard("BID-#{bid}-batches-success")
@@ -131,7 +131,7 @@ module CanvasSync
131
131
 
132
132
  Batch.logger.debug {"Finalize parent complete bid: #{parent_bid}"}
133
133
  _, _, complete, pending, children, failure = Batch.redis do |r|
134
- r.multi do
134
+ r.multi do |r|
135
135
  r.sadd("BID-#{parent_bid}-batches-complete", bid)
136
136
  r.sadd("BID-#{parent_bid}-batches-failed", bid)
137
137
  r.scard("BID-#{parent_bid}-batches-complete")
@@ -127,7 +127,7 @@ module CanvasSync
127
127
  return @hash_map[bid] if @hash_map.key?(bid)
128
128
 
129
129
  context_json, editable = Batch.redis do |r|
130
- r.multi do
130
+ r.multi do |r|
131
131
  r.hget("BID-#{bid}", "context")
132
132
  r.hget("BID-#{bid}", "allow_context_changes")
133
133
  end
@@ -18,7 +18,7 @@ module CanvasSync
18
18
  man_batch_id = SecureRandom.urlsafe_base64(10)
19
19
 
20
20
  Batch.redis do |r|
21
- r.multi do
21
+ r.multi do |r|
22
22
  r.hset("MNGBID-#{man_batch_id}", "root_bid", root_batch.bid)
23
23
  r.hset("MNGBID-#{man_batch_id}", "ordered", ordered)
24
24
  r.hset("MNGBID-#{man_batch_id}", "concurrency", concurrency)
@@ -87,7 +87,7 @@ module CanvasSync
87
87
 
88
88
  def self.perform_next_sequence_job(man_batch_id)
89
89
  root_bid, ordered = Batch.redis do |r|
90
- r.multi do
90
+ r.multi do |r|
91
91
  r.hget("MNGBID-#{man_batch_id}", "root_bid")
92
92
  r.hget("MNGBID-#{man_batch_id}", "ordered")
93
93
  end
@@ -94,16 +94,16 @@ module CanvasSync
94
94
  redis.hincrby(redis_key, "active_count", 0)
95
95
  end
96
96
 
97
- def pending_count
97
+ def pending_count(r = redis)
98
98
  jobs_key = "#{redis_key}-jobs"
99
99
  order = self.order || 'fifo'
100
100
  case order.to_sym
101
101
  when :fifo, :lifo
102
- redis.llen(jobs_key)
102
+ r.llen(jobs_key)
103
103
  when :random
104
- redis.scard(jobs_key)
104
+ r.scard(jobs_key)
105
105
  when :priority
106
- redis.zcard(jobs_key)
106
+ r.zcard(jobs_key)
107
107
  end
108
108
  end
109
109
 
@@ -114,9 +114,9 @@ module CanvasSync
114
114
  # Make sure this is loaded outside of the pipeline
115
115
  self.order
116
116
 
117
- redis.multi do
117
+ redis.multi do |r|
118
118
  r.hincrby(redis_key, "active_count", -1)
119
- self.pending_count
119
+ self.pending_count(r)
120
120
  end
121
121
  end
122
122
 
@@ -40,7 +40,7 @@ module CanvasSync
40
40
  def persist_bid_attr(attribute, value)
41
41
  if @initialized || @existing
42
42
  redis do |r|
43
- r.multi do
43
+ r.multi do |r|
44
44
  r.hset(redis_key, attribute, value)
45
45
  r.expire(redis_key, Batch::BID_EXPIRE_TTL)
46
46
  end
@@ -13,7 +13,7 @@ module CanvasSync::JobBatches::Sidekiq
13
13
 
14
14
  def drain_zset(key)
15
15
  items, _ = Batch.redis do |r|
16
- r.multi do
16
+ r.multi do |r|
17
17
  r.zrange(key, 0, -1)
18
18
  r.zremrangebyrank(key, 0, -1)
19
19
  end
@@ -0,0 +1,20 @@
1
+ module CanvasSync
2
+ module Jobs
3
+ class SyncContentMigrationsJob < ReportStarter
4
+ # Syncs ContentMigrations
5
+ #
6
+ # Starts a report processor for the content migrations report
7
+ # (the proserv_content_migrations_csv report must be enabled)
8
+ #
9
+ # @param options [Hash]
10
+ def perform(options)
11
+ super(
12
+ "proserv_content_migrations_csv",
13
+ merge_report_params(options),
14
+ CanvasSync::Processors::ContentMigrationsProcessor.to_s,
15
+ {},
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -20,9 +20,9 @@ module CanvasSync
20
20
  end
21
21
 
22
22
  JobBatches::ManagedBatchJob.make_batch(jobs, ordered: false, concurrency: true) do |b|
23
- b.description = "TermBatchJob(#{term.canvas_id}) Root"
23
+ b.description = "TermBatchJob(#{term_id}) Root"
24
24
  b.context = local_context
25
- b.on(:success, "#{self.class.to_s}.batch_finished")
25
+ b.on(:success, "#{self.class.to_s}.batch_finished") unless options[:mark_synced] == false
26
26
  end
27
27
  end
28
28
  else
@@ -0,0 +1,19 @@
1
+ require_relative "./report_processor"
2
+
3
+ module CanvasSync
4
+ module Processors
5
+ # Processes a content migrations report using the bulk importer.
6
+ #
7
+ # @param report_file_path [String]
8
+ # @param options [Hash]
9
+ class ContentMigrationsProcessor < ReportProcessor
10
+ def self.process(report_file_path, _options, report_id)
11
+ new(report_file_path, _options)
12
+ end
13
+
14
+ def initialize(report_file_path, options)
15
+ do_bulk_import(report_file_path, ContentMigration, options: options)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -469,3 +469,43 @@ grading_period_groups:
469
469
  status:
470
470
  database_column_name: workflow_state
471
471
  type: string
472
+
473
+ content_migrations:
474
+ conflict_target: canvas_migration_id
475
+ report_columns:
476
+ canvas_migration_id:
477
+ database_column_name: canvas_id
478
+ type: integer
479
+ canvas_context_id:
480
+ database_column_name: canvas_context_id
481
+ type: integer
482
+ canvas_context_type:
483
+ database_column_name: canvas_context_type
484
+ type: string
485
+ workflow_state:
486
+ database_column_name: workflow_state
487
+ type: string
488
+ migration_settings:
489
+ database_column_name: migration_settings
490
+ type: text
491
+ started_at:
492
+ database_column_name: started_at
493
+ type: datetime
494
+ finished_at:
495
+ database_column_name: finished_at
496
+ type: datetime
497
+ progress:
498
+ database_column_name: progress
499
+ type: float
500
+ canvas_source_course_id:
501
+ database_column_name: canvas_source_course_id
502
+ type: integer
503
+ migration_type:
504
+ database_column_name: migration_type
505
+ type: string
506
+ canvas_child_subscription_id:
507
+ database_column_name: canvas_child_subscription_id
508
+ type: integer
509
+ canvas_root_account_id:
510
+ database_column_name: canvas_root_account_id
511
+ type: integer
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.17.27".freeze
2
+ VERSION = "0.17.30".freeze
3
3
  end
data/lib/canvas_sync.rb CHANGED
@@ -44,6 +44,7 @@ module CanvasSync
44
44
  user_observers
45
45
  grading_periods
46
46
  grading_period_groups
47
+ content_migrations
47
48
  ].freeze
48
49
 
49
50
  SUPPORTED_TERM_SCOPE_MODELS = %w[
@@ -150,6 +151,7 @@ module CanvasSync
150
151
  assignment_groups: CanvasSync::Jobs::SyncAssignmentGroupsJob,
151
152
  context_modules: CanvasSync::Jobs::SyncContextModulesJob,
152
153
  context_module_items: CanvasSync::Jobs::SyncContextModuleItemsJob,
154
+ content_migrations: CanvasSync::Jobs::SyncContentMigrationsJob,
153
155
  }.with_indifferent_access
154
156
 
155
157
  root_chain = base_canvas_sync_chain(**kwargs, globals: options[:global] || kwargs[:globals])
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Jobs::SyncContentMigrationsJob do
4
+ describe "#perform" do
5
+ context "no parameters is specified" do
6
+ it "enqueues a ReportStarter for the proserv_content_migrations_csv" do
7
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report)
8
+ .with("self", "proserv_content_migrations_csv", { parameters: { } })
9
+ .and_return("id" => 1)
10
+
11
+ expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
12
+
13
+ CanvasSync::Jobs::SyncContentMigrationsJob.perform_now({})
14
+ end
15
+ end
16
+
17
+ context "updated_after parameters is specified" do
18
+ it "enqueues a ReportStarter for the proserv_content_migrations_csv and get data from given date" do
19
+ expect_any_instance_of(Bearcat::Client).to receive(:start_report)
20
+ .with("self", "proserv_content_migrations_csv", { parameters: { updated_after: 6.hours.ago.to_s } })
21
+ .and_return("id" => 1)
22
+
23
+ expect(CanvasSync::Jobs::ReportChecker).to receive(:set).and_call_original
24
+
25
+ set_batch_context(updated_after: 6.hours.ago.to_s)
26
+ CanvasSync::Jobs::SyncContentMigrationsJob.perform_now({})
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe CanvasSync::Processors::ContentMigrationsProcessor do
4
+ let(:subject) { CanvasSync::Processors::ContentMigrationsProcessor }
5
+
6
+ describe "#process" do
7
+ it "inserts content migrations" do
8
+ expect {
9
+ subject.process("spec/support/fixtures/reports/content_migrations.csv", {}, 1)
10
+ }.to change { ContentMigration.count }.by(2)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # #
2
+ # AUTO GENERATED MODEL
3
+ # This model was auto generated by the CanvasSync Gem.
4
+ # You can customize it as needed, but make sure you test
5
+ # any changes you make to the auto generated methods.
6
+ #
7
+
8
+
9
+ class ContentMigration < ApplicationRecord
10
+ include CanvasSync::Record
11
+ include CanvasSync::Concerns::ApiSyncable
12
+
13
+ validates :canvas_id, uniqueness: true, presence: true
14
+ belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
15
+
16
+ end
@@ -0,0 +1,30 @@
1
+ # #
2
+ # AUTO GENERATED MIGRATION
3
+ # This migration was auto generated by the CanvasSync Gem.
4
+ # You can add new columns to this table, but removing or
5
+ # re-naming ones created here may break Canvas Syncing.
6
+ #
7
+
8
+
9
+ class CreateContentMigrations < ActiveRecord::Migration[5.1]
10
+ def change
11
+ create_table :content_migrations do |t|
12
+ t.bigint :canvas_id
13
+ t.bigint :canvas_context_id
14
+ t.string :canvas_context_type
15
+ t.string :workflow_state
16
+ t.text :migration_settings
17
+ t.datetime :started_at
18
+ t.datetime :finished_at
19
+ t.float :progress
20
+ t.bigint :canvas_source_course_id
21
+ t.string :migration_type
22
+ t.bigint :canvas_child_subscription_id
23
+ t.bigint :canvas_root_account_id
24
+
25
+ t.timestamps
26
+ end
27
+
28
+ add_index :content_migrations, :canvas_id, unique: true
29
+ end
30
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2021_10_01_184920) do
13
+ ActiveRecord::Schema.define(version: 2022_03_08_072643) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -110,6 +110,24 @@ ActiveRecord::Schema.define(version: 2021_10_01_184920) do
110
110
  t.string "batch_bid"
111
111
  end
112
112
 
113
+ create_table "content_migrations", force: :cascade do |t|
114
+ t.bigint "canvas_id"
115
+ t.bigint "canvas_context_id"
116
+ t.string "canvas_context_type"
117
+ t.string "workflow_state"
118
+ t.text "migration_settings"
119
+ t.datetime "started_at"
120
+ t.datetime "finished_at"
121
+ t.float "progress"
122
+ t.bigint "canvas_source_course_id"
123
+ t.string "migration_type"
124
+ t.bigint "canvas_child_subscription_id"
125
+ t.bigint "canvas_root_account_id"
126
+ t.datetime "created_at", null: false
127
+ t.datetime "updated_at", null: false
128
+ t.index ["canvas_id"], name: "index_content_migrations_on_canvas_id", unique: true
129
+ end
130
+
113
131
  create_table "context_module_items", force: :cascade do |t|
114
132
  t.bigint "canvas_id"
115
133
  t.bigint "canvas_context_module_id"