github-to-canvas 0.0.19 → 0.0.24
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/bin/github-to-canvas +46 -12
- data/lib/github-to-canvas.rb +12 -3
- data/lib/github-to-canvas/canvas_interface.rb +24 -8
- data/lib/github-to-canvas/create_canvas_lesson.rb +7 -4
- data/lib/github-to-canvas/github_interface.rb +13 -7
- data/lib/github-to-canvas/repository_converter.rb +25 -1
- data/lib/github-to-canvas/update_canvas_lesson.rb +7 -4
- 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: d720431e21790c476e0cb901dc357a6c9535df029f9a73739a2d6d7acccb0758
|
4
|
+
data.tar.gz: a4826c7a1a660e85754f26063a24c277f4991261d460617042e8f14b3df83fb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0cf044ec46931fc2ff748b6e05a57513ab669aed896118a6db61d745b2f7546af8366dc3a33ea92e98c4b3278be62e0dea024a211f23aadf7ff95967c44558a
|
7
|
+
data.tar.gz: 3b2115286e05dc581c3b953c778e5ab00a4781ca46560666365481cc92bfaa80789080a9002a622a9faed43cd11626e45bdeaaf47406df21adbd81e5552d8b50
|
data/bin/github-to-canvas
CHANGED
@@ -18,19 +18,27 @@ OptionParser.new do |opts|
|
|
18
18
|
github-to-canvas --create COURSE [--branch BRANCH] [--name NAME]
|
19
19
|
github-to-canvas --create COURSE [--branch BRANCH] [--name NAME] [--type TYPE]
|
20
20
|
github-to-canvas --create COURSE [--dry-run]
|
21
|
+
github-to-canvas --create COURSE [--fis-links]
|
22
|
+
github-to-canvas --create COURSE [--fis-links] [--remove-header]
|
21
23
|
github-to-canvas --align
|
24
|
+
github-to-canvas --align [--branch BRANCH]
|
25
|
+
github-to-canvas --align [--branch BRANCH] [--fis-links]
|
22
26
|
github-to-canvas --version
|
27
|
+
|
23
28
|
|
24
29
|
Run these commands from inside a local GitHub repository. This gem is built for Flatiron School's internal use.
|
25
30
|
Some default behaviors assume this, like the default Canvas API path.
|
26
31
|
|
27
32
|
Example usage:
|
28
33
|
|
29
|
-
github-to-canvas --create 154 -> Creates a lesson in course 154,
|
30
|
-
github-to-canvas --create 154 --name "Fetch Lab" -> Creates a lesson in course 154 with the provided name,
|
34
|
+
github-to-canvas --create 154 -> Creates a lesson in course 154, derives the name and type from the local repo
|
35
|
+
github-to-canvas --create 154 --name "Fetch Lab" -> Creates a lesson in course 154 with the provided name, derives the type from the local repo
|
31
36
|
github-to-canvas --create 154 --name "Fetch Lab" --type assignment -> Creates an assignment in course 154 with the provided name
|
32
|
-
github-to-canvas --create 154 --name "Fetch Lab" --branch solution -> Creates a lesson in course 154 with the provided name,
|
33
|
-
|
37
|
+
github-to-canvas --create 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 -> 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 -> Patches existing lessons in Canvas based on the .canvas file, removes top lesson header before converting to HTML
|
41
|
+
|
34
42
|
EOBANNER
|
35
43
|
|
36
44
|
opts.on("-cCOURSE", "--create COURSE",
|
@@ -48,7 +56,7 @@ OptionParser.new do |opts|
|
|
48
56
|
end
|
49
57
|
opts.on("-tTYPE", "--type TYPE",
|
50
58
|
"Sets the type Canvas lesson to be created (page or assignment). If no type, type decided based on repository structure") do |type|
|
51
|
-
if type == 'page' || type == 'assignment'
|
59
|
+
if type == 'page' || type == 'assignment' || type == 'discussion'
|
52
60
|
options[:type] = type
|
53
61
|
else
|
54
62
|
puts "Invalid type. Defaulting to page"
|
@@ -64,9 +72,17 @@ OptionParser.new do |opts|
|
|
64
72
|
options[:version] = true
|
65
73
|
end
|
66
74
|
opts.on("-d", "--dry-run",
|
67
|
-
"Runs through creation without pushing to Canvas or GitHub") do |
|
75
|
+
"Runs through creation without pushing to Canvas or GitHub") do |d|
|
68
76
|
options[:dry] = true
|
69
77
|
end
|
78
|
+
opts.on("-f", "--fis-links",
|
79
|
+
"Adds additional Flatiron School HTML after markdown conversion") do |f|
|
80
|
+
options[:fis] = true
|
81
|
+
end
|
82
|
+
opts.on("-r", "--remove-header",
|
83
|
+
"Removes top lesson header before converting to HTML") do |r|
|
84
|
+
options[:remove_header] = true
|
85
|
+
end
|
70
86
|
|
71
87
|
end.parse!
|
72
88
|
|
@@ -74,10 +90,12 @@ if options[:version]
|
|
74
90
|
GithubToCanvas.new(mode: 'version', course: nil)
|
75
91
|
end
|
76
92
|
|
77
|
-
if
|
78
|
-
|
79
|
-
|
80
|
-
|
93
|
+
if !options[:type]
|
94
|
+
if Dir.glob("**/*/").empty?
|
95
|
+
options[:type] = "page"
|
96
|
+
else
|
97
|
+
options[:type] = "assignment"
|
98
|
+
end
|
81
99
|
end
|
82
100
|
|
83
101
|
if !options[:branch]
|
@@ -89,9 +107,25 @@ if !options[:name]
|
|
89
107
|
end
|
90
108
|
|
91
109
|
if options[:create]
|
92
|
-
GithubToCanvas.new(mode: "create",
|
110
|
+
GithubToCanvas.new(mode: "create",
|
111
|
+
course: options[:course],
|
112
|
+
filepath: Dir.pwd,
|
113
|
+
branch: options[:branch],
|
114
|
+
name: options[:name],
|
115
|
+
type: options[:type],
|
116
|
+
dry: !!options[:dry],
|
117
|
+
fis_links: !!options[:fis],
|
118
|
+
remove_header: !!options[:remove_header])
|
93
119
|
end
|
94
120
|
|
95
121
|
if options[:align]
|
96
|
-
GithubToCanvas.new(mode: "align",
|
122
|
+
GithubToCanvas.new(mode: "align",
|
123
|
+
course: nil,
|
124
|
+
filepath: Dir.pwd,
|
125
|
+
branch: options[:branch],
|
126
|
+
name: options[:name],
|
127
|
+
type: options[:type],
|
128
|
+
dry: !!options[:dry],
|
129
|
+
fis_links: !!options[:fis],
|
130
|
+
remove_header: !!options[:remove_header])
|
97
131
|
end
|
data/lib/github-to-canvas.rb
CHANGED
@@ -9,7 +9,16 @@ require_relative './github-to-canvas/version'
|
|
9
9
|
|
10
10
|
class GithubToCanvas
|
11
11
|
|
12
|
-
def initialize(mode:,
|
12
|
+
def initialize(mode:,
|
13
|
+
course:,
|
14
|
+
filepath:Dir.pwd,
|
15
|
+
branch:'master',
|
16
|
+
name:File.basename(Dir.getwd),
|
17
|
+
type:"page",
|
18
|
+
dry:false,
|
19
|
+
fis_links:false,
|
20
|
+
remove_header:false)
|
21
|
+
|
13
22
|
if mode == 'version'
|
14
23
|
puts VERSION
|
15
24
|
return
|
@@ -17,12 +26,12 @@ class GithubToCanvas
|
|
17
26
|
|
18
27
|
if mode == 'create'
|
19
28
|
puts "github-to-canvas will now create a Canvas lesson based on the current repo"
|
20
|
-
CreateCanvasLesson.new(course, filepath, branch, name, type, dry)
|
29
|
+
CreateCanvasLesson.new(course, filepath, branch, name, type, dry, fis_links, remove_header)
|
21
30
|
end
|
22
31
|
|
23
32
|
if mode == 'align'
|
24
33
|
puts "github-to-canvas will now align any existing Canvas lessons based on the current repo. NOTE: .canvas file must be present"
|
25
|
-
UpdateCanvasLesson.new(filepath, branch, name, type, dry)
|
34
|
+
UpdateCanvasLesson.new(filepath, branch, name, type, dry, fis_links, remove_header)
|
26
35
|
end
|
27
36
|
end
|
28
37
|
|
@@ -17,20 +17,31 @@ class CanvasInterface
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.push_to_canvas(course_id, type, name, new_readme)
|
20
|
-
|
20
|
+
if type == 'discussion'
|
21
|
+
url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/#{type}_topics"
|
22
|
+
else
|
23
|
+
url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/#{type}s"
|
24
|
+
end
|
21
25
|
payload = self.build_payload(type, name, new_readme)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
begin
|
27
|
+
RestClient.post(url, payload, headers={
|
28
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
29
|
+
})
|
30
|
+
rescue
|
31
|
+
puts "Something went wrong while pushing lesson #{id} to course #{course_id}"
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
28
35
|
def self.update_existing_lesson(course_id, id, type, name, new_readme, dry_run)
|
29
36
|
url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/#{type}s/#{id}"
|
30
37
|
payload = self.build_payload(type, name, new_readme)
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
begin
|
39
|
+
RestClient.put(url, payload, headers={
|
40
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
41
|
+
})
|
42
|
+
rescue
|
43
|
+
puts "Something went wrong while pushing lesson #{id} to course #{course_id}"
|
44
|
+
end
|
34
45
|
end
|
35
46
|
|
36
47
|
def self.build_payload(type, name, new_readme)
|
@@ -39,6 +50,11 @@ class CanvasInterface
|
|
39
50
|
'assignment[name]' => name,
|
40
51
|
'assignment[description]' => new_readme
|
41
52
|
}
|
53
|
+
elsif type == "discussion"
|
54
|
+
payload = {
|
55
|
+
'title' => name,
|
56
|
+
'message' => new_readme
|
57
|
+
}
|
42
58
|
else
|
43
59
|
payload = {
|
44
60
|
'wiki_page[title]' => name,
|
@@ -1,18 +1,21 @@
|
|
1
1
|
class CreateCanvasLesson
|
2
2
|
|
3
|
-
def initialize(course, filepath, branch, name, type, dry_run)
|
3
|
+
def initialize(course, filepath, branch, name, type, dry_run, fis_links, remove_header)
|
4
4
|
name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
5
|
original_readme = File.read("#{filepath}/README.md")
|
6
6
|
if !original_readme
|
7
7
|
puts 'README.md not found in current directory. Exiting...'
|
8
8
|
abort
|
9
9
|
end
|
10
|
-
create_canvas_lesson(original_readme, course, filepath, branch, name, type, dry_run)
|
10
|
+
create_canvas_lesson(original_readme, course, filepath, branch, name, type, dry_run, fis_links, remove_header)
|
11
11
|
end
|
12
12
|
|
13
|
-
def create_canvas_lesson(readme, course, filepath, branch, name, type, dry_run)
|
13
|
+
def create_canvas_lesson(readme, course, filepath, branch, name, type, dry_run, fis_links, remove_header)
|
14
14
|
GithubInterface.get_updated_repo(filepath, branch)
|
15
|
-
new_readme = RepositoryConverter.convert(filepath, readme, branch)
|
15
|
+
new_readme = RepositoryConverter.convert(filepath, readme, branch, remove_header)
|
16
|
+
if fis_links
|
17
|
+
new_readme = RepositoryConverter.add_fis_links(filepath, new_readme)
|
18
|
+
end
|
16
19
|
response = CanvasInterface.submit_to_canvas(course, type, name, new_readme, dry_run)
|
17
20
|
if dry_run
|
18
21
|
puts 'DRY RUN: Skipping dotfile creation and push to GitHub'
|
@@ -1,20 +1,26 @@
|
|
1
|
-
|
1
|
+
require 'byebug'
|
2
2
|
class GithubInterface
|
3
3
|
|
4
|
+
def self.cd_into_and(filepath, command)
|
5
|
+
cmd = "cd #{filepath} && #{command}"
|
6
|
+
puts cmd
|
7
|
+
`#{cmd}`
|
8
|
+
end
|
9
|
+
|
4
10
|
def self.get_updated_repo(filepath, branch)
|
5
11
|
self.git_co_branch(filepath, branch)
|
6
12
|
self.git_pull(filepath, branch)
|
7
13
|
end
|
8
14
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
puts cmd
|
12
|
-
`#{cmd}`
|
15
|
+
def self.get_current_branch(filepath)
|
16
|
+
self.cd_into_and(filepath, "git rev-parse --abbrev-ref HEAD")
|
13
17
|
end
|
14
18
|
|
15
19
|
def self.git_co_branch(filepath, branch)
|
16
|
-
|
17
|
-
|
20
|
+
self.cd_into_and(filepath, "git checkout #{branch}")
|
21
|
+
current_branch = self.get_current_branch(filepath)
|
22
|
+
puts "Current branch #{current_branch.strip}"
|
23
|
+
if !current_branch.match(branch)
|
18
24
|
puts "#{branch} branch not found. Exiting..."
|
19
25
|
abort
|
20
26
|
end
|
@@ -2,11 +2,18 @@ require 'redcarpet'
|
|
2
2
|
require 'byebug'
|
3
3
|
class RepositoryConverter
|
4
4
|
|
5
|
-
def self.convert(filepath, readme, branch)
|
5
|
+
def self.convert(filepath, readme, branch, remove_header)
|
6
|
+
if remove_header
|
7
|
+
self.remove_header(readme)
|
8
|
+
end
|
6
9
|
self.fix_local_images(filepath, readme, branch)
|
7
10
|
self.convert_to_html(filepath, readme)
|
8
11
|
end
|
9
12
|
|
13
|
+
def self.remove_header(readme)
|
14
|
+
readme.gsub!(/^#.+?\n\n/,"")
|
15
|
+
end
|
16
|
+
|
10
17
|
def self.fix_local_images(filepath, readme, branch)
|
11
18
|
raw_remote_url = self.set_raw_image_remote_url(filepath)
|
12
19
|
self.adjust_local_markdown_images(readme, raw_remote_url, branch)
|
@@ -21,6 +28,13 @@ class RepositoryConverter
|
|
21
28
|
remote.strip!
|
22
29
|
end
|
23
30
|
|
31
|
+
def self.get_repo_url(filepath)
|
32
|
+
remote = GithubInterface.git_remote(filepath)
|
33
|
+
remote.gsub!("git@github.com:","https://github.com/")
|
34
|
+
remote.gsub!(/.git$/,"")
|
35
|
+
remote.strip!
|
36
|
+
end
|
37
|
+
|
24
38
|
def self.adjust_local_markdown_images(readme, raw_remote_url, branch)
|
25
39
|
readme.gsub!(/\!\[.+\]\(.+\)/) {|image|
|
26
40
|
if !image.match('amazonaws.com') && !image.match('https://') && !image.match('youtube')
|
@@ -53,4 +67,14 @@ class RepositoryConverter
|
|
53
67
|
redcarpet.render(readme)
|
54
68
|
end
|
55
69
|
|
70
|
+
def self.add_fis_links(filepath, readme)
|
71
|
+
repo = self.get_repo_url(filepath)
|
72
|
+
github_repo_link = "<a style='text-decoration: none;' href='#{repo}' target='_blank' rel='noopener'><img style='width: 40px; height: 40px; margin: 2px;' title='Open GitHub Repo' src='https://curriculum-content.s3.amazonaws.com/git-logo-gray.png' alt='Link to GitHub Repo' /></a>"
|
73
|
+
github_issue_link = "<a style='text-decoration: none;' href='#{repo}/issues/new' target='_blank' rel='noopener'><img style='width: 40px; height: 40px; margin: 2px;' title='Create New Issue' src='https://curriculum-content.s3.amazonaws.com/flag-icon-gray.png' alt='Link to GitHub Repo Issue Form' /></a>"
|
74
|
+
|
75
|
+
html = "<p style='margin: 0; padding: 0; position: absolute; right: 5px; top: 5px; margin: 0; padding: 0;'>#{github_repo_link}#{github_issue_link}</p>"
|
76
|
+
|
77
|
+
readme + html
|
78
|
+
end
|
79
|
+
|
56
80
|
end
|
@@ -1,18 +1,21 @@
|
|
1
1
|
class UpdateCanvasLesson
|
2
2
|
|
3
|
-
def initialize(filepath, branch, name, type, dry_run)
|
3
|
+
def initialize(filepath, branch, name, type, dry_run, fis_links, remove_header)
|
4
4
|
name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
5
|
readme = File.read("#{filepath}/README.md")
|
6
6
|
if !readme
|
7
7
|
puts 'README.md not found in current directory. Exiting...'
|
8
8
|
abort
|
9
9
|
end
|
10
|
-
update_canvas_lesson(readme, filepath, branch, name, type, dry_run)
|
10
|
+
update_canvas_lesson(readme, filepath, branch, name, type, dry_run, fis_links, remove_header)
|
11
11
|
end
|
12
12
|
|
13
|
-
def update_canvas_lesson(readme, filepath, branch, name, type, dry_run)
|
13
|
+
def update_canvas_lesson(readme, filepath, branch, name, type, dry_run, fis_links, remove_header)
|
14
14
|
GithubInterface.get_updated_repo(filepath, branch)
|
15
|
-
new_readme = RepositoryConverter.convert(filepath, readme, branch)
|
15
|
+
new_readme = RepositoryConverter.convert(filepath, readme, branch, remove_header)
|
16
|
+
if fis_links
|
17
|
+
new_readme = RepositoryConverter.add_fis_links(filepath, new_readme)
|
18
|
+
end
|
16
19
|
canvas_data = CanvasDotfile.read_canvas_data
|
17
20
|
canvas_data[:lessons].each { |lesson|
|
18
21
|
CanvasInterface.update_existing_lesson(lesson[:course_id], lesson[:id], type, name, new_readme, dry_run)
|