github-to-canvas 0.0.42 → 0.0.48

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: 2c38080e6c0827bce0491f53aaada600e08d92ebf0b7a2d61c6d363a460e42ef
4
- data.tar.gz: b1099325700aadcc9bb0e12115ac5a3c67992ce62ab62277a0aaebd638736319
3
+ metadata.gz: d00d3f8b2e4a748b6d8840c365904d980f7bc6f7ad8046cc44b0f28372cad834
4
+ data.tar.gz: 2cf19fe82846d2cb544ba8cccacd078e08c71c7270f4ecfa1a954d894cdf6750
5
5
  SHA512:
6
- metadata.gz: ec29a4070f46afe5a7dd580ab24688d9f19dba943d2f93e4850278516eccd583cf41e9793228b77e488aa8ef491d6015634116648339c6f2f0a6fb8f1cb1b8ec
7
- data.tar.gz: 325b22cf79ef204466723ab79d638ce3c1790bdaf9a8e3485184200b6947d73b4d543fba55e8580591b794216483428faf997d3033a8b2ce128463bd495cd595
6
+ metadata.gz: 74598233da7a1ecfc041937a838a06e14511fbc98c65a981c8a408f997289e0c3520fa600e023bba1c3800ee84c742bb79598ca067e8ba2e0957972df390173c
7
+ data.tar.gz: b81aca6a1ebd575642e438a60af63a24db731728b144de5e6f7e5be2ed8c36f6c5cdc93411aa7e64e6e6e231946d0db359a51497b7417b25c40d9f4c2b36f6fb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # GitHub to Canvas Gem Test
1
+ # GitHub to Canvas Gem
2
2
 
3
3
  ## Introduction
4
4
 
@@ -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 addition Flatiron School specific HTML
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
- options[:name] = options[:file_to_convert]
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.slice(2,markdown.length)
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
@@ -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 File.file?(".canvas")
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
- page_url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/pages/#{id}"
7
- assignment_url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/assignments/#{id}"
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
- page_response = RestClient.get(page_url, headers={
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 ([200, 201].include? assignment_response.code)
27
- info = JSON.parse(assignment_response.body)
28
- puts "A Canvas assignment with the ID #{id} was found in course #{course}:"
29
- type = "assignment"
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
- info = self.get_lesson_info(course, id)
39
- pp info[1]
40
- pp info[0]
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
- # abort
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 'Creating .canvas file'
23
- CanvasDotfile.update_or_create(filepath, response, course, type)
29
+ puts 'Adding .canvas file'
30
+ GithubInterface.git_add(filepath, '.canvas')
24
31
  puts 'Commiting .canvas file'
25
- CanvasDotfile.commit_canvas_dotfile(filepath)
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!(/\!\[.+\]\(.+\)/) {|image|
44
- if !image.match('amazonaws.com') && !image.match('https://') && !image.match('youtube')
45
- image.gsub!(/\(.+\)/) { |path|
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
- image
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=\"[\s\S]*?" /) { |img|
57
- if !img.match('amazonaws.com') && !img.match('https://') && !img.match('youtube')
58
- img.gsub!(/\"/, "")
59
- img.gsub!(/src=/, '')
60
- img.strip!
61
- 'src="' + raw_remote_url + '/master/' + img + '"'
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
- img
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
- repo = self.get_repo_url(filepath)
76
- github_repo_link = "<a class='fis-git-link' href='#{repo}' target='_blank' rel='noopener'><img id='repo-img' title='Open GitHub Repo' alt='GitHub Repo' /></a>"
77
- github_issue_link = "<a class='fis-git-link' href='#{repo}/issues/new' target='_blank' rel='noopener'><img id='issue-img' title='Create New Issue' alt='Create New Issue' /></a>"
78
- thumbs_up_link = "<img id='thumbs-up' data-repository='#{repo.split('/')[-1]}' title='Thumbs up!' alt='thumbs up' />"
79
- thumbs_down_link = "<img id='thumbs-down' data-repository='#{repo.split('/')[-1]}' title='Thumbs down!' alt='thumbs down' />"
80
- feedback_link = "<h5>Have specific feedback? <a href='#{repo}/issues/new'>Tell us here!</a></h5>"
81
- header = "<header class='fis-header' style='visibility: hidden;'>#{github_repo_link}#{github_issue_link}</header>"
82
- footer = "<footer class='fis-footer' style='visibility: hidden;'><div class='fis-feedback'><h5>How do you feel about this lesson?</h5>#{thumbs_up_link}#{thumbs_down_link}</div>#{feedback_link}</footer>"
83
- header + readme + footer
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) # adds Flatiron School specific header and footer
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].each { |lesson|
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 is provided, uses the ID instead of the .canvas file
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
- CanvasInterface.update_existing_lesson(course, id, info[1], name, new_html, only_update_content)
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
@@ -1,3 +1,3 @@
1
1
  class GithubToCanvas
2
- VERSION = "0.0.42"
2
+ VERSION = "0.0.48"
3
3
  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.42
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.0.8
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