github-to-canvas 0.0.9 → 0.0.11

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 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