-
Notifications
You must be signed in to change notification settings - Fork 1
Manually Create Student Classroom Accounts
Run the following code on the panoptes API to create the relevant user accounts. Don't forget to copy the reporting logs out so you have a copy of the user credentials for logging in.
# frozen_string_literal: true
require 'securerandom'
def print_account_details(user)
puts "login: #{user.login}, password: #{user.password}, email: #{user.email}"
end
def account_num_prefix(account_number)
'%02d' % account_number
end
def log_account_errors(account)
puts account.errors.full_messages
end
def find_or_build_account(login, display_name, email)
account = User.find_or_initialize_by(login: login) do |u|
u.login = login
u.display_name = display_name
u.email = email
u.password = SecureRandom.hex(8)
u.valid_email = false
u.global_email_communication = false
u.project_email_communication = false
u.build_identity_group
end
return account if account.persisted?
# log errors if account is invalid
unless account.valid?
log_account_errors(account)
exit
end
account
end
# accounts data map
accounts_to_save = {}
# create a teacher account
accounts_to_save['teacher'] = find_or_build_account('classrooms-teacher-01', 'Classroom Teacher 01', '[email protected]')
# create the student accounts
# Can you set up 5 classrooms of 25 people each using whatever username makes sense?
# If they could be added to a classroom, owned by a teacher account, that would be fab.
# So teacher_1 with pupils class_1, class_2 etc. Thanks..
num_classrooms = (1..5).to_a
num_students = (1..25).to_a
num_classrooms.each do |classroom_number|
# setup a class num label with 0 prefix
class_numf = account_num_prefix(classroom_number)
# NOTE: classroom's will be created later via education API code
student_accounts = num_students.map do |student_number|
# setup a student num label with 0 prefix
student_numf = account_num_prefix(student_number)
# create the student accounts
login = "student-#{student_numf}-class-#{class_numf}"
find_or_build_account(login, "Student #{student_numf} - Class #{class_numf}", "#{login}[email protected]")
end
# store the accounts in the hash
accounts_to_save[class_numf] = student_accounts
end
# all the accounts should be valid but some may be persisted already if this has run before.
accounts_to_save.each do |account_type, accounts|
puts "Saving account for: #{account_type}"
Array.wrap(accounts).each do |account|
raise StandardError, 'INVALID ACCOUNT WTF!' unless account.valid?
puts 'Account is valid!'
account.save!
end
puts
end; nil
# Pring the accounts details for reporting back
accounts_to_save.each do |account_type, accounts|
puts "Saving account for: #{account_type}"
Array.wrap(accounts).each do |account|
print_account_details(account)
end
puts
end; nil
# DEBUG: CLEANUP the newly created accounts - used when testing/creating
# accounts_to_save.each do |account_type, accounts|
# Array.wrap(accounts).each do |account|
# account.reload
# account.identity_group.destroy!
# account.destroy!
# end
# end; nil
Use the web interface to setup the classrooms 0. visit https://classroom.zooniverse.org/#/astro-101-with-galaxy-zoo/educators/ 0. login as the Teacher account we created above 0. Use the forms to create the classrooms you need :)
Note: Logging in as the teacher will setup that account in the education api system.
Run the following code on the panoptes API to ensure the students are joined to the correct classrooms. Note this builds on the output from the create account step above.
# frozen_string_literal: true
# setup student classroom account linkages
classroom_accounts = {
'2448382' => [
{ id: 2565753, login: 'student-01-class-01' },
{ id: 2565754, login: 'student-02-class-01' },
{ id: 2565755, login: 'student-03-class-01' },
{ id: 2565756, login: 'student-04-class-01' },
{ id: 2565757, login: 'student-05-class-01' },
{ id: 2565758, login: 'student-06-class-01' },
{ id: 2565759, login: 'student-07-class-01' },
{ id: 2565760, login: 'student-08-class-01' },
{ id: 2565761, login: 'student-09-class-01' },
{ id: 2565762, login: 'student-10-class-01' },
{ id: 2565763, login: 'student-11-class-01' },
{ id: 2565764, login: 'student-12-class-01' },
{ id: 2565765, login: 'student-13-class-01' },
{ id: 2565766, login: 'student-14-class-01' },
{ id: 2565767, login: 'student-15-class-01' },
{ id: 2565768, login: 'student-16-class-01' },
{ id: 2565769, login: 'student-17-class-01' },
{ id: 2565770, login: 'student-18-class-01' },
{ id: 2565771, login: 'student-19-class-01' },
{ id: 2565772, login: 'student-20-class-01' },
{ id: 2565773, login: 'student-21-class-01' },
{ id: 2565774, login: 'student-22-class-01' },
{ id: 2565775, login: 'student-23-class-01' },
{ id: 2565776, login: 'student-24-class-01' },
{ id: 2565777, login: 'student-25-class-01' }
],
'2448383' => [
{ id: 2565778, login: 'student-01-class-02' },
{ id: 2565779, login: 'student-02-class-02' },
{ id: 2565780, login: 'student-03-class-02' },
{ id: 2565781, login: 'student-04-class-02' },
{ id: 2565782, login: 'student-05-class-02' },
{ id: 2565783, login: 'student-06-class-02' },
{ id: 2565784, login: 'student-07-class-02' },
{ id: 2565785, login: 'student-08-class-02' },
{ id: 2565786, login: 'student-09-class-02' },
{ id: 2565787, login: 'student-10-class-02' },
{ id: 2565788, login: 'student-11-class-02' },
{ id: 2565789, login: 'student-12-class-02' },
{ id: 2565790, login: 'student-13-class-02' },
{ id: 2565791, login: 'student-14-class-02' },
{ id: 2565792, login: 'student-15-class-02' },
{ id: 2565793, login: 'student-16-class-02' },
{ id: 2565794, login: 'student-17-class-02' },
{ id: 2565795, login: 'student-18-class-02' },
{ id: 2565796, login: 'student-19-class-02' },
{ id: 2565797, login: 'student-20-class-02' },
{ id: 2565798, login: 'student-21-class-02' },
{ id: 2565799, login: 'student-22-class-02' },
{ id: 2565800, login: 'student-23-class-02' },
{ id: 2565801, login: 'student-24-class-02' },
{ id: 2565802, login: 'student-25-class-02' }
],
'2448384' => [
{ id: 2565803, login: 'student-01-class-03' },
{ id: 2565804, login: 'student-02-class-03' },
{ id: 2565805, login: 'student-03-class-03' },
{ id: 2565806, login: 'student-04-class-03' },
{ id: 2565807, login: 'student-05-class-03' },
{ id: 2565808, login: 'student-06-class-03' },
{ id: 2565809, login: 'student-07-class-03' },
{ id: 2565810, login: 'student-08-class-03' },
{ id: 2565811, login: 'student-09-class-03' },
{ id: 2565812, login: 'student-10-class-03' },
{ id: 2565813, login: 'student-11-class-03' },
{ id: 2565814, login: 'student-12-class-03' },
{ id: 2565815, login: 'student-13-class-03' },
{ id: 2565816, login: 'student-14-class-03' },
{ id: 2565817, login: 'student-15-class-03' },
{ id: 2565818, login: 'student-16-class-03' },
{ id: 2565819, login: 'student-17-class-03' },
{ id: 2565820, login: 'student-18-class-03' },
{ id: 2565821, login: 'student-19-class-03' },
{ id: 2565822, login: 'student-20-class-03' },
{ id: 2565823, login: 'student-21-class-03' },
{ id: 2565824, login: 'student-22-class-03' },
{ id: 2565825, login: 'student-23-class-03' },
{ id: 2565826, login: 'student-24-class-03' },
{ id: 2565827, login: 'student-25-class-03' }
],
'2448385' => [
{ id: 2565828, login: 'student-01-class-04' },
{ id: 2565829, login: 'student-02-class-04' },
{ id: 2565830, login: 'student-03-class-04' },
{ id: 2565831, login: 'student-04-class-04' },
{ id: 2565832, login: 'student-05-class-04' },
{ id: 2565833, login: 'student-06-class-04' },
{ id: 2565834, login: 'student-07-class-04' },
{ id: 2565835, login: 'student-08-class-04' },
{ id: 2565836, login: 'student-09-class-04' },
{ id: 2565837, login: 'student-10-class-04' },
{ id: 2565838, login: 'student-11-class-04' },
{ id: 2565839, login: 'student-12-class-04' },
{ id: 2565840, login: 'student-13-class-04' },
{ id: 2565841, login: 'student-14-class-04' },
{ id: 2565842, login: 'student-15-class-04' },
{ id: 2565843, login: 'student-16-class-04' },
{ id: 2565844, login: 'student-17-class-04' },
{ id: 2565845, login: 'student-18-class-04' },
{ id: 2565846, login: 'student-19-class-04' },
{ id: 2565847, login: 'student-20-class-04' },
{ id: 2565848, login: 'student-21-class-04' },
{ id: 2565849, login: 'student-22-class-04' },
{ id: 2565850, login: 'student-23-class-04' },
{ id: 2565851, login: 'student-24-class-04' },
{ id: 2565852, login: 'student-25-class-04' }
],
'2448387' => [
{ id: 2565853, login: 'student-01-class-05' },
{ id: 2565854, login: 'student-02-class-05' },
{ id: 2565855, login: 'student-03-class-05' },
{ id: 2565856, login: 'student-04-class-05' },
{ id: 2565857, login: 'student-05-class-05' },
{ id: 2565858, login: 'student-06-class-05' },
{ id: 2565859, login: 'student-07-class-05' },
{ id: 2565860, login: 'student-08-class-05' },
{ id: 2565861, login: 'student-09-class-05' },
{ id: 2565862, login: 'student-10-class-05' },
{ id: 2565863, login: 'student-11-class-05' },
{ id: 2565864, login: 'student-12-class-05' },
{ id: 2565865, login: 'student-13-class-05' },
{ id: 2565866, login: 'student-14-class-05' },
{ id: 2565867, login: 'student-15-class-05' },
{ id: 2565868, login: 'student-16-class-05' },
{ id: 2565869, login: 'student-17-class-05' },
{ id: 2565870, login: 'student-18-class-05' },
{ id: 2565871, login: 'student-19-class-05' },
{ id: 2565872, login: 'student-20-class-05' },
{ id: 2565873, login: 'student-21-class-05' },
{ id: 2565874, login: 'student-22-class-05' },
{ id: 2565875, login: 'student-23-class-05' },
{ id: 2565876, login: 'student-24-class-05' },
{ id: 2565877, login: 'student-25-class-05' }
]
}
# find the student account by id
classroom_accounts.each do |classroom_id, student_accounts|
user_group = UserGroup.find(classroom_id)
raise StandardError, "Classroom Group not found: #{classroom_id}" unless user_group
student_accounts.each do |student_account|
student = User.find_by_lower_login(student_account[:login])
raise StandardError, "Student not found: #{student_account[:login]}" unless student
membership = Membership.find_or_initialize_by(user: student, user_group: user_group)
membership.state = :active
membership.save! unless membership.persisted?
puts "Membership saved: #{membership.id}"
end
end
Run the following code on the eduction API to ensure the students are setup and linked to the classrooms and assignments.
# frozen_string_literal: true
def find_or_create_account(id, login)
user = User.find_or_create_by(zooniverse_id: id)
user.zooniverse_login = login
# display name will be updated on login to education api system via classroom
user.save! if user.changed?
user
end
def log_account(user)
puts "login: #{user.zooniverse_login}, id: #{user.zooniverse_id}"
end
# link the API accounts to the education-api user accounts
# these come from the the setup code in panoptes API
# make sure you change the IDs to match the student accounts you are creating
# https://github.com/zooniverse/education-api/wiki/Manually-Create-Student-Classroom-Accounts
# setup student classroom account linkages
classroom_accounts = {
'Classroom 01': [
{ id: 2565753, login: 'student-01-class-01' },
{ id: 2565754, login: 'student-02-class-01' },
{ id: 2565755, login: 'student-03-class-01' },
{ id: 2565756, login: 'student-04-class-01' },
{ id: 2565757, login: 'student-05-class-01' },
{ id: 2565758, login: 'student-06-class-01' },
{ id: 2565759, login: 'student-07-class-01' },
{ id: 2565760, login: 'student-08-class-01' },
{ id: 2565761, login: 'student-09-class-01' },
{ id: 2565762, login: 'student-10-class-01' },
{ id: 2565763, login: 'student-11-class-01' },
{ id: 2565764, login: 'student-12-class-01' },
{ id: 2565765, login: 'student-13-class-01' },
{ id: 2565766, login: 'student-14-class-01' },
{ id: 2565767, login: 'student-15-class-01' },
{ id: 2565768, login: 'student-16-class-01' },
{ id: 2565769, login: 'student-17-class-01' },
{ id: 2565770, login: 'student-18-class-01' },
{ id: 2565771, login: 'student-19-class-01' },
{ id: 2565772, login: 'student-20-class-01' },
{ id: 2565773, login: 'student-21-class-01' },
{ id: 2565774, login: 'student-22-class-01' },
{ id: 2565775, login: 'student-23-class-01' },
{ id: 2565776, login: 'student-24-class-01' },
{ id: 2565777, login: 'student-25-class-01' }
],
'Classroom 02': [
{ id: 2565778, login: 'student-01-class-02' },
{ id: 2565779, login: 'student-02-class-02' },
{ id: 2565780, login: 'student-03-class-02' },
{ id: 2565781, login: 'student-04-class-02' },
{ id: 2565782, login: 'student-05-class-02' },
{ id: 2565783, login: 'student-06-class-02' },
{ id: 2565784, login: 'student-07-class-02' },
{ id: 2565785, login: 'student-08-class-02' },
{ id: 2565786, login: 'student-09-class-02' },
{ id: 2565787, login: 'student-10-class-02' },
{ id: 2565788, login: 'student-11-class-02' },
{ id: 2565789, login: 'student-12-class-02' },
{ id: 2565790, login: 'student-13-class-02' },
{ id: 2565791, login: 'student-14-class-02' },
{ id: 2565792, login: 'student-15-class-02' },
{ id: 2565793, login: 'student-16-class-02' },
{ id: 2565794, login: 'student-17-class-02' },
{ id: 2565795, login: 'student-18-class-02' },
{ id: 2565796, login: 'student-19-class-02' },
{ id: 2565797, login: 'student-20-class-02' },
{ id: 2565798, login: 'student-21-class-02' },
{ id: 2565799, login: 'student-22-class-02' },
{ id: 2565800, login: 'student-23-class-02' },
{ id: 2565801, login: 'student-24-class-02' },
{ id: 2565802, login: 'student-25-class-02' }
],
'Classroom 03': [
{ id: 2565803, login: 'student-01-class-03' },
{ id: 2565804, login: 'student-02-class-03' },
{ id: 2565805, login: 'student-03-class-03' },
{ id: 2565806, login: 'student-04-class-03' },
{ id: 2565807, login: 'student-05-class-03' },
{ id: 2565808, login: 'student-06-class-03' },
{ id: 2565809, login: 'student-07-class-03' },
{ id: 2565810, login: 'student-08-class-03' },
{ id: 2565811, login: 'student-09-class-03' },
{ id: 2565812, login: 'student-10-class-03' },
{ id: 2565813, login: 'student-11-class-03' },
{ id: 2565814, login: 'student-12-class-03' },
{ id: 2565815, login: 'student-13-class-03' },
{ id: 2565816, login: 'student-14-class-03' },
{ id: 2565817, login: 'student-15-class-03' },
{ id: 2565818, login: 'student-16-class-03' },
{ id: 2565819, login: 'student-17-class-03' },
{ id: 2565820, login: 'student-18-class-03' },
{ id: 2565821, login: 'student-19-class-03' },
{ id: 2565822, login: 'student-20-class-03' },
{ id: 2565823, login: 'student-21-class-03' },
{ id: 2565824, login: 'student-22-class-03' },
{ id: 2565825, login: 'student-23-class-03' },
{ id: 2565826, login: 'student-24-class-03' },
{ id: 2565827, login: 'student-25-class-03' }
],
'Classroom 04': [
{ id: 2565828, login: 'student-01-class-04' },
{ id: 2565829, login: 'student-02-class-04' },
{ id: 2565830, login: 'student-03-class-04' },
{ id: 2565831, login: 'student-04-class-04' },
{ id: 2565832, login: 'student-05-class-04' },
{ id: 2565833, login: 'student-06-class-04' },
{ id: 2565834, login: 'student-07-class-04' },
{ id: 2565835, login: 'student-08-class-04' },
{ id: 2565836, login: 'student-09-class-04' },
{ id: 2565837, login: 'student-10-class-04' },
{ id: 2565838, login: 'student-11-class-04' },
{ id: 2565839, login: 'student-12-class-04' },
{ id: 2565840, login: 'student-13-class-04' },
{ id: 2565841, login: 'student-14-class-04' },
{ id: 2565842, login: 'student-15-class-04' },
{ id: 2565843, login: 'student-16-class-04' },
{ id: 2565844, login: 'student-17-class-04' },
{ id: 2565845, login: 'student-18-class-04' },
{ id: 2565846, login: 'student-19-class-04' },
{ id: 2565847, login: 'student-20-class-04' },
{ id: 2565848, login: 'student-21-class-04' },
{ id: 2565849, login: 'student-22-class-04' },
{ id: 2565850, login: 'student-23-class-04' },
{ id: 2565851, login: 'student-24-class-04' },
{ id: 2565852, login: 'student-25-class-04' }
],
'Classroom 05': [
{ id: 2565853, login: 'student-01-class-05' },
{ id: 2565854, login: 'student-02-class-05' },
{ id: 2565855, login: 'student-03-class-05' },
{ id: 2565856, login: 'student-04-class-05' },
{ id: 2565857, login: 'student-05-class-05' },
{ id: 2565858, login: 'student-06-class-05' },
{ id: 2565859, login: 'student-07-class-05' },
{ id: 2565860, login: 'student-08-class-05' },
{ id: 2565861, login: 'student-09-class-05' },
{ id: 2565862, login: 'student-10-class-05' },
{ id: 2565863, login: 'student-11-class-05' },
{ id: 2565864, login: 'student-12-class-05' },
{ id: 2565865, login: 'student-13-class-05' },
{ id: 2565866, login: 'student-14-class-05' },
{ id: 2565867, login: 'student-15-class-05' },
{ id: 2565868, login: 'student-16-class-05' },
{ id: 2565869, login: 'student-17-class-05' },
{ id: 2565870, login: 'student-18-class-05' },
{ id: 2565871, login: 'student-19-class-05' },
{ id: 2565872, login: 'student-20-class-05' },
{ id: 2565873, login: 'student-21-class-05' },
{ id: 2565874, login: 'student-22-class-05' },
{ id: 2565875, login: 'student-23-class-05' },
{ id: 2565876, login: 'student-24-class-05' },
{ id: 2565877, login: 'student-25-class-05' }
]
}
program = Program.where(slug: 'zooniverse-in-schools').first
raise StandardError, 'Found the wrong program - wat?!' unless program.name == 'Zooniverse In Schools'
# class rooms are created via the web interface
# https://classroom.zooniverse.org/#/astro-101-with-galaxy-zoo/educators/
# using the teacher login created before
# this will setup the user account in the education api
# and the required classrooms :)
# as there are too many student accounts to manually login and join the classrooms etc
# we will do this manually - a similar step for the teacher could have been performed
#
# for each of the classrooms setup above
# 1. create the student account
# 2. join the classrooms
classroom_accounts.each do |classroom_name, accounts|
# find the classrooms
classroom = Classroom.where(name: classroom_name).first
raise StandardError, "Classroom not found: #{classroom_name}" unless classroom
accounts.each do |student_account|
student = find_or_create_account(student_account[:id], student_account[:login])
log_account(student)
# Student classroom joining is run via code in panoptes rails console
# this is due to the educatino code relying on
# the panoptes client to provide the auth of the logged in student user
# i.e. they request to join the group - this is supplied to the education api from the front end client
# so we need to do this manually for now via the join code in the API :(
#
# SEE "Join student accounts to their classrooms" code section above!
# copied from the Classrooms::Join operation
# now the students are linked to the classrooms in the panoptes API
# we can create their linkage in the education API
classroom.students << student
# skip the student assigment linkage if it's a custom program
# i still don't know what custom means after all this time.... nomeclature :shrug:
next if classroom.program.custom?
# and add the students to the assignments
classroom.assignments.each do |assignment|
student_user = StudentUser.where(user_id: student.id, classroom_id: classroom.id).first
raise StandardError, "StudentUser not found for user: #{student.id} and classroom: #{classroom.id}" unless student_user
assignment.student_users << student_user
end
end
end