Last active
October 3, 2018 22:50
-
-
Save robert-carroll/7a767462ef0f00e4b24b19a1236481da to your computer and use it in GitHub Desktop.
live events ims format to flat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://github.com/instructure/canvas-lms/blob/master/lib/canvas/live_events.rb#L19 | |
# https://canvas.instructure.com/doc/api/file.live_events.html | |
# this file parses the JSON data | |
# making best attempts to map JSON data to documented fields | |
class ParseEvents | |
# mimic this, https://github.com/instructure/switchman/blob/master/app/models/switchman/shard_internal.rb | |
def local_id(any_id) | |
any_id.to_i % 10_000_000_000_000 | |
end | |
def meta(data) | |
md = {} | |
# event fields | |
md['uuid'] = nil | |
md['event_type'] = nil | |
md['event_time'] = nil | |
# listed metadata fields | |
md['user_id'] = nil | |
md['real_user_id'] = nil | |
md['user_login'] = nil | |
md['user_agent'] = nil | |
md['root_account_uuid'] = nil | |
md['root_account_id'] = nil | |
md['root_account_lti_guid'] = nil | |
md['context_type'] = nil | |
md['context_id'] = nil | |
md['role'] = nil | |
md['hostname'] = nil | |
md['producer'] = nil | |
md['request_id'] = nil | |
md['session_id'] = nil | |
md['user_account_id'] = nil | |
md['user_sis_id'] = nil | |
# for events originating as part of an asynchronous job, the following fields may be set | |
md['job_id'] = nil | |
md['job_tag'] = nil | |
# md['root_account_uuid'] = nil | |
# md['root_account_id'] = nil | |
# md['root_account_lti_guid']= nil | |
# event fields | |
md['uuid'] = data['id'].sub(/^urn:uuid:/, '') | |
md['event_type'] = data['type'] | |
md['event_time'] = data['eventTime'] | |
# actor | |
if data.key?('actor') && data['actor'].key?('extensions') | |
actor = data['actor']['extensions']['com.instructure.canvas'] | |
md['global_user_id'] = actor['entity_id'] | |
md['canvas_user_id'] = local_id(actor['entity_id']) | |
md['user_login'] = actor['user_login'] | |
md['root_account_id'] = actor['root_account_id'] | |
md['root_account_lti_guid'] = actor['root_account_lti_guid'] | |
md['root_account_uuid'] = actor['root_account_uuid'] | |
end | |
# membership | |
if data.key?('membership') | |
membership = data['membership'] | |
md['role'] = membership['roles'].join(',') | |
end | |
# session | |
if data.key?('session') | |
session = data['session'] | |
md['session_id'] = session['id'].sub(/^urn:instructure:canvas:session:/, '') | |
md['session_type'] = session['type'] | |
end | |
# extensions | |
if data.key?('extensions') | |
extensions = data['extensions']['com.instructure.canvas'] | |
md['hostname'] = extensions['hostname'] | |
md['request_id'] = extensions['request_id'] | |
md['user_agent'] = extensions['user_agent'] | |
md['version'] = extensions['version'] | |
end | |
md | |
end | |
def account_notification_created(data) | |
# puts data | |
end | |
def asset_accessed(data) | |
# https://www.imsglobal.org/sites/default/files/caliper/v1p1/caliper-spec-v1p1/caliper-spec-v1p1.html#navigationEvent | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
# body fields | |
asset_type = data['object']['extensions']['com.instructure.canvas']['asset_type'] | |
asset_id = data['object']['extensions']['com.instructure.canvas']['entity_id'] | |
asset_subtype = data['object']['extensions']['com.instructure.canvas'].key?('asset_subtype') ? data['object']['extensions']['com.instructure.canvas']['asset_subtype'] : nil | |
begin | |
return { | |
'uuid' => metadata['uuid'], | |
'event_time' => metadata['event_time'], | |
'global_user_id' => metadata['global_user_id'], | |
'canvas_user_id' => metadata['canvas_user_id'], | |
'user_login' => metadata['user_login'], | |
'roles' => metadata['roles'], | |
'course_id' => asset_type == 'course' && !asset_id.nil? ? asset_id : nil, | |
'subtype' => data['object']['name'], | |
'asset_type' => asset_type, | |
'asset_id' => asset_id, | |
'asset_subtype' => asset_subtype, | |
'request_id' => metadata['request_id'], | |
'session_id' => metadata['session_id'], | |
'user_agent' => metadata['user_agent'], | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def assignment_created(data) | |
# puts data | |
end | |
def assignment_updated(data) | |
# puts data | |
end | |
def attachment_created(data) | |
# puts data | |
end | |
def attachment_deleted(data) | |
# puts data | |
end | |
def attachment_updated(data) | |
# puts data | |
end | |
def content_migration_completed(data) | |
# puts data | |
end | |
def course_created(data) | |
# puts data | |
end | |
def course_updated(data) | |
# puts data | |
end | |
def discussion_entry_created(data) | |
# 1% of events are missing group and membership | |
# https://www.imsglobal.org/sites/default/files/caliper/v1p1/caliper-spec-v1p1/caliper-spec-v1p1.html#messageEvent | |
# these 2 properties are optional in the Caliper docs | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
if data.key?('group') && data['group'].key?('id') | |
course_id = data['group']['id'].sub('urn:instructure:canvas:course:', '') | |
else course_id = nil | |
end | |
if data.key?('membership') && data['membership']['member'].key?('id') | |
parent_discussion_entry_author_id = data['membership']['member']['id'].sub('urn:instructure:canvas:user:', '') | |
else parent_discussion_entry_author_id = nil | |
end | |
begin | |
return { | |
# metadata fields | |
'uuid' => metadata['uuid'], | |
'event_time' => metadata['event_time'], | |
'course_id' => course_id, | |
# body fields | |
'discussion_entry_id' => data['object']['id'].sub('urn:instructure:canvas:discussionEntry:', ''), | |
'parent_discussion_entry_id' => nil, | |
'parent_discussion_entry_author_id' => parent_discussion_entry_author_id, | |
'discussion_topic_id' => data['object']['isPartOf']['id'].sub('urn:instructure:canvas:discussion:', ''), | |
'text' => data['object']['body'] | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def discussion_topic_created(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
begin | |
return { | |
# metadata fields | |
'uuid' => metadata['uuid'], | |
'event_time' => metadata['event_time'], | |
'course_id' => data.key?('group') ? data['group']['id'].sub('urn:instructure:canvas:course:', '') : nil, | |
# 'entity_id' => data['group']['extensions']['com.instructure.canvas']['entity_id'], | |
'instructor_id' => data.key?('membership') ? data['membership']['member']['id'].sub('urn:instructure:canvas:user:', '') : nil, | |
'discussion_type' => data['object']['type'], # Thread | |
# body fields | |
'discussion_topic_id' => data['object']['id'].sub('urn:instructure:canvas:discussion:', ''), | |
'is_announcement' => data['object']['extensions']['com.instructure.canvas']['is_announcement'], | |
'title' => data['object']['name'], | |
'body' => data['object'].key?('body') ? data['object']['body'] : nil # not seen | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def enrollment_created(data) | |
# extract metadata | |
metadata = meta(data) | |
begin | |
extensions = data['object']['extensions']['com.instructure.canvas'] | |
return { | |
# metadata fields | |
'uuid' => data['id'].sub(/^urn:uuid:/, ''), | |
# body fields | |
'enrollment_id' => data['object']['id'].sub(/^.+enrollment:/, ''), | |
'course_id' => extensions['course_id'].sub('urn:instructure:canvas:course:', ''), | |
'user_id' => extensions['user_id'].sub('urn:instructure:canvas:user:', ''), | |
'user_name' => extensions['user_name'], | |
'type' => extensions['type'], | |
'created_at' => data['object']['dateCreated'], | |
'updated_at' => data['object']['dateUpdated'], | |
'limit_privileges_to_course_section' => extensions['limit_privileges_to_course_section'], | |
'course_section_id' => extensions['course_section_id'].sub(/^.+section:/, ''), | |
'associated_user_id' => extensions['associated_user_id'], | |
'workflow_state' => extensions['workflow_state'] | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def enrollment_state_created(data) | |
# puts data | |
end | |
def enrollment_state_updated(data) | |
# puts data | |
end | |
def enrollment_updated(data) | |
# puts data | |
end | |
def grade_change(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
puts metadata | |
# begin | |
# return { | |
# 'submission_id' => data['object']['extensions']['com.instructure.canvas']['entity_id'], | |
# 'assignment_id' => data['object']['assignable']['id'].sub('urn:instructure:canvas:assignment:', ''), | |
# 'grade' => data['generated']['extensions']['com.instructure.canvas']['grade'], | |
# 'old_grade' => nil, | |
# # wtf "scoreGiven": {"numberStr": "1.0"} "scoreGiven" => 13.125 | |
# # https://www.idatalobal.org/sites/default/files/caliper/v1p1/caliper-spec-v1p1/caliper-spec-v1p1.html#score | |
# # scoreGiven - decimal - A number with a fractional part denoted by a decimal separator that designates the actual score awarded. | |
# 'score' => !data['generated']['scoreGiven'].key?('numberStr') ? data['generated']['scoreGiven'] : data['generated']['scoreGiven']['numberStr'], | |
# 'old_score' => nil, | |
# 'points_possible' => !data['generated']['maxScore'].key?('numberStr') ? data['generated']['maxScore'] : data['generated']['maxScore']['numberStr'], | |
# 'old_points_possible' => nil, | |
# 'grader_id' => data['generated'].key?('scoredBy') ? data['generated']['scoredBy'].sub('urn:instructure:canvas:user:', '') : nil, | |
# 'user_id' => data['object'].key?('assignee') ? data['object']['assignee']['extensions']['com.instructure.canvas']['sis_id'] : nil, | |
# 'muted' => nil, | |
# 'grading_complete' => nil | |
# } | |
# rescue => e | |
# puts e | |
# puts data | |
# end | |
end | |
def group_category_created(data) | |
# puts data | |
end | |
def group_created(data) | |
# puts data | |
end | |
def group_membership_created(data) | |
# puts data | |
end | |
def group_membership_updated(data) | |
# puts data | |
end | |
def group_updated(data) | |
# puts data | |
end | |
def logged_in(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
# body fields | |
if data['object'].key?('extensions') && data['object']['extensions']['com.instructure.canvas'].key?('redirect_url') | |
redirect_url = data['object']['extensions']['com.instructure.canvas']['redirect_url'] | |
else redirect_url = nil | |
end | |
begin | |
return { | |
'uuid' => metadata['uuid'], | |
'global_user_id' => metadata['global_user_id'], | |
'canvas_user_id' => metadata['canvas_user_id'], | |
'user_login' => metadata['user_login'], | |
'login_at' => metadata['event_time'], | |
'redirect_url' => redirect_url, | |
'request_id' => metadata['request_id'], | |
'session_id' => metadata['session_id'], | |
'user_agent' => metadata['user_agent'], | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def logged_out(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
begin | |
return { | |
'uuid' => metadata['uuid'], | |
'global_user_id' => metadata['global_user_id'], | |
'canvas_user_id' => metadata['canvas_user_id'], | |
'user_login' => metadata['user_login'], | |
'logout_at' => metadata['event_time'], | |
'request_id' => metadata['request_id'], | |
'session_id' => metadata['session_id'], | |
'user_agent' => metadata['user_agent'], | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def module_created(data) | |
# puts data | |
end | |
def module_item_created(data) | |
# puts data | |
end | |
def module_item_updated(data) | |
# puts data | |
end | |
def module_updated(data) | |
# puts data | |
end | |
def plagiarism_resubmit(data) | |
# puts data | |
end | |
def quiz_submitted(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
# puts metadata | |
begin | |
return { | |
'uuid' => metadata['uuid'], | |
'global_user_id' => metadata['global_user_id'], | |
'canvas_user_id' => metadata['canvas_user_id'], | |
'user_login' => metadata['user_login'], | |
'submitted_at' => metadata['event_time'], | |
'request_id' => metadata['request_id'], | |
'session_id' => metadata['session_id'], | |
'user_agent' => metadata['user_agent'], | |
'course_id' => data['group']['extensions']['com.instructure.canvas']['entity_id'], | |
'quiz_id' => data['object']['assignable']['id'].sub('urn:instructure:canvas:quiz:', ''), | |
'submission_id' => data['object']['extensions']['com.instructure.canvas']['entity_id'] | |
} | |
rescue => e | |
puts e | |
puts data | |
end | |
end | |
def submission_created(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
# puts metadata | |
if data.key?('object') | |
obj = data['object'] | |
# type = obj['type'] | |
date_created = obj['dateCreated'] | |
body = !obj['body'].nil? ? obj['body'] : nil | |
attempt = !obj['count'].nil? ? obj['count'] : nil | |
end | |
if data.key?('object') && data['object'].key?('extensions') | |
subm_ext = data['object']['extensions']['com.instructure.canvas'] | |
submission_id = !subm_ext['entity_id'].nil? ? subm_ext['entity_id'] : nil | |
submission_type = !subm_ext['submission_type'].nil? ? subm_ext['submission_type'] : nil | |
submission_url = !subm_ext['url'].nil? ? subm_ext['url'] : nil | |
end | |
if data.key?('object') && data['object'].key?('assignable') | |
assignable = data['object']['assignable'] | |
assignment_id = !assignable['id'].nil? ? assignable['id'].sub('urn:instructure:canvas:assignment:', '') : nil | |
end | |
if data.key?('group') && data['group'].key?('extensions') | |
course_ext = data['group']['extensions']['com.instructure.canvas'] | |
course_id = !course_ext['entity_id'].nil? ? course_ext['entity_id'] : nil | |
end | |
return { | |
# metadata fields | |
'uuid' => metadata['uuid'], | |
'roles' => metadata['roles'], | |
'event_time' => metadata['event_time'], | |
'request_id' => metadata['request_id'], | |
'session_id' => metadata['session_id'], | |
'user_agent' => metadata['user_agent'], | |
'course_id' => course_id, | |
# body fields | |
'submission_id' => submission_id, | |
'assignment_id' => assignment_id, | |
'user_id' => metadata['global_user_id'], | |
'lti_user_id' => nil, | |
'submitted_at' => date_created, | |
'updated_at' => nil, | |
'score' => nil, | |
'grade' => nil, | |
'submission_type' => submission_type, | |
'body' => body, | |
'url' => submission_url, | |
'attempt' => attempt, | |
'lti_assignment_id' => nil, | |
'group_id' => course_id, | |
} | |
end | |
def submission_updated(data) | |
# puts data | |
# extract metadata | |
metadata = meta(data) | |
# puts metadata | |
if data.key?('object') | |
obj = data['object'] | |
# type = obj['type'] | |
date_created = obj['dateCreated'] | |
body = !obj['body'].nil? ? obj['body'] : nil | |
attempt = !obj['count'].nil? ? obj['count'] : nil | |
end | |
if data.key?('object') && data['object'].key?('extensions') | |
subm_ext = data['object']['extensions']['com.instructure.canvas'] | |
submission_id = !subm_ext['entity_id'].nil? ? subm_ext['entity_id'] : nil | |
submission_type = !subm_ext['submission_type'].nil? ? subm_ext['submission_type'] : nil | |
submission_url = !subm_ext['url'].nil? ? subm_ext['url'] : nil | |
end | |
if data.key?('object') && data['object'].key?('assignable') | |
assignable = data['object']['assignable'] | |
assignment_id = !assignable['id'].nil? ? assignable['id'].sub('urn:instructure:canvas:assignment:', '') : nil | |
end | |
if data.key?('group') && data['group'].key?('extensions') | |
course_ext = data['group']['extensions']['com.instructure.canvas'] | |
course_id = !course_ext['entity_id'].nil? ? course_ext['entity_id'] : nil | |
end | |
return { | |
# metadata fields | |
'uuid' => metadata['uuid'], | |
'roles' => metadata['roles'], | |
'event_time' => metadata['event_time'], | |
'course_id' => course_id, | |
# body fields | |
'submission_id' => submission_id, | |
'assignment_id' => assignment_id, | |
'user_id' => metadata['global_user_id'], | |
'lti_user_id' => nil, | |
'submitted_at' => date_created, | |
'updated_at' => nil, | |
'score' => nil, | |
'grade' => nil, | |
'submission_type' => submission_type, | |
'body' => body, | |
'url' => submission_url, | |
'attempt' => attempt, | |
'lti_assignment_id' => nil, | |
'group_id' => course_id, | |
} | |
end | |
def syllabus_updated(data) | |
# puts data | |
end | |
def user_account_association_created(data) | |
# puts data | |
end | |
def user_created(data) | |
# puts data | |
end | |
def user_updated(data) | |
# puts data | |
end | |
def wiki_page_created(data) | |
# puts data | |
end | |
def wiki_page_deleted(data) | |
# puts data | |
end | |
def wiki_page_updated(data) | |
# puts data | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment