Skip to content

Instantly share code, notes, and snippets.

@jstanley0
Last active March 20, 2017 17:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstanley0/efabdc47525c2da7aa46 to your computer and use it in GitHub Desktop.
Save jstanley0/efabdc47525c2da7aa46 to your computer and use it in GitHub Desktop.
Fake Analytics for Canvas
# this will create a course and populate it with synthetic analytics data
# (early / late / missing submissions, grades, messages, page views and participations)
# to use: in a canvas rails console
# > load 'fake_analytics.rb'
# > FakeAnalytics.create_course!(teacher)
# where teacher is the user to enroll as teacher in the new course
class FakeAnalytics
ASSIGNMENT_COUNT = 7
ASSIGNMENTS_WITH_NO_DUE_DATE_COUNT = 2
STUDENT_COUNT = 5
MAX_MESSAGE_COUNT = 10
MAX_PAGE_VIEW_COUNT = 2000
PARTICIPATION_PERCENTAGE = 15
def self.create_course!(teacher, start_date: 3.months.ago)
raise "probably not a good idea" if Rails.env.production?
enable_stuff
FakeAnalytics.new.run(teacher, start_date)
end
def self.enable_stuff
Setting.set('enable_page_views', 'db') unless PageView.page_views_enabled?
Account.default.set_service_availability('analytics', true) unless Account.default.service_enabled? 'analytics'
end
def run(teacher, start_date)
@teacher = teacher
@start_date = start_date
@course = Course.create! :start_at => @start_date, :name => 'fake analytics course'
@course.enroll_teacher(@teacher).accept!
@course.offer!
create_assignments
create_students
create_submissions
create_messages
create_page_views
@course
end
def create_assignments
@assignments = []
ASSIGNMENT_COUNT.times do |x|
a = @course.assignments.create :title => "Assignment #{x + 1}"
a.due_at = interpolate_date(x.to_f / ASSIGNMENT_COUNT) if x < ASSIGNMENT_COUNT - ASSIGNMENTS_WITH_NO_DUE_DATE_COUNT
a.points_possible = 100
a.submission_types = 'online_text_entry'
a.save!
@assignments << a
end
@assignments
end
def create_students
@students = []
STUDENT_COUNT.times do |x|
u = User.create! :name => "Student #{('A'.ord + x).chr}"
u.register!
@course.enroll_student(u).accept!
u.pseudonyms.create! unique_id: "#{u.uuid}@example.edu", account: @course.root_account
@students << u
end
@students
end
def create_submissions
@assignments.each do |assignment|
@students.each do |student|
if rand(3) > 0
create_submission(assignment, student)
end
end
end
end
def create_submission(assignment, student)
submission = assignment.submit_homework(student, :submission_type => 'online_text_entry', :body => 'blah')
submission.submitted_at = assignment.due_at ?
[assignment.due_at + (rand(1000000) - 750000).seconds, @start_date].max :
random_date
submission.cached_due_date = assignment.due_at # this shouldn't be necessary. why is this sometimes nil otherwise
submission.save!
assignment.grade_student(student, :grader => @teacher, :score => rand(100))
end
def create_messages
@students.each do |student|
conversation = Conversation.initiate([@teacher, student], true)
rand(MAX_MESSAGE_COUNT).times do
message = conversation.add_message(rand(2) == 0 ? @teacher : student, 'blah!')
message.update_attribute(:created_at, random_date)
end
end
end
def create_page_views
@students.each do |student|
rand(MAX_PAGE_VIEW_COUNT).times do
create_page_view(student)
end
end
# dump pageviews into Cassandra if we're using that; otherwise, do rollups
if PageView.cassandra?
PageView::CassandraMigrator.new.run
PageView.delete_all
else
Analytics::PageViewRoller.rollup_all(:start_day => @start_date, :end_day => Date.today)
end
end
def create_asset_user_access(student)
assignment = @course.assignments.first
aua = @course.asset_user_accesses.build
aua.user_id = student.id
aua.asset_code = assignment.asset_string
aua.asset_group_code = assignment.assignment_group.asset_string
aua.last_access = random_date
aua.asset_category = 'assignments'
aua.action_level = 'participate'
aua.membership_type = 'StudentEnrollment'
aua.save!
aua
end
def create_page_view(student)
pv = student.page_views.build
pv.request_id = SecureRandom.uuid
pv.session_id = SecureRandom.uuid
pv.context = @course
pv.interaction_seconds = 1
pv.controller = 'submissions'
pv.action = 'create'
if rand(100) < PARTICIPATION_PERCENTAGE
aua = create_asset_user_access(student)
pv.participated = true
pv.asset_user_access_id = aua.id
end
pv.save!
pv.update_attribute(:created_at, random_date)
pv
end
def interpolate_date(fraction)
Time.at(@start_date.to_i + fraction * (Time.now.to_i - @start_date.to_i))
end
def random_date
interpolate_date(rand)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment