class GithubToCanvasQuiz::Synchronizer::Quiz
Synchronize a quiz to Canvas based on the contents of a given directory Given a directory with valid markdown files:
phase-1-quiz-arrays | questions | |– 00.md | |– 01.md |– README.md
Useage:
client = CanvasAPI::Client.new(host: host, api_key: api_key) Synchronizer::Quiz.new(client, 'phase-1-quiz-arrays')
Attributes
client[R]
path[R]
questions_with_path[R]
quiz[R]
repo[R]
Public Class Methods
new(client, path)
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 22 def initialize(client, path) path = File.expand_path(path) raise DirectoryNotFoundError unless Pathname(path).directory? @client = client @path = path @repo = RepositoryInterface.new(path) @quiz = parse_quiz @questions_with_path = parse_questions_with_path end
Public Instance Methods
sync()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 33 def sync backup_canvas_to_json! sync_quiz! sync_questions! backup_canvas_to_json! end
Private Instance Methods
backup_canvas_to_json!()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 139 def backup_canvas_to_json! quiz_data = client.get_single_quiz(quiz.course_id, quiz.id) questions_data = client.list_questions(quiz.course_id, quiz.id) json_data = JSON.pretty_generate({ quiz: quiz_data, questions: questions_data }) File.write(json_path, json_data) repo.commit_files(json_path, 'Created Canvas snapshot') end
create_question_and_update_frontmatter!(question, path)
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 118 def create_question_and_update_frontmatter!(question, path) canvas_question = client.create_question(question.course_id, question.quiz_id, { 'question' => question.to_h }) question.id = canvas_question['id'] update_frontmatter(path, question) end
create_quiz_and_update_frontmatter!()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 95 def create_quiz_and_update_frontmatter! canvas_quiz = client.create_quiz(quiz.course_id, { 'quiz' => quiz.to_h }) quiz.id = canvas_quiz['id'] update_frontmatter(quiz_path, quiz) end
get_answer_ids!(question, canvas_question)
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 68 def get_answer_ids!(question, canvas_question) question.answers.each do |answer| # match the markdown answer to the Canvas answer based on the answer text canvas_answer = canvas_question['answers'].find do |canvas_answer| if canvas_answer['html'].nil? || canvas_answer['html'].empty? canvas_answer['text'] == answer.text else canvas_answer['html'] == answer.text end end answer.id = canvas_answer['id'].to_i if canvas_answer end end
json_path()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 148 def json_path File.join(path, '.canvas-snapshot.json') end
parse_questions_with_path()
click to toggle source
Get question data from Markdown files and return a Model::Question
along with its path
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 50 def parse_questions_with_path # read Canvas question data canvas_questions = client.list_questions(quiz.course_id, quiz.id) # read Markdown data Dir["#{path}/questions/*.md"].map do |question_path| question = Parser::Markdown::Question.new(File.read(question_path)).parse question.quiz_id = quiz.id question.course_id = quiz.course_id # find the matching Canvas answer canvas_question = canvas_questions.find { |canvas_question| canvas_question['id'] == question.id } get_answer_ids!(question, canvas_question) if canvas_question [question, question_path] # need that question path... gotta be a better way! end end
parse_quiz()
click to toggle source
Get quiz data from the Markdown file and return a Model::Quiz
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 43 def parse_quiz raise GithubToCanvasQuiz::FileNotFoundError unless Pathname(quiz_path).exist? Parser::Markdown::Quiz.new(quiz_path).parse end
quiz_path()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 101 def quiz_path File.join(path, 'README.md') end
remove_deleted_questions!()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 128 def remove_deleted_questions! ids = questions_with_path.map { |question_with_path| question_with_path.first.id } client.list_questions(quiz.course_id, quiz.id).each do |canvas_question| id = canvas_question['id'] unless ids.include?(id) # delete questions that are no longer present in the repo client.delete_question(quiz.course_id, quiz.id, id) end end end
sync_questions!()
click to toggle source
Create or update questions on Canvas
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 106 def sync_questions! questions_with_path.each do |question_with_path| question, path = question_with_path if question.id update_question!(question) else create_question_and_update_frontmatter!(question, path) end end remove_deleted_questions! end
sync_quiz!()
click to toggle source
create or update quiz on Canvas
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 83 def sync_quiz! if quiz.id update_quiz! else create_quiz_and_update_frontmatter! end end
update_frontmatter(filepath, markdownable)
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 152 def update_frontmatter(filepath, markdownable) parsed = FrontMatterParser::Parser.parse_file(filepath) new_markdown = MarkdownBuilder.build do |md| md.frontmatter(markdownable.frontmatter_hash) md.md(parsed.content) end File.write(filepath, new_markdown) repo.commit_files(filepath, 'Updated frontmatter') end
update_question!(question)
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 124 def update_question!(question) client.update_question(question.course_id, question.quiz_id, question.id, { 'question' => question.to_h }) end
update_quiz!()
click to toggle source
# File lib/github_to_canvas_quiz/synchronizer/quiz.rb, line 91 def update_quiz! client.update_quiz(quiz.course_id, quiz.id, { 'quiz' => quiz.to_h }) end