canvas_sync 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +5 -5
  2. data/lib/canvas_sync/generators/install_live_events_generator.rb +5 -1
  3. data/lib/canvas_sync/generators/templates/migrations/create_accounts.rb +1 -1
  4. data/lib/canvas_sync/generators/templates/migrations/create_admins.rb +1 -1
  5. data/lib/canvas_sync/generators/templates/migrations/create_assignment_groups.rb +1 -1
  6. data/lib/canvas_sync/generators/templates/migrations/create_assignments.rb +1 -1
  7. data/lib/canvas_sync/generators/templates/migrations/create_context_module_items.rb +1 -1
  8. data/lib/canvas_sync/generators/templates/migrations/create_context_modules.rb +1 -1
  9. data/lib/canvas_sync/generators/templates/migrations/create_courses.rb +1 -1
  10. data/lib/canvas_sync/generators/templates/migrations/create_enrollments.rb +1 -1
  11. data/lib/canvas_sync/generators/templates/migrations/create_roles.rb +1 -1
  12. data/lib/canvas_sync/generators/templates/migrations/create_sections.rb +1 -1
  13. data/lib/canvas_sync/generators/templates/migrations/create_submissions.rb +1 -1
  14. data/lib/canvas_sync/generators/templates/migrations/create_terms.rb +1 -1
  15. data/lib/canvas_sync/generators/templates/migrations/create_users.rb +1 -1
  16. data/lib/canvas_sync/generators/templates/models/account.rb +1 -1
  17. data/lib/canvas_sync/generators/templates/models/admin.rb +1 -1
  18. data/lib/canvas_sync/generators/templates/models/assignment.rb +1 -1
  19. data/lib/canvas_sync/generators/templates/models/assignment_group.rb +1 -1
  20. data/lib/canvas_sync/generators/templates/models/context_module.rb +8 -1
  21. data/lib/canvas_sync/generators/templates/models/context_module_item.rb +8 -1
  22. data/lib/canvas_sync/generators/templates/models/course.rb +1 -1
  23. data/lib/canvas_sync/generators/templates/models/enrollment.rb +1 -1
  24. data/lib/canvas_sync/generators/templates/models/role.rb +1 -1
  25. data/lib/canvas_sync/generators/templates/models/section.rb +2 -1
  26. data/lib/canvas_sync/generators/templates/models/submission.rb +1 -1
  27. data/lib/canvas_sync/generators/templates/models/term.rb +1 -1
  28. data/lib/canvas_sync/generators/templates/models/user.rb +1 -1
  29. data/lib/canvas_sync/generators/templates/services/live_events/assignment_event.rb +33 -0
  30. data/lib/canvas_sync/generators/templates/services/live_events/assignment_group_event.rb +24 -0
  31. data/lib/canvas_sync/generators/templates/services/live_events/base_event.rb +22 -0
  32. data/lib/canvas_sync/generators/templates/services/live_events/course_event.rb +20 -0
  33. data/lib/canvas_sync/generators/templates/services/live_events/course_section_event.rb +18 -0
  34. data/lib/canvas_sync/generators/templates/services/live_events/enrollment_event.rb +20 -0
  35. data/lib/canvas_sync/generators/templates/services/live_events/grade_event.rb +26 -0
  36. data/lib/canvas_sync/generators/templates/services/live_events/module_event.rb +16 -0
  37. data/lib/canvas_sync/generators/templates/services/live_events/module_item_event.rb +15 -0
  38. data/lib/canvas_sync/generators/templates/services/live_events/submission_event.rb +18 -0
  39. data/lib/canvas_sync/generators/templates/services/live_events/syllabus_event.rb +21 -0
  40. data/lib/canvas_sync/generators/templates/services/live_events/user_event.rb +19 -0
  41. data/lib/canvas_sync/version.rb +1 -1
  42. data/spec/canvas_sync/services/module_event_spec.rb +2 -2
  43. data/spec/canvas_sync/services/module_item_event_spec.rb +2 -2
  44. data/spec/dummy/app/models/account.rb +1 -1
  45. data/spec/dummy/app/models/admin.rb +1 -1
  46. data/spec/dummy/app/models/assignment.rb +1 -1
  47. data/spec/dummy/app/models/assignment_group.rb +3 -2
  48. data/spec/dummy/app/models/context_module.rb +8 -1
  49. data/spec/dummy/app/models/context_module_item.rb +8 -1
  50. data/spec/dummy/app/models/course.rb +1 -1
  51. data/spec/dummy/app/models/enrollment.rb +1 -1
  52. data/spec/dummy/app/models/role.rb +1 -1
  53. data/spec/dummy/app/models/section.rb +2 -1
  54. data/spec/dummy/app/models/submission.rb +1 -1
  55. data/spec/dummy/app/models/term.rb +1 -1
  56. data/spec/dummy/app/models/user.rb +1 -1
  57. data/spec/dummy/app/services/live_events/assignment_event.rb +19 -36
  58. data/spec/dummy/app/services/live_events/base_event.rb +26 -0
  59. data/spec/dummy/app/services/live_events/course_event.rb +15 -27
  60. data/spec/dummy/app/services/live_events/course_section_event.rb +13 -39
  61. data/spec/dummy/app/services/live_events/enrollment_event.rb +17 -48
  62. data/spec/dummy/app/services/live_events/grade_event.rb +9 -34
  63. data/spec/dummy/app/services/live_events/module_event.rb +10 -29
  64. data/spec/dummy/app/services/live_events/module_item_event.rb +10 -28
  65. data/spec/dummy/app/services/live_events/submission_event.rb +12 -42
  66. data/spec/dummy/app/services/live_events/syllabus_event.rb +11 -20
  67. data/spec/dummy/app/services/live_events/user_event.rb +14 -25
  68. data/spec/dummy/db/migrate/{20190603215718_create_users.rb → 20190702203620_create_users.rb} +1 -1
  69. data/spec/dummy/db/migrate/{20190603220011_create_courses.rb → 20190702203621_create_courses.rb} +1 -1
  70. data/spec/dummy/db/migrate/{20190604193942_create_accounts.rb → 20190702203622_create_accounts.rb} +1 -1
  71. data/spec/dummy/db/migrate/{20190603215721_create_terms.rb → 20190702203623_create_terms.rb} +1 -1
  72. data/spec/dummy/db/migrate/{20190603220013_create_enrollments.rb → 20190702203624_create_enrollments.rb} +1 -1
  73. data/spec/dummy/db/migrate/{20190603215722_create_sections.rb → 20190702203625_create_sections.rb} +1 -1
  74. data/spec/dummy/db/migrate/{20190603192310_create_assignments.rb → 20190702203626_create_assignments.rb} +1 -1
  75. data/spec/dummy/db/migrate/{20190521003447_create_submissions.rb → 20190702203627_create_submissions.rb} +1 -1
  76. data/spec/dummy/db/migrate/{20190606161037_create_roles.rb → 20190702203628_create_roles.rb} +1 -1
  77. data/spec/dummy/db/migrate/{20190521003449_create_admins.rb → 20190702203629_create_admins.rb} +1 -1
  78. data/spec/dummy/db/migrate/{20190521003450_create_assignment_groups.rb → 20190702203630_create_assignment_groups.rb} +1 -1
  79. data/spec/dummy/db/migrate/{20190521003451_create_context_modules.rb → 20190702203631_create_context_modules.rb} +1 -1
  80. data/spec/dummy/db/migrate/{20190603193502_create_context_module_items.rb → 20190702203632_create_context_module_items.rb} +1 -1
  81. data/spec/dummy/db/schema.rb +1 -1
  82. metadata +41 -67
  83. data/lib/canvas_sync/generators/templates/services/live_events/assignment/assignment_created_event.rb +0 -6
  84. data/lib/canvas_sync/generators/templates/services/live_events/assignment/assignment_event.rb +0 -54
  85. data/lib/canvas_sync/generators/templates/services/live_events/assignment/assignment_updated_event.rb +0 -6
  86. data/lib/canvas_sync/generators/templates/services/live_events/course/course_created_event.rb +0 -6
  87. data/lib/canvas_sync/generators/templates/services/live_events/course/course_event.rb +0 -36
  88. data/lib/canvas_sync/generators/templates/services/live_events/course/course_updated_event.rb +0 -6
  89. data/lib/canvas_sync/generators/templates/services/live_events/course_section/course_section_created_event.rb +0 -6
  90. data/lib/canvas_sync/generators/templates/services/live_events/course_section/course_section_event.rb +0 -48
  91. data/lib/canvas_sync/generators/templates/services/live_events/course_section/course_section_updated_event.rb +0 -6
  92. data/lib/canvas_sync/generators/templates/services/live_events/enrollment/enrollment_created_event.rb +0 -6
  93. data/lib/canvas_sync/generators/templates/services/live_events/enrollment/enrollment_event.rb +0 -55
  94. data/lib/canvas_sync/generators/templates/services/live_events/enrollment/enrollment_updated_event.rb +0 -6
  95. data/lib/canvas_sync/generators/templates/services/live_events/grade/grade_changed_event.rb +0 -6
  96. data/lib/canvas_sync/generators/templates/services/live_events/grade/grade_event.rb +0 -55
  97. data/lib/canvas_sync/generators/templates/services/live_events/module/module_created_event.rb +0 -6
  98. data/lib/canvas_sync/generators/templates/services/live_events/module/module_event.rb +0 -39
  99. data/lib/canvas_sync/generators/templates/services/live_events/module/module_updated_event.rb +0 -6
  100. data/lib/canvas_sync/generators/templates/services/live_events/module_item/module_item_created_event.rb +0 -6
  101. data/lib/canvas_sync/generators/templates/services/live_events/module_item/module_item_event.rb +0 -37
  102. data/lib/canvas_sync/generators/templates/services/live_events/module_item/module_item_updated_event.rb +0 -6
  103. data/lib/canvas_sync/generators/templates/services/live_events/submission/submission_created_event.rb +0 -6
  104. data/lib/canvas_sync/generators/templates/services/live_events/submission/submission_event.rb +0 -52
  105. data/lib/canvas_sync/generators/templates/services/live_events/submission/submission_updated_event.rb +0 -6
  106. data/lib/canvas_sync/generators/templates/services/live_events/syllabus/syllabus_event.rb +0 -34
  107. data/lib/canvas_sync/generators/templates/services/live_events/syllabus/syllabus_updated_event.rb +0 -6
  108. data/lib/canvas_sync/generators/templates/services/live_events/user/user_created_event.rb +0 -6
  109. data/lib/canvas_sync/generators/templates/services/live_events/user/user_event.rb +0 -34
  110. data/lib/canvas_sync/generators/templates/services/live_events/user/user_updated_event.rb +0 -6
  111. data/spec/dummy/db/test.sqlite3 +0 -0
  112. data/spec/dummy/log/development.log +0 -1248
  113. data/spec/dummy/log/test.log +0 -43258
  114. data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +0 -3
  115. data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 50ea86e0116f11f92019daae4edd22aa3a402355e1d910947e391a0f3b6ac000
4
- data.tar.gz: 5712f275605f93eefc0f0ab5f1711b31e20dbc29d9a5e2b56d39853745610a49
2
+ SHA1:
3
+ metadata.gz: f220a92d0d85cce6ff10b1ef1a10784039e93583
4
+ data.tar.gz: 0c305e04af7875261f6c36561b1b39e073f41c41
5
5
  SHA512:
6
- metadata.gz: f914d9934b0b7c7c31fc3e3188d9884a07aeb104a4b89b9815f2455ada59bf74f6f43b3eb8fdc3fbd994dcca48166fd108dc45ae415f8715197ac96f33b3a2df
7
- data.tar.gz: b56ddedc9b422d64bf319f2f425cb209b1889fbfd4a5992eb403ab1901efd2b3aaeaa7463c3ca9b4d32924e6b44fc0b8479084c6462796ea547a8d6e5fd516b9
6
+ metadata.gz: ec6ceaf390ae8a814420d927b1294b66492bd855b62ef9d80042e973871aac7dfb45b061861d503b8ee5303371e67c3df1446be4b159f7f8991ec237684007ad
7
+ data.tar.gz: 83c67e7bdd93c2ac6e068309955c04a08e8f6204481f667049cb3ac6dc8ba5212c31f5e25febde46a788bc5582d18c893cf421718f7604a2399623289e9ff422
@@ -13,6 +13,10 @@ module CanvasSync
13
13
  # You can customize it as needed, but make sure you test
14
14
  # any changes you make to the auto generated methods.
15
15
  #
16
+ # LiveEvent message formats can be found at https://canvas.instructure.com/doc/api/file.live_events.html
17
+ # In the general case, LiveEvent message content should not be trusted - it is highly possible that events may
18
+ # arrive out of order. Most of the CanvasSync LiveEvent templates solve this by always fetching the object from the API.
19
+ #
16
20
  HERE
17
21
  end
18
22
 
@@ -28,7 +32,7 @@ module CanvasSync
28
32
  CanvasSync.validate_live_events!(events)
29
33
 
30
34
  events.each do |event|
31
- Dir.glob("#{File.dirname(__FILE__)}/templates/services/live_events/#{event}/*.rb") do |rb_file|
35
+ Dir.glob("#{File.dirname(__FILE__)}/templates/services/live_events/#{event}_event.rb") do |rb_file|
32
36
  template rb_file.to_s, "app/services/live_events/#{File.basename(rb_file)}"
33
37
  end
34
38
  end
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateAccounts < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateAdmins < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateAssignmentGroups < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateAssignments < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateContextModuleItems < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateContextModules < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateCourses < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateEnrollments < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateRoles < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateSections < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateSubmissions < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateTerms < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_migration_warning %>
1
+ # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class CreateUsers < ActiveRecord::Migration[5.1]
4
4
  def change
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Account < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Admin < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Assignment < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class AssignmentGroup < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,10 +1,17 @@
1
- <%= autogenerated_migration_warning %>
1
+ # # <%= autogenerated_migration_warning %>
2
2
 
3
3
  # A ContextModule is the same as a Canvas Module. They're called ContextModules for 2 reasons:
4
4
  # 1 - Module is a reserved word in Rails and you can't call a model a Module
5
5
  # 2 - Canvas calls them ContextModules
6
6
  class ContextModule < ApplicationRecord
7
+ include CanvasSync::ApiSyncable
8
+
7
9
  belongs_to :context, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_context_id, foreign_type: :canvas_context_type
8
10
  has_many :context_module_items, primary_key: :canvas_id, foreign_key: :canvas_context_module_id
9
11
  has_many :assignments, through: :context_module_items
12
+
13
+ api_syncable({
14
+ # TODO If your tool Syncs ContextModules, please complete this and merge it into CanvasSync
15
+ }, -> (api) { api.course_module(canvas_context_id, canvas_id) })
16
+
10
17
  end
@@ -1,7 +1,14 @@
1
- # <%= autogenerated_migration_warning %>
1
+ # # <%= autogenerated_migration_warning %>
2
2
 
3
3
  class ContextModuleItem < ApplicationRecord
4
+ include CanvasSync::ApiSyncable
5
+
4
6
  belongs_to :context_module, primary_key: :canvas_id, foreign_key: :canvas_context_module_id, optional: true
5
7
  belongs_to :content, polymorphic: true, optional: true, primary_key: :canvas_id, foreign_key: :canvas_content_id, foreign_type: :canvas_content_type
6
8
  belongs_to :assignment, foreign_key: :canvas_assignment_id, primary_key: :canvas_id
9
+
10
+ api_syncable({
11
+ # TODO If your tool Syncs ContextModuleItems, please complete this and merge it into CanvasSync
12
+ }, -> (api) { api.module_item(context_module.context.canvas_id, context_module.canvas_id, canvas_id) })
13
+
7
14
  end
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Course < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Enrollment < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Role < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Section < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -14,5 +14,6 @@ class Section < ApplicationRecord
14
14
  name: :name,
15
15
  start_at: :start_at,
16
16
  end_at: :end_at,
17
+ workflow_state: ->(r){ 'active' },
17
18
  }, -> (api) { api.section(canvas_id) })
18
19
  end
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Submission < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class Term < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -1,4 +1,4 @@
1
- <%= autogenerated_model_warning %>
1
+ # <%= autogenerated_model_warning %>
2
2
 
3
3
  class User < ApplicationRecord
4
4
  include CanvasSync::ApiSyncable
@@ -0,0 +1,33 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class AssignmentEvent < LiveEvents::BaseEvent
5
+
6
+ def process
7
+ canvas_assignment_id = local_canvas_id(payload[:assignment_id])
8
+ assignment = Assignment.where(canvas_id: canvas_assignment_id).first_or_initialize
9
+ assignment.context_id = canvas_course_id
10
+ assignment.sync_from_api
11
+ end
12
+
13
+ private
14
+
15
+ # This could be nil if the context type for this assignment is not 'Course' of if a local course was not found
16
+ def canvas_course_id
17
+ payload[:context_type] == "Course" ? local_canvas_id(payload[:context_id]) : nil
18
+ end
19
+
20
+ # This could be nil if the context type for this assignment is not 'Course' of if a local course was not found
21
+ def course
22
+ @course ||= begin
23
+ course = Course.where(canvas_id: canvas_course_id).first_or_initialize
24
+ course.sync_from_api unless course.persisted?
25
+ course
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ class AssignmentCreatedEvent < LiveEvents::AssignmentEvent; end
32
+ class AssignmentUpdatedEvent < LiveEvents::AssignmentEvent; end
33
+ end
@@ -0,0 +1,24 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class AssignmentGroupEvent < LiveEvents::BaseEvent
5
+
6
+ def process
7
+ canvas_assignment_group_id = local_canvas_id(payload[:assignment_group_id])
8
+ assignment_group = AssignmentGroup.where(canvas_id: canvas_assignment_group_id).first_or_initialize
9
+ assignment_group.canvas_course_id = canvas_course_id
10
+ assignment_group.sync_from_api
11
+ end
12
+
13
+ private
14
+
15
+ # This could be nil if the context type for this assignment is not 'Course' of if a local course was not found
16
+ def canvas_course_id
17
+ payload[:context_type] == "Course" ? local_canvas_id(payload[:context_id]) : nil
18
+ end
19
+
20
+ end
21
+
22
+ class AssignmentGroupCreatedEvent < LiveEvents::AssignmentGroupEvent; end
23
+ class AssignmentGroupUpdatedEvent < LiveEvents::AssignmentGroupEvent; end
24
+ end
@@ -1,6 +1,8 @@
1
1
  # <%= autogenerated_event_warning %>
2
2
 
3
3
  module LiveEvents
4
+ class RetryLiveEventJob < StandardError; end
5
+
4
6
  class BaseEvent < CanvasSync::Job
5
7
  attr_accessor :raw_payload
6
8
  attr_accessor :payload
@@ -10,11 +12,31 @@ module LiveEvents
10
12
  @raw_payload = event_payload
11
13
  @metadata = HashWithIndifferentAccess.new(event_payload["attributes"])
12
14
  @payload = HashWithIndifferentAccess.new(event_payload["body"])
15
+ process_with_retry
16
+ end
17
+
18
+ def process
19
+ raise "process must be implemented in your subclass"
13
20
  end
14
21
 
15
22
  # Live events will use a canvas global ID (cross shard) for any ID's provided. This method will return the local ID.
16
23
  def local_canvas_id(id)
17
24
  id.to_i % 10_000_000_000_000
18
25
  end
26
+
27
+ private
28
+
29
+ # Sometimes a creation and update event get sent by Canvas at almost the exact same time. This means
30
+ # that there is sometimes a race condition that causes them to both try to save a new record at the same time.
31
+ # If that happens, just wait a few seconds and try again -- the second try should be able to see that
32
+ # the save already occured, and it will just update the row..
33
+ def process_with_retry
34
+ tries ||= 5
35
+ process
36
+ rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid, RetryLiveEventJob => e
37
+ raise e if (tries -= 1).zero?
38
+ sleep 5
39
+ retry
40
+ end
19
41
  end
20
42
  end
@@ -0,0 +1,20 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class CourseEvent < LiveEvents::BaseEvent
5
+
6
+ def process
7
+ course = Course.where(canvas_id: local_canvas_id(payload[:course_id])).first_or_initialize
8
+ course.canvas_account_id = local_canvas_id(payload[:account_id])
9
+ if course.account.nil?
10
+ acc = Account.new(canvas_id: course.canvas_account_id)
11
+ acc.sync_from_api
12
+ end
13
+ course.sync_from_api
14
+ end
15
+
16
+ end
17
+
18
+ class CourseCreatedEvent < LiveEvents::CourseEvent; end
19
+ class CourseUpdatedEvent < LiveEvents::CourseEvent; end
20
+ end
@@ -0,0 +1,18 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class CourseSectionEvent < LiveEvents::BaseEvent
5
+
6
+ def process
7
+ section = Section.where(canvas_id: local_canvas_id(payload[:course_section_id])).first_or_initialize
8
+ section.sync_from_api
9
+ # A section change could constitute a crosslisting change, which means
10
+ # we need to make sure all our enrollments are pointing to the correct course
11
+ section.enrollments.update_all(canvas_course_id: section.canvas_course_id)
12
+ end
13
+
14
+ end
15
+
16
+ class CourseSectionCreatedEvent < LiveEvents::CourseSectionEvent; end
17
+ class CourseSectionUpdatedEvent < LiveEvents::CourseSectionEvent; end
18
+ end
@@ -0,0 +1,20 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class EnrollmentEvent < LiveEvents::BaseEvent
5
+ attr_accessor :enrollment
6
+
7
+ def process()
8
+ @enrollment = Enrollment.where(canvas_id: local_canvas_id(payload[:enrollment_id])).first_or_initialize
9
+ enrollment.canvas_course_id = local_canvas_id(payload[:course_id])
10
+ enrollment.sync_from_api
11
+ if enrollment.user.nil?
12
+ u = User.new(canvas_id: enrollment.canvas_user_id)
13
+ u.sync_from_api
14
+ end
15
+ end
16
+ end
17
+
18
+ class EnrollmentCreatedEvent < LiveEvents::EnrollmentEvent; end
19
+ class EnrollmentUpdatedEvent < LiveEvents::EnrollmentEvent; end
20
+ end
@@ -0,0 +1,26 @@
1
+ # <%= autogenerated_event_warning %>
2
+
3
+ module LiveEvents
4
+ class GradeEvent < LiveEvents::BaseEvent
5
+
6
+ def process
7
+ raise "process must be implemented in your subclass"
8
+ end
9
+
10
+ private
11
+
12
+ def submission
13
+ Submission.find_by(canvas_submission_id: local_canvas_id(payload[:submission_id]))
14
+ end
15
+
16
+ def assignment
17
+ Assignment.find_by(canvas_assignment_id: local_canvas_id(payload[:assignment_id]))
18
+ end
19
+
20
+ def user
21
+ User.find_by(canvas_user_id: local_canvas_id(payload[:user_id]))
22
+ end
23
+ end
24
+
25
+ class GradeChangedEvent < LiveEvents::GradeEvent; end
26
+ end