github-to-canvas 0.0.9 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22e9d0258dc0813b99121938b37d82311ffb922ff0ffbcf4b222640e748f8659
4
- data.tar.gz: b804e8f2a65a4d733409cfd3af3d3528bb696f3b458d9a1e30225b2d6f9cc5b9
3
+ metadata.gz: 732a757e941548fa67c1ede523fe03575dc22e8890d87300ce8e41732a2f01e3
4
+ data.tar.gz: 9966442368051e67fea9e6b7ce44ebb1555c645bd61f0512feea8e9ca3486995
5
5
  SHA512:
6
- metadata.gz: 91ab69410efd3b89570ca9484942fd20799a2b2d074e7bd34de95c3bbd50606a435d11ab3d127021d7c4a4f460904644c0ded04f807725b9041681ed6f4b0710
7
- data.tar.gz: 1757de283f3ad403cf3c49b3b89ea842b4f05cd9a075061e601f45690d597885b8d26bee069a5976236670eeb27af9aa731c73fdd35082f179ec4d59c699ea7c
6
+ metadata.gz: 6f67897ee3991f5e914524e04a7b90fb0985092c106ce57b16d64cb8afa74ec1555dbd8dbd57ad0a4be780595b6c8a02af9d914d5e6a63dbc9f5fac662418285
7
+ data.tar.gz: 8e2793cc5b58f7ad2e0a1e2e9a4244d34172736e0d69f34940f87b0603432287ddb088876392905c36adaef4809298791a1164118e6ab8dec95a06469bb6cc24
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # GitHub to Canvas Gem
2
-
2
+ hello
3
3
  ## Introduction
4
4
 
5
5
  The `github-to-canvas` gem is designed to enable GitHub to Canvas LMS
data/bin/github-to-canvas CHANGED
@@ -17,8 +17,8 @@ OptionParser.new do |opts|
17
17
  github-to-canvas --create COURSE [--branch BRANCH]
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
+ github-to-canvas --create COURSE [--dry-run]
20
21
  github-to-canvas --align
21
- github-to-canvas --reverse-align
22
22
  github-to-canvas --version
23
23
 
24
24
  Run these commands from inside a local GitHub repository. This gem is built for Flatiron School's internal use.
@@ -59,14 +59,14 @@ OptionParser.new do |opts|
59
59
  "Updates a canvas lesson based on the local repository's README.md") do |a|
60
60
  options[:align] = true
61
61
  end
62
- opts.on("-r", "--reverse-align",
63
- "Updates a remote repository, converting the Canvas lesson body to markdown and pushing it remotely as the README.md") do |r|
64
- options[:reverse_align] = true
65
- end
66
62
  opts.on("-v", "--version",
67
63
  "Displays current gem version") do |v|
68
64
  options[:version] = true
69
65
  end
66
+ opts.on("-d", "--dry-run",
67
+ "Runs through creation without pushing to Canvas or GitHub") do |v|
68
+ options[:dry] = true
69
+ end
70
70
 
71
71
  end.parse!
72
72
 
@@ -89,13 +89,9 @@ if !options[:name]
89
89
  end
90
90
 
91
91
  if options[:create]
92
- GithubToCanvas.new(mode: "create", course: options[:course], filepath: Dir.pwd, branch: options[:branch], name: options[:name], type: options[:type])
92
+ GithubToCanvas.new(mode: "create", course: options[:course], filepath: Dir.pwd, branch: options[:branch], name: options[:name], type: options[:type], dry: !!options[:dry])
93
93
  end
94
94
 
95
95
  if options[:align]
96
- puts 'feature not working yet'
97
- end
98
-
99
- if options[:reverse_align]
100
- puts 'feature not working yet'
96
+ GithubToCanvas.new(mode: "align", course: nil, filepath: Dir.pwd, branch: options[:branch], name: options[:name], type: options[:type], dry: !!options[:dry])
101
97
  end
@@ -1,9 +1,15 @@
1
- require_relative './github-to-canvas/create-canvas-lesson'
1
+ require_relative './github-to-canvas/create_canvas_lesson'
2
+ require_relative './github-to-canvas/update_canvas_lesson'
3
+ require_relative './github-to-canvas/repository_converter'
4
+ require_relative './github-to-canvas/github_interface'
5
+ require_relative './github-to-canvas/canvas_interface'
6
+ require_relative './github-to-canvas/canvas_dotfile'
2
7
  require_relative './github-to-canvas/version'
3
8
 
9
+
4
10
  class GithubToCanvas
5
11
 
6
- def initialize(mode:, course:, filepath:Dir.pwd, branch:'master', name:File.basename(Dir.getwd), type:"page")
12
+ def initialize(mode:, course:, filepath:Dir.pwd, branch:'master', name:File.basename(Dir.getwd), type:"page", dry:false)
7
13
  if mode == 'version'
8
14
  puts VERSION
9
15
  return
@@ -11,7 +17,12 @@ class GithubToCanvas
11
17
 
12
18
  if mode == 'create'
13
19
  puts "github-to-canvas will now create a Canvas lesson based on the current repo"
14
- CreateCanvasLesson.new(course, filepath, branch, name, type)
20
+ CreateCanvasLesson.new(course, filepath, branch, name, type, dry)
21
+ end
22
+
23
+ if mode == 'align'
24
+ 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)
15
26
  end
16
27
  end
17
28
 
@@ -0,0 +1,93 @@
1
+ require 'yaml'
2
+ require 'byebug'
3
+ class CanvasDotfile
4
+
5
+ def self.update_or_create(filepath, response, course, type)
6
+ if File.file?(".canvas")
7
+ if type == "assignment"
8
+ canvas_data = self.update_assignment_data(response, course, type)
9
+ else
10
+ canvas_data = self.update_page_data(response, course, type)
11
+ end
12
+ else
13
+ if type == "assignment"
14
+ canvas_data = self.create_assignment_data(response, course, type)
15
+ else
16
+ canvas_data = self.create_page_data(response, course, type)
17
+ end
18
+ end
19
+ self.create_canvas_dotfile(filepath, canvas_data)
20
+ end
21
+
22
+ def self.create_canvas_dotfile(filepath, canvas_data)
23
+ File.write("#{filepath}/.canvas", canvas_data.to_yaml)
24
+ end
25
+
26
+ def self.commit_canvas_dotfile(filepath)
27
+ GithubInterface.git_add(filepath, '.canvas')
28
+ GithubInterface.git_commit(filepath, 'AUTO: add .canvas file after migration')
29
+ end
30
+
31
+ def self.read_canvas_data
32
+ if File.file?(".canvas")
33
+ YAML.load(File.read(".canvas"))
34
+ else
35
+ puts 'ERROR: Align functionalty requires .canvas file to be present'
36
+ abort
37
+ end
38
+ end
39
+
40
+ def self.update_assignment_data(response, course, type)
41
+ canvas_data = YAML.load(File.read(".canvas"))
42
+ if canvas_data[:lessons].none? { |lesson| lesson[:id] == response['id'] && lesson[:course_id] == course.to_i && lesson[:canvas_url] == response['html_url']}
43
+ lesson_data = {
44
+ id: response['id'],
45
+ course_id: course.to_i,
46
+ canvas_url: response['html_url'],
47
+ type: type
48
+ }
49
+ canvas_data[:lessons] << lesson_data
50
+ end
51
+ canvas_data
52
+ end
53
+
54
+ def self.create_assignment_data(response, course, type)
55
+ {
56
+ lessons: [
57
+ {
58
+ id: response['id'],
59
+ course_id: course.to_i,
60
+ canvas_url: response['html_url'],
61
+ type: type
62
+ }
63
+ ]
64
+ }
65
+ end
66
+
67
+ def self.update_page_data(response, course, type)
68
+ canvas_data = YAML.load(File.read(".canvas"))
69
+ if canvas_data[:lessons].none? { |lesson| lesson[:page_id] == response['page_id'] && lesson[:course_id] == course.to_i && lesson[:canvas_url] == response['html_url']}
70
+ lesson_data = {
71
+ id: response['page_id'],
72
+ course_id: course.to_i,
73
+ canvas_url: response['html_url'],
74
+ type: type
75
+ }
76
+ canvas_data[:lessons] << lesson_data
77
+ end
78
+ canvas_data
79
+ end
80
+
81
+ def self.create_page_data(response, course, type)
82
+ {
83
+ lessons: [
84
+ {
85
+ id: response['page_id'],
86
+ course_id: course.to_i,
87
+ canvas_url: response['html_url'],
88
+ type: type
89
+ }
90
+ ]
91
+ }
92
+ end
93
+ end
@@ -0,0 +1,50 @@
1
+ require 'json'
2
+ require 'rest-client'
3
+ require 'byebug'
4
+ class CanvasInterface
5
+
6
+ def self.submit_to_canvas(course_id, type, name, readme, dry_run = false)
7
+ if dry_run
8
+ puts 'DRY RUN: Skipping push to Canvas'
9
+ else
10
+ response = self.push_to_canvas(course_id, type, name, readme)
11
+ if ![200, 201].include? response.code
12
+ puts "Canvas push failed. #{response.code} status code returned "
13
+ abort
14
+ end
15
+ JSON.parse(response.body)
16
+ end
17
+ end
18
+
19
+ def self.push_to_canvas(course_id, type, name, new_readme)
20
+ url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/#{type}s"
21
+ payload = self.build_payload(type, name, new_readme)
22
+
23
+ RestClient.post(url, payload, headers={
24
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
25
+ })
26
+ end
27
+
28
+ def self.update_existing_lesson(course_id, page_id, type, name, new_readme, dry_run)
29
+ url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/#{type}s/#{page_id}"
30
+ payload = self.build_payload(type, name, new_readme)
31
+ RestClient.put(url, payload, headers={
32
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
33
+ })
34
+ end
35
+
36
+ def self.build_payload(type, name, new_readme)
37
+ if type == "assignment"
38
+ payload = {
39
+ 'assignment[name]' => name,
40
+ 'assignment[description]' => new_readme
41
+ }
42
+ else
43
+ payload = {
44
+ 'wiki_page[title]' => name,
45
+ 'wiki_page[body]' => new_readme,
46
+ 'wiki_page[editing_roles]' => "teachers"
47
+ }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ class CreateCanvasLesson
2
+
3
+ def initialize(course, filepath, branch, name, type, dry_run)
4
+ name = name.split(/[- _]/).map(&:capitalize).join(' ')
5
+ original_readme = File.read("#{filepath}/README.md")
6
+ if !original_readme
7
+ puts 'README.md not found in current directory. Exiting...'
8
+ abort
9
+ end
10
+ create_canvas_lesson(original_readme, course, filepath, branch, name, type, dry_run)
11
+ end
12
+
13
+ def create_canvas_lesson(readme, course, filepath, branch, name, type, dry_run)
14
+ GithubInterface.get_updated_repo(filepath, branch)
15
+ new_readme = RepositoryConverter.convert(filepath, readme, branch)
16
+ response = CanvasInterface.submit_to_canvas(course, type, name, new_readme, dry_run)
17
+ if dry_run
18
+ puts 'DRY RUN: Skipping dotfile creation and push to GitHub'
19
+ else
20
+ CanvasDotfile.update_or_create(filepath, response, course, type)
21
+ CanvasDotfile.commit_canvas_dotfile(filepath)
22
+ GithubInterface.git_push(filepath, branch)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,42 @@
1
+
2
+ class GithubInterface
3
+
4
+ def self.get_updated_repo(filepath, branch)
5
+ self.git_co_branch(filepath, branch)
6
+ self.git_pull(filepath, branch)
7
+ end
8
+
9
+ def self.cd_into_and(filepath, command)
10
+ cmd = "cd #{filepath} && #{command}"
11
+ puts cmd
12
+ `#{cmd}`
13
+ end
14
+
15
+ def self.git_co_branch(filepath, branch)
16
+ branch = self.cd_into_and(filepath, "git co #{branch}")
17
+ if branch.to_s.strip.empty?
18
+ puts "#{branch} branch not found. Exiting..."
19
+ abort
20
+ end
21
+ end
22
+
23
+ def self.git_pull(filepath, branch)
24
+ self.cd_into_and(filepath, "git pull origin #{branch}")
25
+ end
26
+
27
+ def self.git_remote(filepath)
28
+ self.cd_into_and(filepath, "git config --get remote.origin.url")
29
+ end
30
+
31
+ def self.git_add(filepath, file)
32
+ self.cd_into_and(filepath, "git add #{file}")
33
+ end
34
+
35
+ def self.git_commit(filepath, message)
36
+ self.cd_into_and(filepath, "git commit -m '#{message}'")
37
+ end
38
+
39
+ def self.git_push(filepath, branch)
40
+ self.cd_into_and(filepath, "git push origin #{branch}")
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ require 'redcarpet'
2
+
3
+ class RepositoryConverter
4
+
5
+ def self.convert(filepath, readme, branch)
6
+ self.fix_local_images(filepath, readme, branch)
7
+ self.convert_to_html(filepath, readme)
8
+ end
9
+
10
+ def self.fix_local_images(filepath, readme, branch)
11
+ raw_remote_url = self.set_raw_image_remote_url(filepath)
12
+ self.adjust_local_markdown_images(readme, raw_remote_url, branch)
13
+ self.adjust_local_html_images(readme, raw_remote_url)
14
+ end
15
+
16
+ def self.set_raw_image_remote_url(filepath)
17
+ remote = GithubInterface.git_remote(filepath)
18
+ remote.gsub!("git@github.com:","https://raw.githubusercontent.com/")
19
+ remote.gsub!(/.git$/,"")
20
+ remote.strip!
21
+ end
22
+
23
+ def self.adjust_local_markdown_images(readme, raw_remote_url, branch)
24
+ readme.gsub!(/\!\[.+\]\(.+\)/) {|image|
25
+ if !image.match('amazonaws.com') && !image.match('https://') && !image.match('youtube')
26
+ image.gsub!(/\(.+\)/) { |path|
27
+ path.delete_prefix!("(")
28
+ path.delete_suffix!(")")
29
+ "(" + remote + "/#{branch}/" + path + ")"
30
+ }
31
+ end
32
+ image
33
+ }
34
+ end
35
+
36
+ def self.adjust_local_html_images(readme, raw_remote_url)
37
+ readme.gsub!(/src=\"[\s\S]*?" /) { |img|
38
+ if !image.match('amazonaws.com') && !image.match('https://') && !image.match('youtube')
39
+ img.gsub!(/\"/, "")
40
+ img.gsub!(/src=/, '')
41
+ img.strip!
42
+ end
43
+ 'src="' + raw_remote_url + '/master/' + img + '"'
44
+ }
45
+ end
46
+
47
+ def self.convert_to_html(filepath, readme)
48
+ redcarpet = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options={tables: true, autolink: true, fenced_code_blocks: true})
49
+ # File.write("#{filepath}/README.html", redcarpet.render(readme))
50
+ redcarpet.render(readme)
51
+ end
52
+
53
+ end
@@ -0,0 +1,24 @@
1
+ class UpdateCanvasLesson
2
+
3
+ def initialize(filepath, branch, name, type, dry_run)
4
+ name = name.split(/[- _]/).map(&:capitalize).join(' ')
5
+ readme = File.read("#{filepath}/README.md")
6
+ if !readme
7
+ puts 'README.md not found in current directory. Exiting...'
8
+ abort
9
+ end
10
+ update_canvas_lesson(readme, filepath, branch, name, type, dry_run)
11
+ end
12
+
13
+ def update_canvas_lesson(readme, filepath, branch, name, type, dry_run)
14
+ GithubInterface.get_updated_repo(filepath, branch)
15
+ new_readme = RepositoryConverter.convert(filepath, readme, branch)
16
+ canvas_data = CanvasDotfile.read_canvas_data
17
+ canvas_data[:lessons].each { |lesson|
18
+ CanvasInterface.update_existing_lesson(lesson[:course_id], lesson[:id], type, name, new_readme, dry_run)
19
+ }
20
+ end
21
+
22
+
23
+
24
+ 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.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - maxwellbenton
@@ -80,7 +80,12 @@ files:
80
80
  - Rakefile
81
81
  - bin/github-to-canvas
82
82
  - lib/github-to-canvas.rb
83
- - lib/github-to-canvas/create-canvas-lesson.rb
83
+ - lib/github-to-canvas/canvas_dotfile.rb
84
+ - lib/github-to-canvas/canvas_interface.rb
85
+ - lib/github-to-canvas/create_canvas_lesson.rb
86
+ - lib/github-to-canvas/github_interface.rb
87
+ - lib/github-to-canvas/repository_converter.rb
88
+ - lib/github-to-canvas/update_canvas_lesson.rb
84
89
  - lib/github-to-canvas/version.rb
85
90
  homepage: https://github.com/learn-co-curriculum/github-to-canvas
86
91
  licenses:
@@ -1,156 +0,0 @@
1
- require 'redcarpet'
2
- require 'rest-client'
3
- require 'json'
4
- require 'yaml'
5
- require 'byebug'
6
-
7
- class CreateCanvasLesson
8
-
9
- def initialize(course, filepath, branch, name, type)
10
- @course = course
11
- @filepath = filepath
12
- @branch = branch
13
- @name = name.split(/[ -]/).map(&:capitalize).join(' ')
14
- @type = type
15
- @renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options={tables: true, autolink: true, fenced_code_blocks: true})
16
- @original_readme = File.read("#{filepath}/README.md")
17
- if !@original_readme
18
- puts 'README.md not found in current directory. Exiting...'
19
- abort
20
- end
21
- create_canvas_lesson
22
- end
23
-
24
- def create_canvas_lesson
25
- git_co_branch
26
- git_pull
27
- @raw_remote_url = set_raw_image_remote_url
28
- adjust_local_markdown_images
29
- adjust_local_html_images
30
- @new_readme = @renderer.render(@original_readme)
31
- write_to_html
32
- @response = push_to_canvas
33
- if @response.code != 200
34
- puts "Canvas push failed. #{@response.code} status code returned "
35
- end
36
- @response = JSON.parse(@response.body)
37
- create_canvas_dotfile
38
- commit_canvas_dotfile
39
- git_push
40
- end
41
-
42
- def cd_into_and(command)
43
- cmd = "cd #{@filepath} && #{command}"
44
- puts cmd
45
- `#{cmd}`
46
- end
47
-
48
- def git_co_branch
49
- cmd = "git co #{@branch}"
50
- branch = cd_into_and(cmd)
51
- if branch.to_s.strip.empty?
52
- puts "#{b@ranch} branch not found. Exiting..."
53
- abort
54
- end
55
- end
56
-
57
- def git_pull
58
- if @branch != 'master'
59
- cmd = "git pull #{@branch}"
60
- else
61
- cmd = "git pull"
62
- end
63
- puts "git pulling latest version of #{@branch}"
64
- cd_into_and(cmd)
65
- end
66
-
67
- def git_remote
68
- cmd = "git config --get remote.origin.url"
69
- cd_into_and(cmd)
70
- end
71
-
72
- def git_add(file)
73
- cmd = "git add #{file}"
74
- puts "git adding #{file}"
75
- cd_into_and(cmd)
76
- end
77
-
78
- def git_commit(message)
79
- cmd = "git commit -m '#{message}'"
80
- puts "git commit: '#{message}'"
81
- cd_into_and(cmd)
82
- end
83
-
84
- def git_push
85
- cmd = "git push"
86
- puts "git pushing #{@branch}"
87
- cd_into_and(cmd)
88
- end
89
-
90
- def set_raw_image_remote_url
91
- remote = git_remote
92
- remote.gsub!("git@github.com:","https://raw.githubusercontent.com/")
93
- remote.gsub!(/.git$/,"")
94
- remote.strip!
95
- end
96
-
97
- def adjust_local_markdown_images
98
- @original_readme.gsub!(/\!\[.+\]\(.+\)/) {|image|
99
- if !image.match('amazonaws.com') && !image.match('https://')
100
- image.gsub!(/\(.+\)/) { |path|
101
- path.delete_prefix!("(")
102
- path.delete_suffix!(")")
103
- "(" + remote + "/#{@branch}/" + path + ")"
104
- }
105
- end
106
- image
107
- }
108
- end
109
-
110
- def adjust_local_html_images
111
- @original_readme.gsub!(/src=\"[\s\S]*?" /) { |img|
112
- img.gsub!(/\"/, "")
113
- img.gsub!(/src=/, '')
114
- img.strip!
115
- 'src="' + @raw_remote_url + '/master/' + img + '"'
116
- }
117
- end
118
-
119
- def write_to_html
120
- File.write("#{@filepath}/README.html", @new_readme)
121
- end
122
-
123
- def push_to_canvas
124
- url = "#{ENV['CANVAS_API_PATH']}/courses/#{@course}/#{@type}s"
125
- if @type == "assignment"
126
- payload = {
127
- 'assignment[name]' => @name,
128
- 'assignment[description]' => @new_readme
129
- }
130
- else
131
- payload = {
132
- 'wiki_page[title]' => @name,
133
- 'wiki_page[body]' => @new_readme,
134
- 'wiki_page[editing_roles]' => "teachers"
135
- }
136
- end
137
-
138
- RestClient.post(url, payload, headers={
139
- "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
140
- })
141
- end
142
-
143
- def create_canvas_dotfile
144
- canvas_data = {
145
- page_id: @response['page_id'],
146
- course_id: @course.to_i,
147
- canvas_url: @response['html_url']
148
- }
149
- File.write("#{@filepath}/.canvas", canvas_data.to_yaml)
150
- end
151
-
152
- def commit_canvas_dotfile
153
- git_add('.canvas')
154
- git_commit('AUTO: add .canvas file after migration')
155
- end
156
- end