github-to-canvas 0.0.56 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +331 -52
- data/bin/github-to-canvas +177 -31
- data/lib/github-to-canvas.rb +143 -39
- data/lib/github-to-canvas/canvas_dotfile.rb +9 -9
- data/lib/github-to-canvas/canvas_interface.rb +375 -67
- data/lib/github-to-canvas/course_creation_interface.rb +9 -0
- data/lib/github-to-canvas/create_canvas_lesson.rb +8 -32
- data/lib/github-to-canvas/github_interface.rb +34 -0
- data/lib/github-to-canvas/repository_converter.rb +117 -31
- data/lib/github-to-canvas/repository_interface.rb +33 -0
- data/lib/github-to-canvas/update_canvas_lesson.rb +0 -32
- data/lib/github-to-canvas/version.rb +1 -1
- metadata +4 -2
@@ -1,38 +1,14 @@
|
|
1
1
|
class CreateCanvasLesson
|
2
2
|
|
3
|
-
def initialize(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
4
|
-
|
5
|
-
begin
|
6
|
-
markdown = File.read("#{filepath}/#{file_to_convert}")
|
7
|
-
rescue
|
8
|
-
puts "#{file_to_convert} not found in current directory. Exiting..."
|
9
|
-
abort
|
10
|
-
end
|
11
|
-
create_canvas_lesson(markdown, course, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
12
|
-
end
|
13
|
-
|
14
|
-
def create_canvas_lesson(markdown, course, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
15
|
-
GithubInterface.get_updated_repo(filepath, branch)
|
16
|
-
new_html = RepositoryConverter.convert(filepath, markdown, branch, remove_header_and_footer)
|
17
|
-
if fis_links
|
18
|
-
new_html = RepositoryConverter.add_fis_links(filepath, new_html, forkable)
|
19
|
-
end
|
20
|
-
response = CanvasInterface.submit_to_canvas(course, type, name, new_html)
|
3
|
+
# def initialize(course, filepath, file_to_convert, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
4
|
+
# # name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
21
5
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
puts "Canvas lesson created. Lesson available at #{response['html_url']}."
|
6
|
+
# create_canvas_lesson(markdown, course, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
7
|
+
# end
|
26
8
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
puts 'Commiting .canvas file'
|
32
|
-
GithubInterface.git_commit(filepath, 'AUTO: add .canvas file after migration')
|
33
|
-
puts 'Pushing .canvas file'
|
34
|
-
GithubInterface.git_push(filepath, branch)
|
35
|
-
end
|
36
|
-
end
|
9
|
+
# def create_canvas_lesson(markdown, course, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, forkable)
|
10
|
+
# response = CanvasInterface.submit_to_canvas(course, type, name, new_html)
|
11
|
+
|
12
|
+
# end
|
37
13
|
|
38
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rest-client'
|
1
3
|
class GithubInterface
|
2
4
|
|
3
5
|
def self.cd_into_and(filepath, command)
|
@@ -44,4 +46,36 @@ class GithubInterface
|
|
44
46
|
def self.git_push(filepath, branch)
|
45
47
|
self.cd_into_and(filepath, "git push origin #{branch}")
|
46
48
|
end
|
49
|
+
|
50
|
+
def self.read_remote(url)
|
51
|
+
if url.match(/https:\/\/github.com\//)
|
52
|
+
url = url.sub(/https:\/\/github.com\//, 'https://raw.githubusercontent.com/')
|
53
|
+
url = url.sub(/blob\//, '')
|
54
|
+
end
|
55
|
+
if !url.end_with?('.md')
|
56
|
+
url_fallback = url + '/main/README.md'
|
57
|
+
url = url + '/master/README.md'
|
58
|
+
end
|
59
|
+
begin
|
60
|
+
response = RestClient.get(url)
|
61
|
+
rescue
|
62
|
+
begin
|
63
|
+
response = RestClient.get(url_fallback)
|
64
|
+
rescue
|
65
|
+
puts 'Error reading ' + url
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
response.body
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.save_to_github(filepath, branch)
|
73
|
+
puts 'Adding .canvas file'
|
74
|
+
self.git_add(filepath, '.canvas')
|
75
|
+
puts 'Commiting .canvas file'
|
76
|
+
self.git_commit(filepath, 'AUTO: add .canvas file after migration')
|
77
|
+
puts 'Pushing .canvas file'
|
78
|
+
self.git_push(filepath, branch)
|
79
|
+
end
|
80
|
+
|
47
81
|
end
|
@@ -1,13 +1,58 @@
|
|
1
1
|
require 'redcarpet'
|
2
|
+
|
3
|
+
class CustomRender < Redcarpet::Render::HTML
|
4
|
+
def block_code(code, lang)
|
5
|
+
"<pre>" \
|
6
|
+
"<code>#{multi_line(code)}</code>" \
|
7
|
+
"</pre>"
|
8
|
+
end
|
9
|
+
|
10
|
+
def multi_line(code)
|
11
|
+
code.gsub(/\n(?=[^.])/, "<br />")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
2
15
|
class RepositoryConverter
|
16
|
+
def self.local_file_conversion(options)
|
17
|
+
GithubInterface.get_updated_repo(options[:filepath], options[:branch])
|
18
|
+
markdown = RepositoryInterface.read_local_file(options[:filepath], options[:file_to_convert])
|
19
|
+
raw_remote_url = self.set_raw_image_remote_url(options[:filepath])
|
20
|
+
|
21
|
+
markdown = self.fix_local_images(options, markdown, raw_remote_url)
|
22
|
+
html = self.convert_to_html(markdown)
|
23
|
+
# self.fix_local_html_links(options, html, options[:filepath])
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.remote_file_conversion(options)
|
27
|
+
markdown = GithubInterface.read_remote(options[:filepath])
|
28
|
+
raw_remote_url = self.set_raw_image_remote_url(options[:filepath])
|
29
|
+
markdown = self.fix_local_images(options, markdown, raw_remote_url)
|
30
|
+
html = self.convert_to_html(markdown)
|
31
|
+
# self.fix_local_html_links(options, html, options[:filepath])
|
32
|
+
end
|
3
33
|
|
4
|
-
def self.
|
5
|
-
|
6
|
-
|
7
|
-
|
34
|
+
def self.convert_to_html(markdown)
|
35
|
+
redcarpet = Redcarpet::Markdown.new(CustomRender, options={tables: true, autolink: true, fenced_code_blocks: true})
|
36
|
+
html = redcarpet.render(markdown)
|
37
|
+
self.remove_line_breaks(html)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.adjust_converted_html(options, html)
|
41
|
+
|
42
|
+
if options[:remove_header_and_footer]
|
43
|
+
html = self.remove_header_and_footer(html)
|
44
|
+
end
|
45
|
+
|
46
|
+
if options[:fis_links]
|
47
|
+
html = self.add_fis_links(options, html)
|
8
48
|
end
|
9
|
-
|
10
|
-
|
49
|
+
html
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.remove_header_and_footer(html)
|
53
|
+
new_html = self.remove_html_header(html)
|
54
|
+
new_html = self.remove_footer(new_html)
|
55
|
+
new_html
|
11
56
|
end
|
12
57
|
|
13
58
|
def self.remove_header(readme)
|
@@ -16,21 +61,49 @@ class RepositoryConverter
|
|
16
61
|
end
|
17
62
|
|
18
63
|
def self.remove_footer(readme)
|
19
|
-
readme.gsub(/<p (.+?)<\/p>/,"")
|
64
|
+
readme.gsub(/<p class='util--hide'(.+?)<\/p>/,"")
|
20
65
|
end
|
21
66
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
self.adjust_local_markdown_images(readme, raw_remote_url, branch)
|
25
|
-
self.adjust_local_html_images(readme, raw_remote_url)
|
67
|
+
def self.remove_html_header(html)
|
68
|
+
html.gsub(/<h1>.*<\/h1>/,"")
|
26
69
|
end
|
27
70
|
|
28
|
-
def self.
|
71
|
+
def self.fix_local_html_links(options, html, filepath)
|
72
|
+
# fixes relative hyperlinks by appending the github path to the file
|
73
|
+
filepath_base = filepath.match(/https:\/\/github.com\/.*?\/.*?\//).to_s
|
74
|
+
filepath_base = self.get_github_base_url(filepath)
|
75
|
+
html.gsub!(/a href="(?!(http|#)).*?"/) {|local_link|
|
76
|
+
local_link[8..-2]
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.fix_local_images(options, markdown, raw_remote_url)
|
81
|
+
# fixes markdown images with relative links by appending the raw githubusercontent path to the file
|
82
|
+
self.adjust_local_markdown_images(markdown, raw_remote_url, options[:branch])
|
83
|
+
self.adjust_local_html_images(markdown, raw_remote_url, options[:branch])
|
84
|
+
markdown
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.get_github_base_url(filepath)
|
29
88
|
remote = GithubInterface.git_remote(filepath)
|
30
|
-
remote.gsub!("git@github.com:","https://
|
31
|
-
remote.gsub!("https://github.com/","https://raw.githubusercontent.com/")
|
89
|
+
remote.gsub!("git@github.com:","https://github.com/")
|
32
90
|
remote.gsub!(/.git$/,"")
|
33
|
-
remote.strip!
|
91
|
+
remote.strip!
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def self.set_raw_image_remote_url(filepath)
|
96
|
+
if filepath.include? 'https://github.com/'
|
97
|
+
remote = filepath
|
98
|
+
else
|
99
|
+
remote = GithubInterface.git_remote(filepath)
|
100
|
+
end
|
101
|
+
raw_remote = remote.gsub("git@github.com:","https://raw.githubusercontent.com/")
|
102
|
+
raw_remote = raw_remote.gsub("https://github.com/","https://raw.githubusercontent.com/")
|
103
|
+
raw_remote = raw_remote.gsub(/\/blob\/master\/.*$/,"")
|
104
|
+
raw_remote = raw_remote.gsub(/\/blob\/main\/.*$/,"")
|
105
|
+
raw_remote = raw_remote.gsub(/.git$/,"")
|
106
|
+
raw_remote.strip
|
34
107
|
end
|
35
108
|
|
36
109
|
def self.get_repo_url(filepath)
|
@@ -53,38 +126,50 @@ class RepositoryConverter
|
|
53
126
|
}
|
54
127
|
end
|
55
128
|
|
56
|
-
def self.adjust_local_html_images(readme, raw_remote_url)
|
129
|
+
def self.adjust_local_html_images(readme, raw_remote_url, branch)
|
57
130
|
readme.gsub!(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
|
58
131
|
if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube')
|
59
132
|
image_source.gsub!(/(\'|\")/, "")
|
60
133
|
image_source.gsub!(/src=/, '')
|
61
134
|
image_source.strip!
|
62
|
-
'src="' + raw_remote_url + '/
|
135
|
+
'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
|
63
136
|
else
|
64
137
|
image_source
|
65
138
|
end
|
66
139
|
}
|
67
140
|
end
|
68
141
|
|
69
|
-
def self.
|
70
|
-
|
71
|
-
# File.write("#{filepath}/README.html", redcarpet.render(readme))
|
72
|
-
redcarpet.render(readme)
|
142
|
+
def self.remove_line_breaks(html)
|
143
|
+
html.gsub("\n",' ')
|
73
144
|
end
|
74
145
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
146
|
+
|
147
|
+
|
148
|
+
def self.get_repo_info(filepath)
|
149
|
+
if !filepath.match?('https://github.com')
|
150
|
+
repo_path = self.get_repo_url(filepath)
|
151
|
+
else
|
152
|
+
repo_path = filepath
|
153
|
+
end
|
79
154
|
|
80
|
-
|
81
|
-
|
82
|
-
|
155
|
+
{
|
156
|
+
repo_path: repo_path,
|
157
|
+
repo_name: repo_path.split('/')[4],
|
158
|
+
repo_org: repo_path.split('/')[3]
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.add_fis_links(options, html)
|
163
|
+
repo_info = self.get_repo_info(options[:filepath])
|
164
|
+
html = html.sub(/<div id="git-data-element.*<header class="fis-header.*<\/header>/,'') # remove existing fis header
|
165
|
+
header = self.create_github_link_header(repo_info[:repo_path], options[:forkable])
|
166
|
+
data_element = self.create_data_element(repo_info[:repo_org], repo_info[:repo_name])
|
167
|
+
data_element + header + html
|
83
168
|
end
|
84
169
|
|
85
170
|
def self.create_github_link_header(repo_path, forkable)
|
86
171
|
# add link to associated repository
|
87
|
-
|
172
|
+
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>"
|
88
173
|
|
89
174
|
# add link to new issue form
|
90
175
|
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,9 +177,9 @@ class RepositoryConverter
|
|
92
177
|
# add link to fork (forking handled by separate Flatiron server, generation of link handled via custom Canvas JS theme file)
|
93
178
|
if (forkable)
|
94
179
|
github_fork_link = "<a class='fis-fork-link' id='fork-link' href='#' target='_blank' rel='noopener'><img id='fork-img' title='Fork This Assignment' alt='Fork This Assignment' /></a>"
|
95
|
-
"<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_issue_link}</header>"
|
180
|
+
"<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_repo_link}#{github_issue_link}</header>"
|
96
181
|
else
|
97
|
-
"<header class='fis-header' style='visibility: hidden;'>#{github_issue_link}</header>"
|
182
|
+
"<header class='fis-header' style='visibility: hidden;'>#{github_repo_link}#{github_issue_link}</header>"
|
98
183
|
end
|
99
184
|
end
|
100
185
|
|
@@ -102,4 +187,5 @@ class RepositoryConverter
|
|
102
187
|
"<div id='git-data-element' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
|
103
188
|
end
|
104
189
|
|
190
|
+
|
105
191
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class RepositoryInterface
|
2
|
+
|
3
|
+
def self.local_repo_post_submission(options, response)
|
4
|
+
# Updates or creates a local .canvas file
|
5
|
+
CanvasDotfile.update_or_create(options, response)
|
6
|
+
|
7
|
+
# If --save option is used, the .canvas file gets committed and pushed to the remote repo
|
8
|
+
if options[:save_to_github]
|
9
|
+
self.save_to_github(options[:filepath], options[:branch])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.get_name(filepath, html)
|
14
|
+
repo_info = RepositoryConverter.get_repo_info(filepath)
|
15
|
+
name = html[/<h1>.*<\/h1>/]
|
16
|
+
if name
|
17
|
+
name = name.sub('<h1>','').sub('</h1>','')
|
18
|
+
else
|
19
|
+
name = repo_info[:repo_name].split(/[- _]/).map(&:capitalize).join(' ')
|
20
|
+
end
|
21
|
+
name
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.read_local_file(filepath, file_to_convert)
|
25
|
+
begin
|
26
|
+
markdown = File.read("#{filepath}/#{file_to_convert}")
|
27
|
+
rescue
|
28
|
+
puts "#{file_to_convert} not found in current directory. Exiting..."
|
29
|
+
abort
|
30
|
+
end
|
31
|
+
markdown
|
32
|
+
end
|
33
|
+
end
|
@@ -1,29 +1,10 @@
|
|
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, forkable)
|
4
|
-
# name = name.split(/[- _]/).map(&:capitalize).join(' ')
|
5
|
-
begin
|
6
|
-
markdown = File.read("#{filepath}/#{file_to_convert}")
|
7
|
-
rescue
|
8
|
-
puts "#{file_to_convert} not found in current directory. Exiting..."
|
9
|
-
abort
|
10
|
-
end
|
11
4
|
update_canvas_lesson(course, markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id, forkable)
|
12
5
|
end
|
13
6
|
|
14
7
|
def update_canvas_lesson(course, markdown, filepath, branch, name, type, save_to_github, fis_links, remove_header_and_footer, only_update_content, id, forkable)
|
15
|
-
# Pulls any updates that exist on GitHub
|
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.
|
20
|
-
new_html = RepositoryConverter.convert(filepath, markdown, branch, remove_header_and_footer)
|
21
|
-
|
22
|
-
# adds Flatiron School specific header and footer
|
23
|
-
if fis_links
|
24
|
-
new_html = RepositoryConverter.add_fis_links(filepath, new_html, forkable)
|
25
|
-
end
|
26
|
-
|
27
8
|
# Read the local .canvas file if --id <ID> is not used. Otherwise, use provided ID (--course <COURSE> also required)
|
28
9
|
if !id
|
29
10
|
canvas_data = CanvasDotfile.read_canvas_data
|
@@ -37,20 +18,7 @@ class UpdateCanvasLesson
|
|
37
18
|
|
38
19
|
# Implements update on Canvas
|
39
20
|
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])
|
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
21
|
end
|
53
|
-
|
54
22
|
end
|
55
23
|
|
56
24
|
|
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.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maxwellbenton
|
@@ -82,9 +82,11 @@ files:
|
|
82
82
|
- lib/github-to-canvas.rb
|
83
83
|
- lib/github-to-canvas/canvas_dotfile.rb
|
84
84
|
- lib/github-to-canvas/canvas_interface.rb
|
85
|
+
- lib/github-to-canvas/course_creation_interface.rb
|
85
86
|
- lib/github-to-canvas/create_canvas_lesson.rb
|
86
87
|
- lib/github-to-canvas/github_interface.rb
|
87
88
|
- lib/github-to-canvas/repository_converter.rb
|
89
|
+
- lib/github-to-canvas/repository_interface.rb
|
88
90
|
- lib/github-to-canvas/update_canvas_lesson.rb
|
89
91
|
- lib/github-to-canvas/version.rb
|
90
92
|
homepage: https://github.com/learn-co-curriculum/github-to-canvas
|
@@ -106,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
108
|
- !ruby/object:Gem::Version
|
107
109
|
version: '0'
|
108
110
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.0.8
|
110
112
|
signing_key:
|
111
113
|
specification_version: 4
|
112
114
|
summary: github-to-canvas is a tool for migrating and aligning GitHub content with
|