github-to-canvas 0.0.42 → 0.0.48
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 +1 -1
- data/bin/github-to-canvas +24 -3
- data/lib/github-to-canvas.rb +12 -1
- data/lib/github-to-canvas/canvas_dotfile.rb +5 -6
- data/lib/github-to-canvas/canvas_interface.rb +25 -24
- data/lib/github-to-canvas/create_canvas_lesson.rb +11 -5
- data/lib/github-to-canvas/repository_converter.rb +31 -21
- data/lib/github-to-canvas/update_canvas_lesson.rb +29 -8
- data/lib/github-to-canvas/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: d00d3f8b2e4a748b6d8840c365904d980f7bc6f7ad8046cc44b0f28372cad834
|
4
|
+
data.tar.gz: 2cf19fe82846d2cb544ba8cccacd078e08c71c7270f4ecfa1a954d894cdf6750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74598233da7a1ecfc041937a838a06e14511fbc98c65a981c8a408f997289e0c3520fa600e023bba1c3800ee84c742bb79598ca067e8ba2e0957972df390173c
|
7
|
+
data.tar.gz: b81aca6a1ebd575642e438a60af63a24db731728b144de5e6f7e5be2ed8c36f6c5cdc93411aa7e64e6e6e231946d0db359a51497b7417b25c40d9f4c2b36f6fb
|
data/README.md
CHANGED
data/bin/github-to-canvas
CHANGED
@@ -36,7 +36,7 @@ OptionParser.new do |opts|
|
|
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
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
|
39
|
+
github-to-canvas --align --fis-links -> Patches existing lessons in Canvas based on the .canvas file, adds additional Flatiron School specific HTML and meta-data
|
40
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
41
|
github-to-canvas --info COURSE -> Displays a course's lesson and assignment names
|
42
42
|
|
@@ -104,6 +104,10 @@ OptionParser.new do |opts|
|
|
104
104
|
"Displays a course's lessons and assignments") do |course|
|
105
105
|
options[:query] = course
|
106
106
|
end
|
107
|
+
opts.on("--remote",
|
108
|
+
"Retrieves a Canvas lesson. Requires --course and --id") do |remote|
|
109
|
+
options[:remote] = true
|
110
|
+
end
|
107
111
|
|
108
112
|
end.parse!
|
109
113
|
|
@@ -115,6 +119,14 @@ if options[:query]
|
|
115
119
|
GithubToCanvas.new(mode: 'query', course: options[:query], id: options[:id])
|
116
120
|
end
|
117
121
|
|
122
|
+
if options[:remote]
|
123
|
+
if !options[:course] || !options[:id]
|
124
|
+
puts "Both --course and --id required when using --remote"
|
125
|
+
abort
|
126
|
+
end
|
127
|
+
GithubToCanvas.new(mode: 'remote', course: options[:course], id: options[:id])
|
128
|
+
end
|
129
|
+
|
118
130
|
if !options[:type]
|
119
131
|
if Dir.glob("**/*/").empty?
|
120
132
|
options[:type] = "page"
|
@@ -129,11 +141,20 @@ end
|
|
129
141
|
|
130
142
|
if !options[:name]
|
131
143
|
if options[:file_to_convert]
|
132
|
-
|
144
|
+
markdown = File.read("#{Dir.pwd}/#{options[:file_to_convert]}")
|
145
|
+
if markdown.match?(/^# .+?\n\n/)
|
146
|
+
options[:name] = markdown.match(/^# .+?\n\n/)[0].strip.gsub("# ","").gsub("#","")
|
147
|
+
elsif markdown.match?(/^# .+?\n/)
|
148
|
+
options[:name] = markdown.match(/^# .+?\n/)[0].strip.gsub("# ","").gsub("#","")
|
149
|
+
else
|
150
|
+
options[:name] = options[:file_to_convert]
|
151
|
+
end
|
133
152
|
else
|
134
153
|
markdown = File.read("#{Dir.pwd}/README.md")
|
135
154
|
if markdown.match?(/^# .+?\n\n/)
|
136
|
-
options[:name] = markdown.match(/^# .+?\n\n/)[0].strip.
|
155
|
+
options[:name] = markdown.match(/^# .+?\n\n/)[0].strip.gsub("# ","").gsub("#","")
|
156
|
+
elsif markdown.match?(/^# .+?\n/)
|
157
|
+
options[:name] = markdown.match(/^# .+?\n/)[0].strip.gsub("# ","").gsub("#","")
|
137
158
|
else
|
138
159
|
options[:name] = File.basename(Dir.getwd)
|
139
160
|
end
|
data/lib/github-to-canvas.rb
CHANGED
@@ -6,7 +6,6 @@ require_relative './github-to-canvas/canvas_interface'
|
|
6
6
|
require_relative './github-to-canvas/canvas_dotfile'
|
7
7
|
require_relative './github-to-canvas/version'
|
8
8
|
|
9
|
-
|
10
9
|
class GithubToCanvas
|
11
10
|
|
12
11
|
def initialize(mode:,
|
@@ -30,6 +29,18 @@ class GithubToCanvas
|
|
30
29
|
CanvasInterface.get_course_info(course, id)
|
31
30
|
end
|
32
31
|
|
32
|
+
if mode == 'remote'
|
33
|
+
lesson_data = CanvasInterface.get_lesson_info(course, id)
|
34
|
+
if !lesson_data[1]
|
35
|
+
puts "No lesson with id #{id} was found in course #{course}."
|
36
|
+
else
|
37
|
+
pp lesson_data[0]
|
38
|
+
puts "\nLesson Type: #{lesson_data[1]}"
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
33
44
|
if mode == 'create'
|
34
45
|
puts "github-to-canvas will now create a Canvas lesson based on the current repo"
|
35
46
|
CreateCanvasLesson.new(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer)
|
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
class CanvasDotfile
|
3
3
|
|
4
|
+
def self.exists?
|
5
|
+
File.file?(".canvas")
|
6
|
+
end
|
7
|
+
|
4
8
|
def self.update_or_create(filepath, response, course, type)
|
5
|
-
if
|
9
|
+
if self.exists?
|
6
10
|
if type == "assignment" || type == "discussion"
|
7
11
|
canvas_data = self.update_assignment_data(response, course, type)
|
8
12
|
else
|
@@ -22,11 +26,6 @@ class CanvasDotfile
|
|
22
26
|
File.write("#{filepath}/.canvas", canvas_data.to_yaml)
|
23
27
|
end
|
24
28
|
|
25
|
-
def self.commit_canvas_dotfile(filepath)
|
26
|
-
GithubInterface.git_add(filepath, '.canvas')
|
27
|
-
GithubInterface.git_commit(filepath, 'AUTO: add .canvas file after migration')
|
28
|
-
end
|
29
|
-
|
30
29
|
def self.read_canvas_data
|
31
30
|
if File.file?(".canvas")
|
32
31
|
YAML.load(File.read(".canvas"))
|
@@ -3,41 +3,41 @@ require 'rest-client'
|
|
3
3
|
class CanvasInterface
|
4
4
|
|
5
5
|
def self.get_lesson_info(course, id)
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
lesson_types = ["quizzes", "assignments", "pages", "discussion_topics"]
|
8
|
+
lesson_type_urls = []
|
9
|
+
lesson_types.each do |type|
|
10
|
+
lesson_type_urls << "#{ENV['CANVAS_API_PATH']}/courses/#{course}/#{type}/#{id}"
|
11
|
+
end
|
12
|
+
|
8
13
|
type = nil
|
9
14
|
info = ""
|
15
|
+
lesson_type_urls.each do |url|
|
10
16
|
begin
|
11
|
-
|
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={
|
17
|
+
response = RestClient.get(url, headers={
|
24
18
|
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
25
19
|
})
|
26
|
-
if
|
27
|
-
info = JSON.parse(
|
28
|
-
|
29
|
-
type
|
20
|
+
if [200, 201].include? response.code
|
21
|
+
info = JSON.parse(response.body)
|
22
|
+
type = lesson_types.find {|type| url.match?("#{type}")}
|
23
|
+
type.delete_suffix!('zes')
|
24
|
+
type.delete_suffix!('s')
|
25
|
+
puts "\nA Canvas #{type} was found in course #{course} with the id #{id}"
|
26
|
+
break
|
30
27
|
end
|
31
28
|
rescue
|
32
29
|
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
33
|
[info, type]
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.get_course_info(course, id)
|
37
37
|
if id
|
38
|
-
|
39
|
-
pp
|
40
|
-
pp
|
38
|
+
lesson_data = self.get_lesson_info(course, id)
|
39
|
+
pp lesson_data[0]
|
40
|
+
pp "\nLesson Type: #{lesson_data[1]}"
|
41
41
|
return
|
42
42
|
end
|
43
43
|
|
@@ -58,7 +58,8 @@ class CanvasInterface
|
|
58
58
|
index = nil
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
puts ""
|
62
|
+
puts ""
|
62
63
|
puts "Info for Course #{course} from #{ENV['CANVAS_API_PATH']}"
|
63
64
|
puts ""
|
64
65
|
puts "## Pages ##"
|
@@ -114,7 +115,7 @@ class CanvasInterface
|
|
114
115
|
})
|
115
116
|
rescue
|
116
117
|
puts "Something went wrong while pushing lesson #{id} to course #{course_id}"
|
117
|
-
|
118
|
+
nil
|
118
119
|
end
|
119
120
|
end
|
120
121
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class CreateCanvasLesson
|
2
2
|
|
3
3
|
def initialize(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer)
|
4
|
-
name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
4
|
+
# name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
5
|
begin
|
6
6
|
markdown = File.read("#{filepath}/#{file_to_convert}")
|
7
7
|
rescue
|
@@ -18,15 +18,21 @@ class CreateCanvasLesson
|
|
18
18
|
new_html = RepositoryConverter.add_fis_links(filepath, new_html)
|
19
19
|
end
|
20
20
|
response = CanvasInterface.submit_to_canvas(course, type, name, new_html)
|
21
|
+
|
22
|
+
puts 'Creating .canvas file'
|
23
|
+
CanvasDotfile.update_or_create(filepath, response, course, type)
|
24
|
+
|
25
|
+
puts "Canvas lesson created. Lesson available at #{response['html_url']}."
|
26
|
+
|
27
|
+
# If --save option is used, the .canvas file gets committed and pushed to the remote repo
|
21
28
|
if save_to_github
|
22
|
-
puts '
|
23
|
-
|
29
|
+
puts 'Adding .canvas file'
|
30
|
+
GithubInterface.git_add(filepath, '.canvas')
|
24
31
|
puts 'Commiting .canvas file'
|
25
|
-
|
32
|
+
GithubInterface.git_commit(filepath, 'AUTO: add .canvas file after migration')
|
26
33
|
puts 'Pushing .canvas file'
|
27
34
|
GithubInterface.git_push(filepath, branch)
|
28
35
|
end
|
29
|
-
puts "Canvas lesson created. Lesson available at #{response['html_url']}."
|
30
36
|
end
|
31
37
|
|
32
38
|
end
|
@@ -11,7 +11,8 @@ class RepositoryConverter
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.remove_header(readme)
|
14
|
-
readme.gsub(/^# .+?\n\n/,"")
|
14
|
+
readme.gsub!(/^# .+?\n\n/,"")
|
15
|
+
readme.gsub(/^# .+?\n/,"")
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.remove_footer(readme)
|
@@ -40,27 +41,27 @@ class RepositoryConverter
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def self.adjust_local_markdown_images(readme, raw_remote_url, branch)
|
43
|
-
readme.gsub!(/\!\[.+\]\(.+\)/) {|
|
44
|
-
if !
|
45
|
-
|
44
|
+
readme.gsub!(/\!\[.+\]\(.+\)/) {|image_markdown|
|
45
|
+
if !image_markdown.match?('amazonaws.com') && !image_markdown.match?('https://') && !image_markdown.match?('http://') && !image_markdown.match?('youtube')
|
46
|
+
image_markdown.gsub!(/\(.+\)/) { |path|
|
46
47
|
path.delete_prefix!("(")
|
47
48
|
path.delete_suffix!(")")
|
48
49
|
"(" + raw_remote_url + "/#{branch}/" + path + ")"
|
49
50
|
}
|
50
51
|
end
|
51
|
-
|
52
|
+
image_markdown
|
52
53
|
}
|
53
54
|
end
|
54
55
|
|
55
56
|
def self.adjust_local_html_images(readme, raw_remote_url)
|
56
|
-
readme.gsub!(/src
|
57
|
-
if !
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
'src="' + raw_remote_url + '/master/' +
|
57
|
+
readme.gsub!(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
|
58
|
+
if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube')
|
59
|
+
image_source.gsub!(/(\'|\")/, "")
|
60
|
+
image_source.gsub!(/src=/, '')
|
61
|
+
image_source.strip!
|
62
|
+
'src="' + raw_remote_url + '/master/' + image_source + '"'
|
62
63
|
else
|
63
|
-
|
64
|
+
image_source
|
64
65
|
end
|
65
66
|
}
|
66
67
|
end
|
@@ -72,15 +73,24 @@ class RepositoryConverter
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def self.add_fis_links(filepath, readme)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
repo_path = self.get_repo_url(filepath)
|
77
|
+
header = self.create_github_link_header(repo_path)
|
78
|
+
header + readme
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.create_github_link_header(repo_path)
|
82
|
+
repo_name = repo_path.split('/')[-1]
|
83
|
+
|
84
|
+
# add link to fork (forking handled by separate Flatiron server, generation of link handled via custom Canvas JS theme file)
|
85
|
+
github_fork_link = "<a class='fis-git-link' data-repo='#{repo_name}' href='#' target='_blank' rel='noopener'><img id='fork-img' title='Fork This Assignment' alt='Fork This Assignment' /></a>"
|
86
|
+
|
87
|
+
# add link to associated repository
|
88
|
+
# github_repo_link = "<a class='fis-git-link' href='#{repo_path}' target='_blank' rel='noopener'><img id='repo-img' title='Open GitHub Repo' alt='GitHub Repo' /></a>"
|
89
|
+
|
90
|
+
# add link to new issue form
|
91
|
+
github_issue_link = "<a class='fis-git-link' href='#{repo_path}/issues/new' target='_blank' rel='noopener'><img id='issue-img' title='Create New Issue' alt='Create New Issue' /></a>"
|
92
|
+
|
93
|
+
"<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_issue_link}</header>"
|
84
94
|
end
|
85
95
|
|
86
96
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class UpdateCanvasLesson
|
2
2
|
|
3
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
|
-
name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
4
|
+
# name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
5
|
begin
|
6
6
|
markdown = File.read("#{filepath}/#{file_to_convert}")
|
7
7
|
rescue
|
@@ -12,25 +12,46 @@ class UpdateCanvasLesson
|
|
12
12
|
end
|
13
13
|
|
14
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
|
+
# Pulls any updates that exist on GitHub
|
15
16
|
GithubInterface.get_updated_repo(filepath, branch)
|
17
|
+
|
18
|
+
# Converts markdown to HTML
|
19
|
+
# Default is README.md. --file <FILENAME> can be used to override default.
|
16
20
|
new_html = RepositoryConverter.convert(filepath, markdown, branch, remove_header_and_footer)
|
21
|
+
|
22
|
+
# adds Flatiron School specific header and footer
|
17
23
|
if fis_links
|
18
|
-
new_html = RepositoryConverter.add_fis_links(filepath, new_html)
|
24
|
+
new_html = RepositoryConverter.add_fis_links(filepath, new_html)
|
19
25
|
end
|
26
|
+
|
27
|
+
# Read the local .canvas file if --id <ID> is not used. Otherwise, use provided ID (--course <COURSE> also required)
|
20
28
|
if !id
|
21
|
-
# If no assignment or page ID is provided, tries to get info from a .canvas file
|
22
29
|
canvas_data = CanvasDotfile.read_canvas_data
|
23
|
-
canvas_data[:lessons].
|
30
|
+
canvas_data[:lessons] = canvas_data[:lessons].map { |lesson|
|
24
31
|
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
32
|
}
|
27
33
|
else
|
28
|
-
# If an ID
|
34
|
+
# If an ID (and course) are provided, they are used instead of the .canvas file
|
35
|
+
# Gets the current lesson's type (page or assignment)
|
29
36
|
info = CanvasInterface.get_lesson_info(course, id)
|
30
|
-
|
37
|
+
|
38
|
+
# Implements update on Canvas
|
39
|
+
response = JSON.parse(CanvasInterface.update_existing_lesson(course, id, info[1], name, new_html, only_update_content))
|
40
|
+
|
41
|
+
# Updates or creates a local .canvas file
|
42
|
+
CanvasDotfile.update_or_create(filepath, response, course, info[1])
|
31
43
|
end
|
44
|
+
# If --save option is used, the .canvas file gets committed and pushed to the remote repo
|
45
|
+
if save_to_github
|
46
|
+
puts 'Adding .canvas file'
|
47
|
+
GithubInterface.git_add(filepath, '.canvas')
|
48
|
+
puts 'Commiting .canvas file'
|
49
|
+
GithubInterface.git_commit(filepath, 'AUTO: add .canvas file after migration')
|
50
|
+
puts 'Pushing .canvas file'
|
51
|
+
GithubInterface.git_push(filepath, branch)
|
52
|
+
end
|
53
|
+
|
32
54
|
end
|
33
|
-
|
34
55
|
|
35
56
|
|
36
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-to-canvas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.48
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maxwellbenton
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
108
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
109
|
+
rubygems_version: 3.1.4
|
110
110
|
signing_key:
|
111
111
|
specification_version: 4
|
112
112
|
summary: github-to-canvas is a tool for migrating and aligning GitHub content with
|