github-to-canvas 0.0.40 → 0.0.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +49 -31
- data/bin/github-to-canvas +23 -5
- data/lib/github-to-canvas.rb +7 -3
- data/lib/github-to-canvas/canvas_interface.rb +73 -0
- data/lib/github-to-canvas/update_canvas_lesson.rb +15 -8
- data/lib/github-to-canvas/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06a0c55312a2f98cfab18af28e44eff85e7e278178c92c2f87b0ea06e274dc7b
|
4
|
+
data.tar.gz: e6692af5eb0439d14239a3945d522a55986943a95f2987ba14c651e579459c34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1396b11ac39793429af8dc9ae34272d3ebc988475e68294acea92f0df1fd59d190eb5dce02671a1389267c62fed234b207dd67dcf894116b66ea4e914493adf
|
7
|
+
data.tar.gz: d9ce9f1eb8ef7c8ce1f3675b16f5d8b57e1cdecd1e39f0988a2dad6c14439903e1bad9dce3ff39a7f132d0a1afcd265142d8bf5a2f607fa7ac29cd1510c46dcd
|
data/README.md
CHANGED
@@ -2,19 +2,21 @@
|
|
2
2
|
|
3
3
|
## Introduction
|
4
4
|
|
5
|
-
The `github-to-canvas` gem is designed to
|
6
|
-
|
7
|
-
|
8
|
-
repository to include a `.canvas` file containing Canvas specific
|
5
|
+
The `github-to-canvas` gem is designed to aid in integrating GitHub and the
|
6
|
+
Canvas LMS. This gem takes a GitHub repository's `README.md` file, converts it
|
7
|
+
to HTML, and pushes it to Canvas using the Canvas API. The gem also has the ability
|
8
|
+
to updates a repository to include a `.canvas` file containing Canvas specific
|
9
|
+
information.
|
9
10
|
|
10
11
|
With the `.canvas` file in place, this gem can be used to continuously align
|
11
12
|
content between GitHub and Canvas using the GitHub repository as the single
|
12
13
|
source of truth.
|
13
14
|
|
14
|
-
This gem is built for use internally at [Flatiron School][]
|
15
|
+
This gem is built for use internally at [Flatiron School][], so some features may be
|
16
|
+
specific to Flatiron School branding and needs. Access to the
|
15
17
|
[Canvas LMS API][] and the ability to add pages and assignments to a Canvas
|
16
18
|
course are required. Write access to the GitHub repository being converted is
|
17
|
-
also required.
|
19
|
+
also required for committing `.canvas` files.
|
18
20
|
|
19
21
|
## Installation
|
20
22
|
|
@@ -27,15 +29,21 @@ also required.
|
|
27
29
|
In order to access the Canvas API, you must first generate an API key. Go to
|
28
30
|
your Canvas Account Settings and under **Approved Integrations**, create a
|
29
31
|
**New Access Token**. You will need to store this API key as an `ENV` variable
|
30
|
-
called `CANVAS_API_KEY`.
|
31
|
-
|
32
|
+
called `CANVAS_API_KEY`.
|
33
|
+
|
34
|
+
If you are using Zsh, the following command will add your new key to the top of `~/.zshrc`:
|
35
|
+
|
36
|
+
```sh
|
37
|
+
echo "$(export 'CANVAS_API_KEY=your-new-API-key-here' | cat - ~/.zshrc)" > ~/.zshrc
|
38
|
+
```
|
39
|
+
|
40
|
+
If you are using Bash, use this command instead:
|
32
41
|
|
33
42
|
```sh
|
34
|
-
echo "$(export 'CANVAS_API_KEY
|
43
|
+
echo "$(export 'CANVAS_API_KEY=your-new-API-key-here' | cat - ~/.bash_profile)" > ~/.bash_profile
|
35
44
|
```
|
36
45
|
|
37
|
-
>
|
38
|
-
> you are using something else like Bash.
|
46
|
+
> If you aren't sure which you use, run `echo $SHELL`
|
39
47
|
|
40
48
|
### Add Canvas API Base Path
|
41
49
|
|
@@ -47,9 +55,15 @@ as an `ENV` variable like the API key. **Do not add a `/` at the end after `/api
|
|
47
55
|
echo "$(export 'CANVAS_API_PATH=<your-base-api-path>' | cat - ~/.zshrc)" > ~/.zshrc
|
48
56
|
```
|
49
57
|
|
50
|
-
|
58
|
+
Or for Bash:
|
59
|
+
|
60
|
+
```sh
|
61
|
+
echo "$(export 'CANVAS_API_PATH=<your-base-api-path>' | cat - ~/.bash_profile)" > ~/.bash_profile
|
62
|
+
```
|
63
|
+
|
64
|
+
After both the API key and path are added to `~/.zshrc`, run `source ~/.zshrc` (`source ~/.bash_profile` for Bash)
|
51
65
|
to make them available in your current terminal. You can verify these variables
|
52
|
-
are present by running `ENV
|
66
|
+
are present by running `ENV` and finding them in the output list.
|
53
67
|
|
54
68
|
## Usage
|
55
69
|
|
@@ -70,26 +84,23 @@ using `master` branch `README.md` and the name of the current folder. By
|
|
70
84
|
default, if the repository contains folders, an **assignment** will be created.
|
71
85
|
Otherwise, a **page** will be created.
|
72
86
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
### Saving `.canvas` to GitHub
|
88
|
+
|
89
|
+
Using `--save-to-github` will create a `.canvas` YAML file in the local repo and attempt to commit
|
90
|
+
and push it to the remote repository. This file contains the course id, the newly
|
91
|
+
created page id, and the Canvas URL to the lesson for future reference.
|
78
92
|
|
79
93
|
If you create multiple Canvas lessons from the same repository, each lesson's
|
80
94
|
Canvas data will be stored in the `.canvas` file.
|
81
95
|
|
82
|
-
|
83
|
-
> will still be created locally.
|
84
|
-
|
85
|
-
### Update an existing Canvas Lesson
|
96
|
+
### Update an Existing Canvas Lesson
|
86
97
|
|
87
98
|
To update an existing Canvas lesson using a local repository, **a `.canvas` file
|
88
99
|
must be present in the repo**, as it contains the lesson information for the
|
89
100
|
Canvas API.
|
90
101
|
|
91
102
|
1. Clone down and/or change directory into the repository you'd like to update
|
92
|
-
2. Run `github-to-canvas --align
|
103
|
+
2. Run `github-to-canvas --align` from inside the local repo
|
93
104
|
|
94
105
|
`github-to-canvas` will get the course id and page/assignment id from the
|
95
106
|
`.canvas` file and update the associated Canvas lesson. If there are multiple
|
@@ -98,13 +109,20 @@ you have the same lesson in two courses created from one repository).
|
|
98
109
|
|
99
110
|
### Options
|
100
111
|
|
101
|
-
|
102
|
-
|
103
|
-
*
|
104
|
-
*
|
105
|
-
*
|
106
|
-
|
107
|
-
|
112
|
+
This gem provides to the following options:
|
113
|
+
|
114
|
+
* `-c, --create-lesson COURSE` - Creates a new Canvas lesson, converting the local repository's README.md to HTML. Adds .canvas file to remote repository
|
115
|
+
* `-a, --align` - Updates a canvas lesson based on the local repository's README.md
|
116
|
+
* `-n, --name NAME` - Sets the name of the new Canvas lesson to be created. If no name is given, repository folder name is used
|
117
|
+
* `-t, --type TYPE` - Sets the type of Canvas lesson to be created (page, assignment or discussion). If no type, type decided based on repository structure
|
118
|
+
* `-f, --file FILE` - Looks for and uses a markdown file in the currentt folder as source for conversion. Default file is README.md
|
119
|
+
* `-b, --branch BRANCH` - Sets the repository branch used for lesson creation
|
120
|
+
* `-s, --save-to-github` - Creates a local .canvas file and attempts to commit and push it to the GitHub repository
|
121
|
+
* `-l, --fis-links` - Adds additional Flatiron School HTML after markdown conversion
|
122
|
+
* `-r, --remove-header-and-footer` - Removes top lesson header and any Learn.co specific footer links before converting to HTML
|
123
|
+
* `-o, --only-content` - For align functionality only - updates the HTML content of a lesson without changing the name
|
124
|
+
* `-h, --help` - Outputs examples commands and all options
|
125
|
+
|
108
126
|
|
109
127
|
## Examples of Valid Images This Gem Can Convert
|
110
128
|
|
@@ -119,4 +137,4 @@ HTML:
|
|
119
137
|
</p>
|
120
138
|
|
121
139
|
[Canvas LMS API]: https://canvas.instructure.com/doc/api/index.html
|
122
|
-
[Flatiron School]: https://flatironschool.com/
|
140
|
+
[Flatiron School]: https://flatironschool.com/
|
data/bin/github-to-canvas
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
2
|
require 'optparse'
|
4
3
|
require 'github-to-canvas'
|
5
4
|
options = {}
|
@@ -23,6 +22,7 @@ OptionParser.new do |opts|
|
|
23
22
|
github-to-canvas --align [--branch BRANCH]
|
24
23
|
github-to-canvas --align [--only-content]
|
25
24
|
github-to-canvas --align [--branch BRANCH] [--fis-links]
|
25
|
+
github-to-canvas --info COURSE
|
26
26
|
github-to-canvas --version
|
27
27
|
|
28
28
|
|
@@ -35,9 +35,10 @@ OptionParser.new do |opts|
|
|
35
35
|
github-to-canvas --create-lesson 154 --name "Fetch Lab" -> Creates a lesson in course 154 with the provided name, derives the type from the local repo
|
36
36
|
github-to-canvas --create-lesson 154 --name "Fetch Lab" --type assignment -> Creates an assignment in course 154 with the provided name
|
37
37
|
github-to-canvas --create-lesson 154 --name "Fetch Lab" --branch solution -> Creates a lesson in course 154 with the provided name, uses the repository's solution branch and derives the type from the local repo
|
38
|
-
github-to-canvas --align
|
39
|
-
github-to-canvas --align --fis-links
|
40
|
-
github-to-canvas --align --remove-header-and-footer
|
38
|
+
github-to-canvas --align -> Patches existing lessons in Canvas based on the .canvas file
|
39
|
+
github-to-canvas --align --fis-links -> Patches existing lessons in Canvas based on the .canvas file, adds addition Flatiron School specific HTML
|
40
|
+
github-to-canvas --align --remove-header-and-footer -> Patches existing lessons in Canvas based on the .canvas file, removes top lesson header before converting to HTML
|
41
|
+
github-to-canvas --info COURSE -> Displays a course's lesson and assignment names
|
41
42
|
|
42
43
|
EOBANNER
|
43
44
|
|
@@ -87,10 +88,22 @@ OptionParser.new do |opts|
|
|
87
88
|
"Removes top lesson header and any Learn.co specific footer links before converting to HTML") do |r|
|
88
89
|
options[:remove_header_and_footer] = true
|
89
90
|
end
|
91
|
+
opts.on("--course COURSE",
|
92
|
+
"For align functionality only - updates the HTML content of a lesson using the provided course ID. Use with --id.") do |course|
|
93
|
+
options[:course] = course
|
94
|
+
end
|
95
|
+
opts.on("--id ID",
|
96
|
+
"For align functionality only - updates the HTML content of a lesson using the provided assignment or page ID. Use with --course.") do |id|
|
97
|
+
options[:id] = id
|
98
|
+
end
|
90
99
|
opts.on("-o", "--only-content",
|
91
100
|
"For align functionality only - updates the HTML content of a lesson without changing the name") do |o|
|
92
101
|
options[:only_content] = true
|
93
102
|
end
|
103
|
+
opts.on("-q COURSE", "--query COURSE",
|
104
|
+
"Displays a course's lessons and assignments") do |course|
|
105
|
+
options[:query] = course
|
106
|
+
end
|
94
107
|
|
95
108
|
end.parse!
|
96
109
|
|
@@ -98,6 +111,10 @@ if options[:version]
|
|
98
111
|
GithubToCanvas.new(mode: 'version', course: nil)
|
99
112
|
end
|
100
113
|
|
114
|
+
if options[:query]
|
115
|
+
GithubToCanvas.new(mode: 'query', course: options[:query], id: options[:id])
|
116
|
+
end
|
117
|
+
|
101
118
|
if !options[:type]
|
102
119
|
if Dir.glob("**/*/").empty?
|
103
120
|
options[:type] = "page"
|
@@ -139,7 +156,8 @@ end
|
|
139
156
|
|
140
157
|
if options[:align]
|
141
158
|
GithubToCanvas.new(mode: "align",
|
142
|
-
course:
|
159
|
+
course: options[:course],
|
160
|
+
id: options[:id],
|
143
161
|
filepath: Dir.pwd,
|
144
162
|
file_to_convert: options[:file_to_convert],
|
145
163
|
branch: options[:branch],
|
data/lib/github-to-canvas.rb
CHANGED
@@ -10,7 +10,8 @@ require_relative './github-to-canvas/version'
|
|
10
10
|
class GithubToCanvas
|
11
11
|
|
12
12
|
def initialize(mode:,
|
13
|
-
course
|
13
|
+
course:nil,
|
14
|
+
id:nil,
|
14
15
|
filepath:Dir.pwd,
|
15
16
|
file_to_convert:'README.md',
|
16
17
|
branch:'master',
|
@@ -23,7 +24,10 @@ class GithubToCanvas
|
|
23
24
|
|
24
25
|
if mode == 'version'
|
25
26
|
puts VERSION
|
26
|
-
|
27
|
+
end
|
28
|
+
|
29
|
+
if mode == 'query'
|
30
|
+
CanvasInterface.get_course_info(course, id)
|
27
31
|
end
|
28
32
|
|
29
33
|
if mode == 'create'
|
@@ -33,7 +37,7 @@ class GithubToCanvas
|
|
33
37
|
|
34
38
|
if mode == 'align'
|
35
39
|
puts "github-to-canvas will now align any existing Canvas lessons based on the current repo. NOTE: .canvas file must be present"
|
36
|
-
UpdateCanvasLesson.new(filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content)
|
40
|
+
UpdateCanvasLesson.new(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
@@ -2,6 +2,79 @@ require 'json'
|
|
2
2
|
require 'rest-client'
|
3
3
|
class CanvasInterface
|
4
4
|
|
5
|
+
def self.get_lesson_info(course, id)
|
6
|
+
page_url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/pages/#{id}"
|
7
|
+
assignment_url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/assignments/#{id}"
|
8
|
+
type = nil
|
9
|
+
info = ""
|
10
|
+
begin
|
11
|
+
page_response = RestClient.get(page_url, headers={
|
12
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
13
|
+
})
|
14
|
+
if ([200, 201].include? page_response.code)
|
15
|
+
info = JSON.parse(page_response.body)
|
16
|
+
puts "A Canvas page with the ID #{id} was found in course #{course}:"
|
17
|
+
type = "page"
|
18
|
+
end
|
19
|
+
rescue
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
assignment_response = RestClient.get(assignment_url, headers={
|
24
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
25
|
+
})
|
26
|
+
if ([200, 201].include? assignment_response.code)
|
27
|
+
info = JSON.parse(assignment_response.body)
|
28
|
+
puts "A Canvas assignment with the ID #{id} was found in course #{course}:"
|
29
|
+
type = "assignment"
|
30
|
+
end
|
31
|
+
rescue
|
32
|
+
end
|
33
|
+
[info, type]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_course_info(course, id)
|
37
|
+
if id
|
38
|
+
info = self.get_lesson_info(course, id)
|
39
|
+
pp info[1]
|
40
|
+
pp info[0]
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
results = []
|
46
|
+
index = 1
|
47
|
+
|
48
|
+
while !!index
|
49
|
+
url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/pages?order=asc&sort=title&page=#{index}&per_page=10"
|
50
|
+
index += 1
|
51
|
+
response = RestClient.get(url, headers={
|
52
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
53
|
+
})
|
54
|
+
pages = JSON.parse(response.body)
|
55
|
+
if ([200, 201].include? response.code) && (!pages.empty?)
|
56
|
+
results = results + pages
|
57
|
+
else
|
58
|
+
index = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
puts "Info for Course #{course} from #{ENV['CANVAS_API_PATH']}"
|
63
|
+
puts ""
|
64
|
+
puts "## Pages ##"
|
65
|
+
puts "Title : Page ID"
|
66
|
+
puts ""
|
67
|
+
|
68
|
+
results.each {|result|
|
69
|
+
puts "#{result['title']} : #{result['page_id']}"
|
70
|
+
}
|
71
|
+
|
72
|
+
rescue
|
73
|
+
puts "Something went wrong while getting info about course #{course}"
|
74
|
+
abort
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
5
78
|
def self.submit_to_canvas(course_id, type, name, readme)
|
6
79
|
response = self.push_to_canvas(course_id, type, name, readme)
|
7
80
|
if ![200, 201].include? response.code
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class UpdateCanvasLesson
|
2
2
|
|
3
|
-
def initialize(filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content)
|
3
|
+
def initialize(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id)
|
4
4
|
name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
5
|
begin
|
6
6
|
markdown = File.read("#{filepath}/#{file_to_convert}")
|
@@ -8,20 +8,27 @@ class UpdateCanvasLesson
|
|
8
8
|
puts "#{file_to_convert} not found in current directory. Exiting..."
|
9
9
|
abort
|
10
10
|
end
|
11
|
-
update_canvas_lesson(markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content)
|
11
|
+
update_canvas_lesson(course, markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id)
|
12
12
|
end
|
13
13
|
|
14
|
-
def update_canvas_lesson(markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content)
|
14
|
+
def update_canvas_lesson(course, markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id)
|
15
15
|
GithubInterface.get_updated_repo(filepath, branch)
|
16
16
|
new_html = RepositoryConverter.convert(filepath, markdown, branch, remove_header_and_footer)
|
17
17
|
if fis_links
|
18
18
|
new_html = RepositoryConverter.add_fis_links(filepath, new_html) # adds Flatiron School specific header and footer
|
19
19
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
if !id
|
21
|
+
# If no assignment or page ID is provided, tries to get info from a .canvas file
|
22
|
+
canvas_data = CanvasDotfile.read_canvas_data
|
23
|
+
canvas_data[:lessons].each { |lesson|
|
24
|
+
response = CanvasInterface.update_existing_lesson(lesson[:course_id], lesson[:id], lesson[:type], name, new_html, only_update_content)
|
25
|
+
# puts "Canvas lesson created. Lesson available at #{response['html_url']}."
|
26
|
+
}
|
27
|
+
else
|
28
|
+
# If an ID is provided, uses the ID instead of the .canvas file
|
29
|
+
info = CanvasInterface.get_lesson_info(course, id)
|
30
|
+
CanvasInterface.update_existing_lesson(course, id, info[1], name, new_html, only_update_content)
|
31
|
+
end
|
25
32
|
end
|
26
33
|
|
27
34
|
|