canvas_sync 0.17.27 → 0.17.30

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: 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"