github-to-canvas-quiz 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +48 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +21 -0
  7. data/NOTES.md +53 -0
  8. data/README.md +89 -0
  9. data/Rakefile +8 -0
  10. data/bin/console +29 -0
  11. data/bin/github-to-canvas-quiz +15 -0
  12. data/bin/setup +8 -0
  13. data/github-to-canvas-quiz.gemspec +50 -0
  14. data/lib/github_to_canvas_quiz/builder/quiz.rb +110 -0
  15. data/lib/github_to_canvas_quiz/canvas_api/client.rb +80 -0
  16. data/lib/github_to_canvas_quiz/canvas_api/endpoints/quiz_questions.rb +29 -0
  17. data/lib/github_to_canvas_quiz/canvas_api/endpoints/quizzes.rb +25 -0
  18. data/lib/github_to_canvas_quiz/canvas_api/endpoints.rb +10 -0
  19. data/lib/github_to_canvas_quiz/cli.rb +31 -0
  20. data/lib/github_to_canvas_quiz/markdown_builder.rb +90 -0
  21. data/lib/github_to_canvas_quiz/markdown_converter.rb +44 -0
  22. data/lib/github_to_canvas_quiz/model/answer/fill_in_multiple_blanks.rb +34 -0
  23. data/lib/github_to_canvas_quiz/model/answer/matching.rb +35 -0
  24. data/lib/github_to_canvas_quiz/model/answer/multiple_answers.rb +33 -0
  25. data/lib/github_to_canvas_quiz/model/answer/multiple_choice.rb +33 -0
  26. data/lib/github_to_canvas_quiz/model/answer/multiple_dropdowns.rb +34 -0
  27. data/lib/github_to_canvas_quiz/model/answer/short_answer.rb +33 -0
  28. data/lib/github_to_canvas_quiz/model/answer/true_false.rb +33 -0
  29. data/lib/github_to_canvas_quiz/model/question.rb +61 -0
  30. data/lib/github_to_canvas_quiz/model/quiz.rb +62 -0
  31. data/lib/github_to_canvas_quiz/parser/canvas/answer/base.rb +19 -0
  32. data/lib/github_to_canvas_quiz/parser/canvas/answer/fill_in_multiple_blanks.rb +30 -0
  33. data/lib/github_to_canvas_quiz/parser/canvas/answer/matching.rb +31 -0
  34. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_answers.rb +33 -0
  35. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_choice.rb +33 -0
  36. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_dropdowns.rb +30 -0
  37. data/lib/github_to_canvas_quiz/parser/canvas/answer/short_answer.rb +29 -0
  38. data/lib/github_to_canvas_quiz/parser/canvas/answer/true_false.rb +29 -0
  39. data/lib/github_to_canvas_quiz/parser/canvas/answer.rb +34 -0
  40. data/lib/github_to_canvas_quiz/parser/canvas/helpers.rb +25 -0
  41. data/lib/github_to_canvas_quiz/parser/canvas/question.rb +55 -0
  42. data/lib/github_to_canvas_quiz/parser/canvas/quiz.rb +44 -0
  43. data/lib/github_to_canvas_quiz/parser/markdown/answer/base.rb +22 -0
  44. data/lib/github_to_canvas_quiz/parser/markdown/answer/fill_in_multiple_blanks.rb +21 -0
  45. data/lib/github_to_canvas_quiz/parser/markdown/answer/matching.rb +23 -0
  46. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_answers.rb +21 -0
  47. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_choice.rb +19 -0
  48. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_dropdowns.rb +21 -0
  49. data/lib/github_to_canvas_quiz/parser/markdown/answer/short_answer.rb +21 -0
  50. data/lib/github_to_canvas_quiz/parser/markdown/answer/true_false.rb +21 -0
  51. data/lib/github_to_canvas_quiz/parser/markdown/answer.rb +34 -0
  52. data/lib/github_to_canvas_quiz/parser/markdown/base.rb +22 -0
  53. data/lib/github_to_canvas_quiz/parser/markdown/helpers/node_parser.rb +21 -0
  54. data/lib/github_to_canvas_quiz/parser/markdown/helpers/node_scanner.rb +208 -0
  55. data/lib/github_to_canvas_quiz/parser/markdown/question.rb +76 -0
  56. data/lib/github_to_canvas_quiz/parser/markdown/quiz.rb +42 -0
  57. data/lib/github_to_canvas_quiz/repository_interface.rb +42 -0
  58. data/lib/github_to_canvas_quiz/reverse_markdown/converters/p.rb +20 -0
  59. data/lib/github_to_canvas_quiz/reverse_markdown/converters/pre.rb +51 -0
  60. data/lib/github_to_canvas_quiz/reverse_markdown/register.rb +9 -0
  61. data/lib/github_to_canvas_quiz/synchronizer/quiz.rb +140 -0
  62. data/lib/github_to_canvas_quiz/version.rb +5 -0
  63. data/lib/github_to_canvas_quiz.rb +62 -0
  64. metadata +348 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module CanvasAPI
5
+ module Endpoints
6
+ include Quizzes
7
+ include QuizQuestions
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ class CLI < Thor
5
+ option :course, type: :numeric, required: true, desc: 'Canvas Course ID'
6
+ option :quiz, type: :numeric, required: true, desc: 'Canvas Quiz ID'
7
+ option :directory, default: '.',
8
+ desc: '(optional) Directory to output markdown files. Defaults to current directory'
9
+ desc 'backup', 'Backup a Canvas quiz and its questions as markdown'
10
+ def backup
11
+ puts '⬇️ Converting quiz...'
12
+ Builder::Quiz.new(client, options[:course], options[:quiz], options[:directory]).build
13
+ puts '✅ Done'
14
+ end
15
+
16
+ option :directory, default: '.',
17
+ desc: '(optional) Directory with markdown files to align. Defaults to current directory'
18
+ desc 'align', 'Updates a Canvas quiz from Markdown files.'
19
+ def align
20
+ puts '⬆️ Aligning quiz...'
21
+ Synchronizer::Quiz.new(client, options[:directory]).sync
22
+ puts '✅ Done'
23
+ end
24
+
25
+ private
26
+
27
+ def client
28
+ @client ||= CanvasAPI::Client.new(api_key: ENV['CANVAS_API_KEY'], host: ENV['CANVAS_API_PATH'])
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ # Custom DSL for building a Markdown string
5
+ class MarkdownBuilder
6
+ # Provides a custom DSL for building a Markdown string
7
+ # Usage:
8
+ #
9
+ # MarkdownBuilder.build do |md|
10
+ # md.h1('Hello')
11
+ # md.ul('item 1', 'item 2')
12
+ # md.blockquote('comment')
13
+ # end
14
+ #
15
+ # # => "# Hello\n\n- item 1\n- item 2\n\n> comment\n"
16
+ def self.build
17
+ raise ArgumentError, 'no block given' unless block_given?
18
+
19
+ builder = new
20
+ yield(builder)
21
+ builder.to_s
22
+ end
23
+
24
+ attr_accessor :blocks
25
+
26
+ def initialize
27
+ @blocks = []
28
+ end
29
+
30
+ # @return [String] markdown produced by joining all blocks
31
+ def to_s
32
+ "#{blocks.join("\n\n")}\n"
33
+ end
34
+
35
+ # Adds a frontmatter block
36
+ # @param hash [Hash] the data to covert to YAML for the frontmatter
37
+ def frontmatter(hash)
38
+ blocks << "#{hash.to_yaml.strip}\n---"
39
+ end
40
+
41
+ # Adds a H1 heading
42
+ # @param text [String] heading text
43
+ def h1(text)
44
+ blocks << "# #{text}"
45
+ end
46
+
47
+ # Adds a H2 heading
48
+ # @param text [String] heading text
49
+ def h2(text)
50
+ blocks << "## #{text}"
51
+ end
52
+
53
+ # Adds a paragraph
54
+ # @param text [String] paragraph text
55
+ def p(text)
56
+ blocks << escape(text)
57
+ end
58
+
59
+ # Adds a blockquote
60
+ # @param text [String] blockquote text
61
+ def blockquote(text)
62
+ text = text.gsub("\n", "\n> ")
63
+ blocks << "> #{text}"
64
+ end
65
+
66
+ # Adds multiple list items
67
+ # @param texts* [Strings] a list of text to convert to list items
68
+ def ul(*texts)
69
+ blocks << texts.map { |text| "- #{escape(text)}" }.join("\n")
70
+ end
71
+
72
+ # Adds a block of arbitrary markdown
73
+ # @param markdown [String] markdown string
74
+ def md(markdown)
75
+ blocks << markdown.strip
76
+ end
77
+
78
+ # TODO: This doesn't belong here...
79
+ def html_to_markdown(html)
80
+ ReverseMarkdown.convert(html, github_flavored: true).strip
81
+ end
82
+
83
+ private
84
+
85
+ # TODO: What needs escaping??
86
+ def escape(text)
87
+ text.gsub('_', '\_')
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ # Custom HTML renderer for Redcarpet, using Rouge for syntax highlighting
5
+ class HTMLRenderer < Redcarpet::Render::HTML
6
+ include Rouge::Plugins::Redcarpet
7
+ end
8
+
9
+ # Convert a string of Markdown to HTML using Redcarpet and Rouge.
10
+ #
11
+ # Useage:
12
+ #
13
+ # MarkdownConverter.new("# Hello\n\nWorld\n").to_html
14
+ # # => "<h1>Hello</h1>\n\n<p>World</p>\n"
15
+ class MarkdownConverter
16
+ attr_reader :options, :markdown
17
+
18
+ OPTIONS = {
19
+ tables: true,
20
+ autolink: true,
21
+ fenced_code_blocks: true,
22
+ disable_indented_code_blocks: true,
23
+ no_intra_emphasis: true
24
+ }.freeze
25
+
26
+ # @param [String] markdown The markdown to be converted
27
+ # @param [Hash] options Overrides the defaults for the [Redcarpet](https://github.com/vmg/redcarpet) gem
28
+ def initialize(markdown, options = {})
29
+ @options = OPTIONS.merge(options)
30
+ @markdown = markdown
31
+ end
32
+
33
+ # @return [String] the markdown converted to HTML
34
+ def to_html
35
+ Redcarpet::Markdown.new(renderer, options).render(markdown)
36
+ end
37
+
38
+ private
39
+
40
+ def renderer
41
+ HTMLRenderer.new(escape_html: true)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class FillInMultipleBlanks
7
+ attr_accessor :title, :text, :comments, :blank_id
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(text, blank_id)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments,
28
+ 'blank_id' => blank_id
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class Matching
7
+ attr_accessor :title, :text, :comments, :left, :right
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(left, right)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => left,
26
+ 'answer_weight' => 100,
27
+ 'answer_comment_html' => comments,
28
+ 'answer_match_left' => left,
29
+ 'answer_match_right' => right
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleAnswers
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.md(md.html_to_markdown(text))
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_html' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleChoice
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.md(md.html_to_markdown(text))
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_html' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleDropdowns
7
+ attr_accessor :title, :text, :comments, :blank_id
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(text, blank_id)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments,
28
+ 'blank_id' => blank_id
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class ShortAnswer
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.p(text)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class TrueFalse
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.p(text)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ class Question
6
+ attr_accessor :course_id, :quiz_id, :id, :type, :sources, :name, :description, :answers, :distractors
7
+
8
+ def initialize(options)
9
+ options.each do |key, value|
10
+ send("#{key}=", value) if respond_to?("#{key}=")
11
+ end
12
+ end
13
+
14
+ def to_markdown
15
+ MarkdownBuilder.build do |md|
16
+ md.frontmatter(frontmatter_hash)
17
+ md.h1(name)
18
+ md.md(md.html_to_markdown(description))
19
+ answers.each do |answer|
20
+ md.md(answer.to_markdown)
21
+ end
22
+ unless distractors.empty?
23
+ md.h2('Incorrect')
24
+ md.ul(*distractors)
25
+ end
26
+ end
27
+ end
28
+
29
+ def to_h
30
+ {
31
+ 'question_name' => name,
32
+ 'question_text' => description,
33
+ 'question_type' => type,
34
+ 'points_possible' => 1,
35
+ 'neutral_comments_html' => sources.nil? || sources.empty? ? '' : sources_to_html,
36
+ 'answers' => answers.map(&:to_h),
37
+ 'matching_answer_incorrect_matches' => distractors.join("\n")
38
+ }
39
+ end
40
+
41
+ def frontmatter_hash
42
+ {
43
+ 'course_id' => course_id,
44
+ 'quiz_id' => quiz_id,
45
+ 'id' => id,
46
+ 'type' => type,
47
+ 'sources' => sources
48
+ }
49
+ end
50
+
51
+ private
52
+
53
+ def sources_to_html
54
+ comments = sources.map do |source|
55
+ "<a href=\"#{source['url']}\">#{source['name']}</a>"
56
+ end.join
57
+ "<p><strong>Source/s:</strong> #{comments}</p>"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ class Quiz
6
+ attr_accessor :course_id, :id, :repo, :title, :description
7
+
8
+ def initialize(options)
9
+ options.each do |key, value|
10
+ send("#{key}=", value) if respond_to?("#{key}=")
11
+ end
12
+ end
13
+
14
+ def to_markdown
15
+ MarkdownBuilder.build do |md|
16
+ md.frontmatter(frontmatter_hash)
17
+ md.h1(title)
18
+ md.md(md.html_to_markdown(description))
19
+ end
20
+ end
21
+
22
+ def to_h
23
+ {
24
+ 'title' => title,
25
+ 'description' => description_with_header,
26
+ 'quiz_type' => 'assignment',
27
+ 'shuffle_answers' => true,
28
+ 'hide_results' => 'until_after_last_attempt',
29
+ 'show_correct_answers_last_attempt' => true,
30
+ 'allowed_attempts' => 3,
31
+ 'scoring_policy' => 'keep_highest',
32
+ 'one_question_at_a_time' => true
33
+ }
34
+ end
35
+
36
+ def frontmatter_hash
37
+ {
38
+ 'id' => id,
39
+ 'course_id' => course_id,
40
+ 'repo' => repo
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ def description_with_header
47
+ [git_links_header, description].reject(&:nil?).join("\n")
48
+ end
49
+
50
+ def git_links_header
51
+ return unless repo
52
+
53
+ <<~HTML
54
+ <div id='git-data-element' data-org='learn-co-curriculum' data-repo='#{repo}'></div>
55
+ <header class='fis-header'>
56
+ <a class='fis-git-link' href='https://github.com/learn-co-curriculum/#{repo}/issues/new' target='_blank' rel='noopener'><img id='issue-img' title='Create New Issue' alt='Create New Issue' /></a>
57
+ </header>
58
+ HTML
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class Base
8
+ include Helpers
9
+
10
+ attr_reader :data
11
+
12
+ def initialize(data)
13
+ @data = data
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class FillInMultipleBlanks < Base
8
+ def parse
9
+ Model::Answer::FillInMultipleBlanks.new(
10
+ title: title,
11
+ text: data['text'],
12
+ comments: comments,
13
+ blank_id: data['blank_id']
14
+ )
15
+ end
16
+
17
+ private
18
+
19
+ def title
20
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
21
+ end
22
+
23
+ def comments
24
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class Matching < Base
8
+ def parse
9
+ Model::Answer::Matching.new(
10
+ title: title,
11
+ text: data['text'],
12
+ comments: comments,
13
+ left: data['left'],
14
+ right: data['right']
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def title
21
+ data['left'].empty? ? 'Incorrect' : 'Correct'
22
+ end
23
+
24
+ def comments
25
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class MultipleAnswers < Base
8
+ def parse
9
+ Model::Answer::MultipleAnswers.new(
10
+ title: title,
11
+ text: text,
12
+ comments: comments
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
20
+ end
21
+
22
+ def text
23
+ choose_text(data.fetch('text', ''), data.fetch('html', ''))
24
+ end
25
+
26
+ def comments
27
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class MultipleChoice < Base
8
+ def parse
9
+ Model::Answer::MultipleChoice.new(
10
+ title: title,
11
+ text: text,
12
+ comments: comments
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
20
+ end
21
+
22
+ def text
23
+ choose_text(data.fetch('text', ''), data.fetch('html', ''))
24
+ end
25
+
26
+ def comments
27
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end