github-to-canvas-quiz 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -24
- data/lib/github_to_canvas_quiz/cli.rb +24 -6
- data/lib/github_to_canvas_quiz/model/answer/fill_in_multiple_blanks.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/matching.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/multiple_answers.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/multiple_choice.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/multiple_dropdowns.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/short_answer.rb +4 -3
- data/lib/github_to_canvas_quiz/model/answer/true_false.rb +4 -3
- data/lib/github_to_canvas_quiz/synchronizer/quiz.rb +28 -3
- data/lib/github_to_canvas_quiz/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e555944c5bbb43ede1e842476996a905bacf1f923d16b61a1eb2940bf596d409
|
4
|
+
data.tar.gz: c21175afacb3f8ea41bda6ec0cf7b962a93b79c2dbcbf898a757941fe95f0156
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a4e9b94994681e11f48e5d368fb9d55cad4c6a26697d91247341f5b6fd6385a5cdf00afbf943571380539e5deaf647a4476e73fd563629cf72cab1e711d4e99
|
7
|
+
data.tar.gz: eec67a66fdcfed1ada76c6cf1ed96169352ae03a998c1d2c5fa359e10d1b18dbcdba0b6de9c8f6d56eb97730a54a6b65915ba436f69e2b87f040d2bab9bb294a
|
data/README.md
CHANGED
@@ -1,24 +1,9 @@
|
|
1
1
|
# GithubToCanvasQuiz
|
2
2
|
|
3
|
-
|
4
|
-
A tool for resizing and uploading images to AWS S3.
|
3
|
+
A tool maintaining Canvas quizzes as markdown files in GitHub.
|
5
4
|
|
6
5
|
## Installation
|
7
6
|
|
8
|
-
Add this line to your application's Gemfile:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
gem 'github-to-canvas-quiz'
|
12
|
-
```
|
13
|
-
|
14
|
-
And then execute:
|
15
|
-
|
16
|
-
```console
|
17
|
-
$ bundle install
|
18
|
-
```
|
19
|
-
|
20
|
-
Or install it yourself as:
|
21
|
-
|
22
7
|
```console
|
23
8
|
$ gem install github-to-canvas-quiz
|
24
9
|
```
|
@@ -29,14 +14,17 @@ Interacting with the Canvas API requires that you have the following environment
|
|
29
14
|
variables set:
|
30
15
|
|
31
16
|
- `ENV['CANVAS_API_PATH']`
|
32
|
-
- The base URL for your institution's Canvas API
|
17
|
+
- The base URL for your institution's Canvas API
|
18
|
+
(`https://flatironlearn.beta.instructure.com/api/v1`)
|
33
19
|
- `ENV['CANVAS_API_KEY']`
|
34
|
-
- Your
|
20
|
+
- Your
|
21
|
+
[Canvas Access Token](https://canvas.instructure.com/doc/api/file.oauth.html#manual-token-generation)
|
35
22
|
|
36
23
|
## Usage
|
37
24
|
|
38
25
|
This gem provides two key features via the CLI: backing up Canvas quizzes to
|
39
|
-
markdown, and updating a Canvas quiz from an existing directory of markdown
|
26
|
+
markdown, and updating a Canvas quiz from an existing directory of markdown
|
27
|
+
files.
|
40
28
|
|
41
29
|
### Backup
|
42
30
|
|
@@ -72,10 +60,10 @@ git commits and the created tag, and push the `.gem` file to
|
|
72
60
|
## Contributing
|
73
61
|
|
74
62
|
Bug reports and pull requests are welcome on GitHub at
|
75
|
-
https://github.com/
|
76
|
-
be a safe, welcoming space for collaboration, and contributors are
|
77
|
-
adhere to the
|
78
|
-
[code of conduct](https://github.com/
|
63
|
+
https://github.com/learn-co-curriculum/github-to-canvas-quiz. This project is
|
64
|
+
intended to be a safe, welcoming space for collaboration, and contributors are
|
65
|
+
expected to adhere to the
|
66
|
+
[code of conduct](https://github.com/learn-co-curriculum/github-to-canvas-quiz/blob/main/CODE_OF_CONDUCT.md).
|
79
67
|
|
80
68
|
## License
|
81
69
|
|
@@ -86,4 +74,4 @@ The gem is available as open source under the terms of the
|
|
86
74
|
|
87
75
|
Everyone interacting in the FlatironS3Uploader project's codebases, issue
|
88
76
|
trackers, chat rooms and mailing lists is expected to follow the
|
89
|
-
[code of conduct](https://github.com/
|
77
|
+
[code of conduct](https://github.com/learn-co-curriculum/github-to-canvas-quiz/blob/main/CODE_OF_CONDUCT.md).
|
@@ -4,17 +4,26 @@ module GithubToCanvasQuiz
|
|
4
4
|
class CLI < Thor
|
5
5
|
option :course, type: :numeric, required: true, desc: 'Canvas Course ID'
|
6
6
|
option :quiz, type: :numeric, required: true, desc: 'Canvas Quiz ID'
|
7
|
-
option :directory,
|
8
|
-
|
7
|
+
option :directory,
|
8
|
+
default: '.',
|
9
|
+
desc:
|
10
|
+
'(optional) Directory to output markdown files. Defaults to current directory'
|
9
11
|
desc 'backup', 'Backup a Canvas quiz and its questions as markdown'
|
10
12
|
def backup
|
11
13
|
puts '⬇️ Converting quiz...'
|
12
|
-
Builder::Quiz.new(
|
14
|
+
Builder::Quiz.new(
|
15
|
+
client,
|
16
|
+
options[:course],
|
17
|
+
options[:quiz],
|
18
|
+
options[:directory],
|
19
|
+
).build
|
13
20
|
puts '✅ Done'
|
14
21
|
end
|
15
22
|
|
16
|
-
option :directory,
|
17
|
-
|
23
|
+
option :directory,
|
24
|
+
default: '.',
|
25
|
+
desc:
|
26
|
+
'(optional) Directory with markdown files to align. Defaults to current directory'
|
18
27
|
desc 'align', 'Updates a Canvas quiz from Markdown files.'
|
19
28
|
def align
|
20
29
|
puts '⬆️ Aligning quiz...'
|
@@ -22,10 +31,19 @@ module GithubToCanvasQuiz
|
|
22
31
|
puts '✅ Done'
|
23
32
|
end
|
24
33
|
|
34
|
+
desc 'version', 'Display the Gem version'
|
35
|
+
def version
|
36
|
+
puts VERSION
|
37
|
+
end
|
38
|
+
|
25
39
|
private
|
26
40
|
|
27
41
|
def client
|
28
|
-
@client ||=
|
42
|
+
@client ||=
|
43
|
+
CanvasAPI::Client.new(
|
44
|
+
api_key: ENV['CANVAS_API_KEY'],
|
45
|
+
host: ENV['CANVAS_API_PATH'],
|
46
|
+
)
|
29
47
|
end
|
30
48
|
end
|
31
49
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class FillInMultipleBlanks
|
7
|
-
attr_accessor :title, :text, :comments, :blank_id
|
7
|
+
attr_accessor :id, :title, :text, :comments, :blank_id
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -25,8 +25,9 @@ module GithubToCanvasQuiz
|
|
25
25
|
'answer_text' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
27
|
'answer_comment_html' => comments,
|
28
|
-
'blank_id' => blank_id
|
29
|
-
|
28
|
+
'blank_id' => blank_id,
|
29
|
+
'id' => id
|
30
|
+
}.reject { |_,v| v.nil? }
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class Matching
|
7
|
-
attr_accessor :title, :text, :comments, :left, :right
|
7
|
+
attr_accessor :id, :title, :text, :comments, :left, :right
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -26,8 +26,9 @@ module GithubToCanvasQuiz
|
|
26
26
|
'answer_weight' => 100,
|
27
27
|
'answer_comment_html' => comments,
|
28
28
|
'answer_match_left' => left,
|
29
|
-
'answer_match_right' => right
|
30
|
-
|
29
|
+
'answer_match_right' => right,
|
30
|
+
'id' => id
|
31
|
+
}.reject { |_,v| v.nil? }
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class MultipleAnswers
|
7
|
-
attr_accessor :title, :text, :comments
|
7
|
+
attr_accessor :id, :title, :text, :comments
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -24,8 +24,9 @@ module GithubToCanvasQuiz
|
|
24
24
|
{
|
25
25
|
'answer_html' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
|
-
'answer_comment_html' => comments
|
28
|
-
|
27
|
+
'answer_comment_html' => comments,
|
28
|
+
'id' => id
|
29
|
+
}.reject { |_,v| v.nil? }
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class MultipleChoice
|
7
|
-
attr_accessor :title, :text, :comments
|
7
|
+
attr_accessor :id, :title, :text, :comments
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -24,8 +24,9 @@ module GithubToCanvasQuiz
|
|
24
24
|
{
|
25
25
|
'answer_html' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
|
-
'answer_comment_html' => comments
|
28
|
-
|
27
|
+
'answer_comment_html' => comments,
|
28
|
+
'id' => id
|
29
|
+
}.reject { |_,v| v.nil? }
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class MultipleDropdowns
|
7
|
-
attr_accessor :title, :text, :comments, :blank_id
|
7
|
+
attr_accessor :id, :title, :text, :comments, :blank_id
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -25,8 +25,9 @@ module GithubToCanvasQuiz
|
|
25
25
|
'answer_text' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
27
|
'answer_comment_html' => comments,
|
28
|
-
'blank_id' => blank_id
|
29
|
-
|
28
|
+
'blank_id' => blank_id,
|
29
|
+
'id' => id
|
30
|
+
}.reject { |_,v| v.nil? }
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class ShortAnswer
|
7
|
-
attr_accessor :title, :text, :comments
|
7
|
+
attr_accessor :id, :title, :text, :comments
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -24,8 +24,9 @@ module GithubToCanvasQuiz
|
|
24
24
|
{
|
25
25
|
'answer_text' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
|
-
'answer_comment_html' => comments
|
28
|
-
|
27
|
+
'answer_comment_html' => comments,
|
28
|
+
'id' => id
|
29
|
+
}.reject { |_,v| v.nil? }
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -4,7 +4,7 @@ module GithubToCanvasQuiz
|
|
4
4
|
module Model
|
5
5
|
module Answer
|
6
6
|
class TrueFalse
|
7
|
-
attr_accessor :title, :text, :comments
|
7
|
+
attr_accessor :id, :title, :text, :comments
|
8
8
|
|
9
9
|
def initialize(options)
|
10
10
|
options.each do |key, value|
|
@@ -24,8 +24,9 @@ module GithubToCanvasQuiz
|
|
24
24
|
{
|
25
25
|
'answer_text' => text,
|
26
26
|
'answer_weight' => title == 'Correct' ? 100 : 0,
|
27
|
-
'answer_comment_html' => comments
|
28
|
-
|
27
|
+
'answer_comment_html' => comments,
|
28
|
+
'id' => id
|
29
|
+
}.reject { |_,v| v.nil? }
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -22,16 +22,16 @@ module GithubToCanvasQuiz
|
|
22
22
|
def initialize(client, path)
|
23
23
|
path = File.expand_path(path)
|
24
24
|
raise DirectoryNotFoundError unless Pathname(path).directory?
|
25
|
-
|
25
|
+
|
26
26
|
@client = client
|
27
27
|
@path = path
|
28
28
|
@repo = RepositoryInterface.new(path)
|
29
29
|
@quiz = parse_quiz
|
30
|
-
@questions_with_path = parse_questions_with_path
|
30
|
+
@questions_with_path = parse_questions_with_path if @quiz.id
|
31
31
|
end
|
32
32
|
|
33
33
|
def sync
|
34
|
-
backup_canvas_to_json!
|
34
|
+
backup_canvas_to_json! if @quiz.id
|
35
35
|
sync_quiz!
|
36
36
|
sync_questions!
|
37
37
|
backup_canvas_to_json!
|
@@ -48,14 +48,37 @@ module GithubToCanvasQuiz
|
|
48
48
|
|
49
49
|
# Get question data from Markdown files and return a Model::Question along with its path
|
50
50
|
def parse_questions_with_path
|
51
|
+
# read Canvas question data
|
52
|
+
canvas_questions = client.list_questions(quiz.course_id, quiz.id)
|
53
|
+
|
54
|
+
# read Markdown data
|
51
55
|
Dir["#{path}/questions/*.md"].map do |question_path|
|
52
56
|
question = Parser::Markdown::Question.new(File.read(question_path)).parse
|
53
57
|
question.quiz_id = quiz.id
|
54
58
|
question.course_id = quiz.course_id
|
59
|
+
|
60
|
+
# find the matching Canvas answer
|
61
|
+
canvas_question = canvas_questions.find { |canvas_question| canvas_question['id'] == question.id }
|
62
|
+
get_answer_ids!(question, canvas_question) if canvas_question
|
63
|
+
|
55
64
|
[question, question_path] # need that question path... gotta be a better way!
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
68
|
+
def get_answer_ids!(question, canvas_question)
|
69
|
+
question.answers.each do |answer|
|
70
|
+
# match the markdown answer to the Canvas answer based on the answer text
|
71
|
+
canvas_answer = canvas_question['answers'].find do |canvas_answer|
|
72
|
+
if canvas_answer['html'].nil? || canvas_answer['html'].empty?
|
73
|
+
canvas_answer['text'] == answer.text
|
74
|
+
else
|
75
|
+
canvas_answer['html'] == answer.text
|
76
|
+
end
|
77
|
+
end
|
78
|
+
answer.id = canvas_answer['id'].to_i if canvas_answer
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
59
82
|
# create or update quiz on Canvas
|
60
83
|
def sync_quiz!
|
61
84
|
if quiz.id
|
@@ -81,6 +104,8 @@ module GithubToCanvasQuiz
|
|
81
104
|
|
82
105
|
# Create or update questions on Canvas
|
83
106
|
def sync_questions!
|
107
|
+
@questions_with_path ||= parse_questions_with_path
|
108
|
+
|
84
109
|
questions_with_path.each do |question_with_path|
|
85
110
|
question, path = question_with_path
|
86
111
|
if question.id
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-to-canvas-quiz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ihollander
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: front_matter_parser
|