github-to-canvas 0.1.3 → 0.1.9

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: d3d7cf49277d1fb40bb6a956a16865fded3e5a722b115313ab598c8b0ac16338
4
- data.tar.gz: '01129c91256e4391343d2dd4bafc0c87acf57d7f8e0a4f3b040289ab045b6dea'
3
+ metadata.gz: 71e183a1ea3659fdc71af9af4c1ce0370be119f4241e8773ac82fdee9400cf48
4
+ data.tar.gz: ce08e0ec8f3f64471a4966a955e454d8a25cd95e9b9555dd61ca550ec77fe41b
5
5
  SHA512:
6
- metadata.gz: ead1b6073842a1d3c65214ffc3e3cd8bd20048df97a878d8f12dd522655090e02b98f9fb2d45be70a16a044d05aea682bf5c6c71cd31ccd8a6ab9fb215591948
7
- data.tar.gz: cb340a9d7f4910116ede731ad44cb44a02f90bf77dae5e632669d2b54879af2eab38a8ff1ebf4e1fd639ee1c68ac22fdd5ded4d3ae5f57cd283696b4e32b0834
6
+ metadata.gz: 2b04300b61b6301f32512ca328f27affaa186082e0e35d8eeab7c748b77ba3c10a07a7309ba1d3e92563007910da3c9e70a7a1db37ce184b48763cc8d455ffb7
7
+ data.tar.gz: 2cbe19f6cd61338619072f9f07e215762ce45ffbd3b3aa0672d3f77a1c3bd3a8e7837b5e237bf6b01bd4058ac05afaf5c547b82c1b829a8787b344c88fc21276
data/bin/github-to-canvas CHANGED
@@ -1,5 +1,6 @@
1
- require 'byebug'
2
1
  #!/usr/bin/env ruby
2
+
3
+
3
4
  require 'optparse'
4
5
  require 'github-to-canvas'
5
6
 
@@ -76,7 +77,6 @@ OptionParser.new do |opts|
76
77
  end
77
78
  opts.on("-tTYPE", "--type TYPE",
78
79
  "Sets the type Canvas lesson to be created (page or assignment). If no type, type decided based on repository structure") do |type|
79
- # byebug
80
80
  options[:type] = type.downcase
81
81
  abort if type == 'quiz' || type == 'discussion'
82
82
  # if type == 'page' || type == 'assignment' || type == 'discussion' || type == 'quiz' || type == 'Page' || type == 'Assignment' || type == 'Discussion' || type == 'Quiz'
@@ -106,10 +106,18 @@ OptionParser.new do |opts|
106
106
  "Adds additional Flatiron School HTML after markdown conversion") do |f|
107
107
  options[:fis] = true
108
108
  end
109
+ opts.on("-g", "--git-links",
110
+ "Adds additional GitHub after markdown conversion") do |f|
111
+ options[:git_links] = true
112
+ end
109
113
  opts.on("--aaq",
110
114
  "Adds AAQ flag to HTML header appended with --fis-links") do |aaq|
111
115
  options[:aaq] = aaq
112
116
  end
117
+ opts.on("--prework",
118
+ "Adds prework flag to HTML header appended with --fis-links") do |prework|
119
+ options[:prework] = prework
120
+ end
113
121
  opts.on("--forkable",
114
122
  "Used with --fis-links, adds fork button to HTML header injected into Canvas lesson") do |remote|
115
123
  options[:forkable] = true
@@ -138,10 +146,14 @@ OptionParser.new do |opts|
138
146
  "REQUIRES -f or --file Associates canvas lessons with repositories. Use query to create required YAML file") do |file|
139
147
  options[:map] = file
140
148
  end
141
- opts.on("--csv COURSE",
142
- "Returns a course's lesson struction as CSV") do |course|
143
- options[:csv] = course
149
+ opts.on("--urls-only",
150
+ "Use with --map. Outputs repo URLs instead of YAML") do |urls|
151
+ options[:urls_only] = urls
144
152
  end
153
+ opts.on("--csv",
154
+ "Returns a course's lesson struction as CSV") do |csv|
155
+ options[:csv] = csv
156
+ end
145
157
  opts.on("--read-from-canvas CANVAS_URL",
146
158
  "Retrieves an existing Canvas lesson using the provided URL") do |url|
147
159
  options[:read_from_canvas] = url
@@ -182,6 +194,19 @@ OptionParser.new do |opts|
182
194
  "Escapes all HTML included in source markdown by replacing '<' and '>' with HTML charset values") do |html|
183
195
  options[:contains_html] = html
184
196
  end
197
+ opts.on("--canvas-to-canvas COURSE",
198
+ "Copies an existing Canvas lesson into another Canvas lesson") do |canvas_to_canvas|
199
+ options[:canvas_to_canvas] = canvas_to_canvas
200
+ end
201
+ opts.on("--build-from-csv CSV",
202
+ "Build a course using a CSV of lesson repos, names, modules, and types") do |csv_build|
203
+ options[:csv_build] = csv_build
204
+ end
205
+ opts.on("--update-from-csv CSV",
206
+ "Update a course using a CSV of lesson repos, names, modules, types, lesson IDs, and course IDs") do |csv_align|
207
+ options[:csv_align] = csv_align
208
+ end
209
+
185
210
 
186
211
  end.parse!
187
212
 
@@ -196,6 +221,16 @@ if options[:read_from_canvas]
196
221
  abort
197
222
  end
198
223
 
224
+ if options[:canvas_to_canvas]
225
+ GithubToCanvas.new(mode: 'canvas_copy',
226
+ filepath: options[:canvas_to_canvas],
227
+ course_id: options[:course_id],
228
+ type: options[:type],
229
+ id: options[:id]
230
+ )
231
+ abort
232
+ end
233
+
199
234
  if options[:read_from_github]
200
235
  GithubToCanvas.new(mode: 'github_read',
201
236
  filepath: options[:read_from_github],
@@ -203,6 +238,7 @@ if options[:read_from_github]
203
238
  forkable: !!options[:forkable],
204
239
  fis_links: !!options[:fis],
205
240
  aaq: !!options[:aaq],
241
+ prework: !!options[:prework],
206
242
  contains_html: options[:contains_html])
207
243
  abort
208
244
  end
@@ -218,6 +254,7 @@ if options[:create_from_github]
218
254
  forkable: !!options[:forkable],
219
255
  fis_links: !!options[:fis],
220
256
  aaq: !!options[:aaq],
257
+ prework: !!options[:prework],
221
258
  contains_html: options[:contains_html])
222
259
  else
223
260
  puts 'Canvas course ID and lesson type required. Example: github-to-canvas --create-from-github URL --course ID --type TYPE'
@@ -237,6 +274,7 @@ if options[:align_from_github]
237
274
  forkable: !!options[:forkable],
238
275
  fis_links: !!options[:fis],
239
276
  aaq: !!options[:aaq],
277
+ prework: !!options[:prework],
240
278
  contains_html: options[:contains_html])
241
279
  else
242
280
  puts 'Canvas course ID, lesson ID, and type required. Example: github-to-canvas --create-from-github URL --course COURSE_ID --id LESSON_ID --type TYPE'
@@ -250,12 +288,43 @@ if options[:query]
250
288
  end
251
289
 
252
290
  if options[:map]
253
- GithubToCanvas.new(mode: 'map', file_to_convert: options[:map])
291
+ GithubToCanvas.new(mode: 'map',
292
+ file_to_convert: options[:map],
293
+ urls_only: !!options[:urls_only],
294
+ csv: !!options[:csv])
295
+ abort
296
+ end
297
+
298
+ # if options[:csv]
299
+ # GithubToCanvas.new(mode: 'csv', file_to_convert: options[:csv])
300
+ # abort
301
+ # end
302
+
303
+ if options[:csv_build]
304
+ GithubToCanvas.new(mode: 'csv_build',
305
+ file_to_convert: options[:csv_build],
306
+ course_id: options[:course_id],
307
+ fis_links: !!options[:fis],
308
+ remove_header_and_footer: !!options[:remove_header_and_footer],
309
+ aaq: !!options[:aaq],
310
+ forkable: !!options[:forkable],
311
+ branch: options[:branch],
312
+ contains_html: options[:contains_html],
313
+ git_links: !!options[:git_links])
254
314
  abort
255
315
  end
256
316
 
257
- if options[:csv]
258
- GithubToCanvas.new(mode: 'csv', file_to_convert: options[:csv])
317
+ if options[:csv_align]
318
+ GithubToCanvas.new(mode: 'csv_align',
319
+ file_to_convert: options[:csv_align],
320
+ course_id: options[:course_id],
321
+ fis_links: !!options[:fis],
322
+ remove_header_and_footer: !!options[:remove_header_and_footer],
323
+ aaq: !!options[:aaq],
324
+ forkable: !!options[:forkable],
325
+ branch: options[:branch],
326
+ contains_html: options[:contains_html],
327
+ git_links: !!options[:git_links])
259
328
  abort
260
329
  end
261
330
 
@@ -265,7 +334,10 @@ if options[:build_course]
265
334
  fis_links: !!options[:fis],
266
335
  remove_header_and_footer: !!options[:remove_header_and_footer],
267
336
  aaq: !!options[:aaq],
268
- forkable: !!options[:forkable])
337
+ prework: !!options[:prework],
338
+ forkable: !!options[:forkable],
339
+ contains_html: options[:contains_html],
340
+ git_links: !!options[:git_links])
269
341
  abort
270
342
  end
271
343
 
@@ -278,7 +350,9 @@ if options[:add_to_course]
278
350
  remove_header_and_footer: !!options[:remove_header_and_footer],
279
351
  forkable: !!options[:forkable],
280
352
  aaq: !!options[:aaq],
281
- contains_html: options[:contains_html])
353
+ prework: !!options[:prework],
354
+ contains_html: options[:contains_html],
355
+ git_links: !!options[:git_links])
282
356
  else
283
357
  puts '--course required'
284
358
  end
@@ -292,7 +366,9 @@ if options[:update_course_lessons]
292
366
  remove_header_and_footer: !!options[:remove_header_and_footer],
293
367
  forkable: !!options[:forkable],
294
368
  aaq: !!options[:aaq],
295
- contains_html: options[:contains_html])
369
+ prework: !!options[:prework],
370
+ contains_html: options[:contains_html],
371
+ git_links: !!options[:git_links])
296
372
  abort
297
373
  end
298
374
 
@@ -352,10 +428,12 @@ if options[:create_lesson]
352
428
  type: options[:type],
353
429
  save_to_github: !!options[:save_to_github],
354
430
  fis_links: !!options[:fis],
431
+ git_links: !!options[:git_links],
355
432
  remove_header_and_footer: !!options[:remove_header_and_footer],
356
433
  only_update_content: !!options[:only_content],
357
434
  forkable: !!options[:forkable],
358
435
  aaq: !!options[:aaq],
436
+ prework: !!options[:prework],
359
437
  contains_html: options[:contains_html])
360
438
  end
361
439
 
@@ -369,10 +447,12 @@ if options[:align]
369
447
  name: options[:name],
370
448
  type: options[:type],
371
449
  save_to_github: !!options[:save_to_github],
372
- fis_links: !!options[:fis],
450
+ fis_links: !!options[:fis],
451
+ git_links: !!options[:git_links],
373
452
  remove_header_and_footer: !!options[:remove_header_and_footer],
374
453
  only_update_content: !!options[:only_content],
375
454
  forkable: !!options[:forkable],
376
455
  aaq: !!options[:aaq],
456
+ prework: !!options[:prework],
377
457
  contains_html: options[:contains_html])
378
458
  end
@@ -1,4 +1,4 @@
1
- require 'byebug'
1
+ require 'csv'
2
2
  require_relative './github-to-canvas/create_canvas_lesson'
3
3
  require_relative './github-to-canvas/update_canvas_lesson'
4
4
  require_relative './github-to-canvas/canvas_dotfile'
@@ -21,11 +21,13 @@ class GithubToCanvas
21
21
  when 'query'
22
22
  CanvasInterface.get_course_info(options[:course_id], options[:id])
23
23
  when 'map'
24
- CanvasInterface.map_course_info(options[:file_to_convert])
24
+ CanvasInterface.map_course_info(options)
25
25
  when 'csv'
26
26
  CanvasInterface.csv(options[:file_to_convert])
27
27
  when 'canvas_read'
28
28
  puts CanvasInterface.read_lesson(options[:filepath])
29
+ when 'canvas_copy'
30
+ CanvasInterface.copy_lesson(options)
29
31
  when 'github_read'
30
32
  html = RepositoryConverter.remote_file_conversion(options)
31
33
  puts RepositoryConverter.adjust_converted_html(options, html)
@@ -43,16 +45,24 @@ class GithubToCanvas
43
45
  CanvasInterface.update_all_related_lessons(options, name, html)
44
46
 
45
47
  when 'github_create'
48
+ if (!options[:branch])
49
+ options[:branch] = 'master'
50
+ end
46
51
  html = RepositoryConverter.remote_file_conversion(options)
47
- name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
48
- html = RepositoryConverter.adjust_converted_html(options, html)
49
52
 
53
+ html = RepositoryConverter.adjust_converted_html(options, html)
54
+ name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
55
+ puts name
50
56
  response = CanvasInterface.create_lesson(options, name, html)
51
57
 
52
58
  puts "Canvas lesson created. Lesson available at #{response['html_url']}"
53
59
  when 'github_align'
60
+ if (!options[:branch])
61
+ options[:branch] = 'master'
62
+ end
54
63
  html = RepositoryConverter.remote_file_conversion(options)
55
64
  name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
65
+
56
66
  html = RepositoryConverter.adjust_converted_html(options, html)
57
67
  response = CanvasInterface.update_existing_lesson(options, name, html)
58
68
  puts "Canvas lesson updated. Lesson available at #{response['html_url']}"
@@ -152,6 +162,101 @@ class GithubToCanvas
152
162
  end
153
163
  }
154
164
  }
165
+ when 'csv_build'
166
+ if !options[:course_id]
167
+ course_info = {
168
+ name: "CSV Build Test",
169
+ course_code: "CSV-TEST"
170
+ }
171
+ created_course_info = CanvasInterface.create_course(course_info)
172
+ puts "Course created - #{created_course_info["id"]}"
173
+ puts "Make sure to add yourself as a teacher to this course before continuing, then press Enter/Return"
174
+ input = gets
175
+ options[:course_id] = created_course_info["id"]
176
+ else
177
+ puts "Adding to course #{options[:course_id]}"
178
+ end
179
+
180
+ csv_data = CSV.read(options[:file_to_convert])
181
+ created_module_info = {
182
+ "id" => "",
183
+ "name" => ""
184
+ }
185
+
186
+ csv_data.each { |lesson|
187
+ # lesson[0] == repo
188
+ # lesson[1] == name
189
+ # lesson[2] == module
190
+ # lesson[3] == type
191
+ # lesson[4] == yes/no contains HTML
192
+ module_info = {
193
+ name: lesson[2]
194
+ }
195
+ if created_module_info["name"] != module_info[:name]
196
+ created_module_info = CanvasInterface.create_module(options[:course_id], module_info)
197
+ puts "New module created - #{created_module_info["id"]} - #{created_module_info["name"]}"
198
+ end
199
+
200
+ options[:filepath] = lesson[0]
201
+ options[:name] = lesson[1]
202
+ options[:type] = lesson[3]
203
+ options[:branch] = "master" if !options[:branch]
204
+ if !options[:contains_html]
205
+ options[:contains_html] = (lesson[4] == "yes" || lesson[4] == "Yes") ? true : false
206
+ end
207
+
208
+
209
+ html = RepositoryConverter.remote_file_conversion(options)
210
+ html = RepositoryConverter.adjust_converted_html(options, html)
211
+ created_lesson_info = CanvasInterface.create_lesson(options, lesson[1], html)
212
+ created_lesson_info["page_url"] = created_lesson_info["url"] if !created_lesson_info["page_url"]
213
+ created_lesson_info["id"] = created_lesson_info["page_url"] if !created_lesson_info["id"]
214
+ created_lesson_info["type"] = options[:type]
215
+ puts "Creating lesson - #{options[:name]}"
216
+ response = CanvasInterface.add_to_module(options[:course_id], created_module_info, created_lesson_info)
217
+
218
+ }
219
+ when 'csv_align'
220
+
221
+ csv_data = CSV.read(options[:file_to_convert])
222
+ created_module_info = {
223
+ "id" => "",
224
+ "name" => ""
225
+ }
226
+
227
+ csv_data.each { |lesson|
228
+ # lesson[0] == repo
229
+ # lesson[1] == name
230
+ # lesson[2] == module
231
+ # lesson[3] == type
232
+ # lesson[4] == yes/no contains HTML
233
+ # lesson[5] == lesson id
234
+ # lesson[6] == course id
235
+
236
+ module_info = {
237
+ name: lesson[2]
238
+ }
239
+
240
+ options[:filepath] = lesson[0]
241
+ options[:name] = lesson[1]
242
+ options[:type] = lesson[3]
243
+ options[:id] = lesson[5]
244
+ options[:course_id] = lesson[6]
245
+ options[:branch] = "master" if !options[:branch]
246
+ if !options[:contains_html]
247
+ options[:contains_html] = (lesson[4] == "yes" || lesson[4] == "Yes") ? true : false
248
+ end
249
+
250
+
251
+ html = RepositoryConverter.remote_file_conversion(options)
252
+ html = RepositoryConverter.adjust_converted_html(options, html)
253
+ updated_lesson_info = CanvasInterface.update_existing_lesson(options, lesson[1], html)
254
+ updated_lesson_info["page_url"] = updated_lesson_info["url"] if !updated_lesson_info["page_url"]
255
+ updated_lesson_info["id"] = updated_lesson_info["page_url"] if !updated_lesson_info["id"]
256
+ updated_lesson_info["type"] = options[:type]
257
+ puts "Updating lesson - #{options[:name]}"
258
+
259
+ }
155
260
  else
156
261
  puts VERSION
157
262
  end
@@ -1,7 +1,7 @@
1
- require 'byebug'
2
1
  require 'json'
3
2
  require 'rest-client'
4
3
  require 'yaml'
4
+ require 'byebug'
5
5
  class CanvasInterface
6
6
 
7
7
  def self.create_course(course_info)
@@ -51,21 +51,21 @@ class CanvasInterface
51
51
  # POST /api/v1/courses/:course_id/modules/:module_id/items
52
52
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/modules/#{module_info["id"]}/items"
53
53
 
54
- if lesson_info["type"] == "Page"
54
+ if lesson_info["type"] == "Page" || lesson_info["type"] == "page"
55
55
  payload = {
56
- 'module_item[title]' => lesson_info["title"],
57
- 'module_item[type]' => lesson_info["type"],
58
- 'module_item[indent]' => 0,
59
- 'module_item[page_url]' => lesson_info["id"],
60
- 'module_item[completion_requirement][type]' => 'must_view'
61
- }
56
+ 'module_item[title]' => lesson_info["title"],
57
+ 'module_item[type]' => lesson_info["type"].capitalize,
58
+ 'module_item[indent]' => 0,
59
+ 'module_item[page_url]' => lesson_info["id"],
60
+ 'module_item[completion_requirement][type]' => 'must_view'
61
+ }
62
62
  elsif lesson_info["type"] == "Quiz"
63
63
  puts "Quiz needs to be added manually - #{lesson_info['title']} - lesson_info["
64
64
  else
65
65
 
66
66
  payload = {
67
67
  'module_item[title]' => lesson_info["title"],
68
- 'module_item[type]' => lesson_info["type"],
68
+ 'module_item[type]' => lesson_info["type"].capitalize,
69
69
  'module_item[indent]' => 1,
70
70
  'module_item[content_id]' => lesson_info["id"],
71
71
  'module_item[completion_requirement][type]' => 'must_submit'
@@ -95,14 +95,15 @@ class CanvasInterface
95
95
  if options[:type] == 'page' || options[:type] == 'Page'
96
96
  response = RestClient.get(url, headers)
97
97
  lesson_info = JSON.parse(response)
98
+ lesson_info = lesson_info[0] if lesson_info.kind_of?(Array)
98
99
  url = url.sub(/[^\/]+$/, lesson_info["page_id"].to_s)
99
100
  end
101
+
100
102
  response = RestClient.put(url, payload, headers)
101
103
  rescue
102
104
  puts "Something went wrong while pushing lesson #{options[:id]} to course #{options[:course_id]}"
103
105
  puts "Make sure you are working on lessons that are not locked"
104
106
  abort
105
- ""
106
107
  end
107
108
  JSON.parse(response.body)
108
109
  end
@@ -193,6 +194,7 @@ class CanvasInterface
193
194
  while !!index
194
195
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/modules?page=#{index}&per_page=20"
195
196
  index += 1
197
+
196
198
  response = RestClient.get(url, self.headers)
197
199
  modules = JSON.parse(response.body)
198
200
 
@@ -200,7 +202,7 @@ class CanvasInterface
200
202
  course_info[:modules] = course_info[:modules] + modules
201
203
  else
202
204
  index = nil
203
- end
205
+ end
204
206
  end
205
207
 
206
208
  course_info[:modules] = course_info[:modules].map do |mod|
@@ -213,11 +215,12 @@ class CanvasInterface
213
215
  while !!index
214
216
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/modules/#{mod['id']}/items?page=#{index}&per_page=20"
215
217
  index += 1
216
- response = RestClient.get(url, headers={
217
- "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
218
- })
218
+ response = RestClient.get(url, self.headers)
219
219
  lessons = JSON.parse(response.body)
220
220
  lessons = lessons.map do |lesson|
221
+ if lesson["type"] == "ExternalUrl"
222
+ next
223
+ end
221
224
  lesson = lesson.slice("id","title","name","indent","type","html_url","page_url","url","completion_requirement", "published")
222
225
  lesson["repository"] = ""
223
226
  lesson['id'] = lesson['url'].gsub(/^(.*[\\\/])/,'')
@@ -232,7 +235,7 @@ class CanvasInterface
232
235
  end
233
236
  new_mod
234
237
  end
235
-
238
+
236
239
  puts course_info.to_yaml
237
240
 
238
241
  rescue
@@ -241,8 +244,8 @@ class CanvasInterface
241
244
  end
242
245
  end
243
246
 
244
- def self.map_course_info(file_to_convert)
245
- course_info = YAML.load(File.read("#{Dir.pwd}/#{file_to_convert}"))
247
+ def self.map_course_info(options)
248
+ course_info = YAML.load(File.read("#{Dir.pwd}/#{options[:file_to_convert]}"))
246
249
  course_info[:modules] = course_info[:modules].map do |mod|
247
250
  mod[:lessons] = mod[:lessons].map do |lesson|
248
251
 
@@ -279,13 +282,15 @@ class CanvasInterface
279
282
  else
280
283
  lesson["repository"] = "https://github.com/learn-co-curriculum/" + repo
281
284
  end
285
+ puts lesson["repository"] if options[:urls_only]
286
+ puts "#{lesson["repository"]}, #{lesson["title"]}, #{mod[:name]}, #{lesson["type"].downcase}, , #{lesson["id"]}, #{course_info[:id]}" if options[:csv]
282
287
  end
283
288
  sleep(1)
284
289
  lesson
285
290
  end
286
291
  mod
287
292
  end
288
- puts course_info.to_yaml
293
+ puts course_info.to_yaml if !options[:urls_only]
289
294
  end
290
295
 
291
296
  def self.csv(file_to_convert)
@@ -332,12 +337,40 @@ class CanvasInterface
332
337
  end
333
338
  mod
334
339
  end
335
- byebug
336
340
  puts course_info.to_yaml
337
341
  end
338
342
 
339
-
343
+ def self.copy_lesson(options)
344
+ types = ["page", "assignment", "quiz", "discussion"]
345
+ url = options[:filepath]
346
+ type = types.find {|type| url.match(type)}
347
+ options[:type] = type
348
+ if !url.include?(ENV['CANVAS_API_PATH'])
349
+ url = url.sub(/^.*\/\/.*?\//,"#{ENV['CANVAS_API_PATH']}/")
350
+ end
340
351
 
352
+ response = RestClient.get(url, headers={
353
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
354
+ })
355
+
356
+ lesson_info = JSON.parse(response)
357
+ lesson_info = lesson_info.slice("title",
358
+ "name",
359
+ "description",
360
+ "body",
361
+ "message",
362
+ "shuffle_answers",
363
+ "allowed_attempts",
364
+ "question_count"
365
+ )
366
+ if options[:type] == "page"
367
+ self.update_existing_lesson(options, lesson_info["title"], lesson_info["body"])
368
+ else
369
+ self.update_existing_lesson(options, lesson_info["name"], lesson_info["description"])
370
+ end
371
+
372
+
373
+ end
341
374
 
342
375
  def self.build_payload(options, name, html)
343
376
  if options[:only_update_content]
@@ -61,11 +61,11 @@ class GithubInterface
61
61
  rescue
62
62
  begin
63
63
  response = RestClient.get(url_fallback)
64
+ return response.body
64
65
  rescue
65
66
  puts 'Error reading ' + url
66
67
  end
67
68
  end
68
-
69
69
  response.body
70
70
  end
71
71
 
@@ -1,5 +1,5 @@
1
1
  require 'redcarpet'
2
-
2
+ # require 'byebug'
3
3
  class CustomRender < Redcarpet::Render::HTML
4
4
  def block_code(code, lang)
5
5
  "<pre>" \
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  class RepositoryConverter
16
16
  def self.local_file_conversion(options)
17
- GithubInterface.get_updated_repo(options[:filepath], options[:branch])
17
+ # GithubInterface.get_updated_repo(options[:filepath], options[:branch])
18
18
  markdown = RepositoryInterface.read_local_file(options[:filepath], options[:file_to_convert])
19
19
  raw_remote_url = self.set_raw_image_remote_url(options[:filepath])
20
20
  markdown = self.escape_existing_html(markdown) if options[:contains_html]
@@ -26,15 +26,27 @@ class RepositoryConverter
26
26
  def self.remote_file_conversion(options)
27
27
  markdown = GithubInterface.read_remote(options[:filepath])
28
28
  raw_remote_url = self.set_raw_image_remote_url(options[:filepath])
29
- markdown = self.escape_existing_html(markdown) if options[:contains_html]
29
+ if options[:contains_html]
30
+ begin
31
+ markdown = self.escape_existing_html(markdown)
32
+ rescue
33
+ puts "Error reading remote markdown"
34
+ abort
35
+ end
36
+ end
37
+ if (!options[:branch])
38
+ options[:branch] = 'master'
39
+ end
30
40
  markdown = self.fix_local_images(options, markdown, raw_remote_url)
31
41
  html = self.convert_to_html(markdown)
32
42
  # self.fix_local_html_links(options, html, options[:filepath])
33
43
  end
34
44
 
35
45
  def self.convert_to_html(markdown)
36
- redcarpet = Redcarpet::Markdown.new(CustomRender, options={tables: true, autolink: true, fenced_code_blocks: true})
46
+ renderer = CustomRender.new(escape_html: true, prettify: true, hard_wrap: true)
47
+ redcarpet = Redcarpet::Markdown.new(CustomRender, options={tables: true, autolink: true, fenced_code_blocks: true, disable_indented_code_blocks: true})
37
48
  html = redcarpet.render(markdown)
49
+ puts "Markdown converted to HTML"
38
50
  self.remove_line_breaks(html)
39
51
  end
40
52
 
@@ -44,25 +56,57 @@ class RepositoryConverter
44
56
  html = self.remove_header_and_footer(html)
45
57
  end
46
58
 
47
- if options[:fis_links]
59
+ if options[:fis_links] || options[:git_links]
48
60
  html = self.add_fis_links(options, html)
49
61
  end
50
62
 
51
- html = self.fix_escaped_inline_html_code(html)
63
+ if options[:contains_html]
64
+ html = self.fix_escaped_inline_html_code(html)
65
+ end
52
66
 
53
67
  html
54
68
  end
55
69
 
56
70
  def self.fix_escaped_inline_html_code(html)
57
- html = html.gsub("<code>&amp;lt;", "<code>&lt;")
58
- html = html.gsub("&amp;gt;</code>", "&gt;</code>")
71
+
72
+ # stops HTML/JSX code blocks from rendering as HTML in Canvas
73
+ # html = html.gsub("&amp;gt;</code>", "&gt;</code>")
74
+ # html = html.gsub("&amp;gt;</code>", "&gt;</code>")
75
+
76
+ # fixes < and > code snippets
77
+
78
+ # html = html.gsub(/<pre><code>(.*?)<\/code><\/pre>/) { |string|
79
+ # byebug
80
+ # }
81
+ # html = html.gsub("&amp;gt;", "&gt;")
82
+
83
+ # # fixes blockquotes
84
+ # html = html.gsub(/\n<p>&gt\;(.*)\n&gt\;/) { |bq|
85
+ # bq.delete_prefix!("\n<p>&gt;")
86
+ # "\n<blockquote>" + bq
87
+ # }
88
+ # html = html.gsub(/\n&gt\;(.*)\n&gt\;/) { |bq|
89
+ # bq.delete_prefix!("\n&gt;")
90
+ # " " + bq
91
+ # }
92
+ # html = html.gsub(/\n&gt\;(.*)<\/p>/) { |bq|
93
+ # bq.delete_prefix!("\n&gt\;")
94
+ # bq.delete_suffix!("</p>")
95
+ # " " + bq + "</blockquote>"
96
+ # }
97
+
98
+ html
59
99
  end
60
100
 
61
101
 
62
102
  def self.escape_existing_html(markdown)
63
- markdown = markdown.gsub(/<\/(?!iframe)/, "&lt;/")
64
- markdown = markdown.gsub(/<(?!iframe)/, "&lt;")
65
- markdown = markdown.gsub(/(?<!iframe)>/, "&gt;")
103
+ # markdown = markdown.gsub(/<\/(?!iframe)/, "&lt;/")
104
+ # markdown = markdown.gsub(/<(?!iframe)/, "&lt;")
105
+ # markdown = markdown.gsub(/(?<!iframe)>/, "&gt;")
106
+ # byebug
107
+ # markdown = markdown.gsub(/```(.*?)```/) {|s|
108
+ # byebug
109
+ # }
66
110
  end
67
111
 
68
112
  def self.remove_header_and_footer(html)
@@ -78,6 +122,9 @@ class RepositoryConverter
78
122
 
79
123
  def self.remove_footer(readme)
80
124
  readme.gsub(/<p class='util--hide'(.+?)<\/p>/,"")
125
+ readme.gsub(/<p data-visibility='hidden'(.+?)<\/p>/,"")
126
+ readme.gsub(/<p>&lt\;p data-visibility=&#39\;hidden&#39(.+?)<\/p>/,"")
127
+ readme.gsub(/<p>&lt\;p class=&#39;util--hide&#39\;(.+?)<\/p>/,"")
81
128
  end
82
129
 
83
130
  def self.remove_html_header(html)
@@ -115,7 +162,7 @@ class RepositoryConverter
115
162
  remote = GithubInterface.git_remote(filepath)
116
163
  end
117
164
  raw_remote = remote.gsub("git@github.com:","https://raw.githubusercontent.com/")
118
- raw_remote = raw_remote.gsub("https://github.com/","https://raw.githubusercontent.com/")
165
+ raw_remote = raw_remo te.gsub("https://github.com/","https://raw.githubusercontent.com/")
119
166
  raw_remote = raw_remote.gsub(/\/blob\/master\/.*$/,"")
120
167
  raw_remote = raw_remote.gsub(/\/blob\/main\/.*$/,"")
121
168
  raw_remote = raw_remote.gsub(/.git$/,"")
@@ -130,7 +177,7 @@ class RepositoryConverter
130
177
  end
131
178
 
132
179
  def self.adjust_local_markdown_images(readme, raw_remote_url, branch)
133
- readme.gsub!(/\!\[.+\]\(.+\)/) {|image_markdown|
180
+ readme.gsub(/\!\[.+\]\(.+\)/) {|image_markdown|
134
181
  if !image_markdown.match?('amazonaws.com') && !image_markdown.match?('https://') && !image_markdown.match?('http://') && !image_markdown.match?('youtube')
135
182
  image_markdown.gsub!(/\(.+\)/) { |path|
136
183
  path.delete_prefix!("(")
@@ -143,12 +190,18 @@ class RepositoryConverter
143
190
  end
144
191
 
145
192
  def self.adjust_local_html_images(readme, raw_remote_url, branch)
146
- readme.gsub!(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
147
- if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube')
148
- image_source.gsub!(/(\'|\")/, "")
149
- image_source.gsub!(/src=/, '')
150
- image_source.strip!
151
- 'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
193
+ readme.gsub(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
194
+
195
+ if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube') && !image_source.match(/src=(\'|\")(?=<%)/)
196
+ image_source = image_source.gsub(/(\'|\")/, "")
197
+ image_source = image_source.gsub(/src=/, '')
198
+ image_source = image_source.strip
199
+
200
+ begin
201
+ 'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
202
+ rescue
203
+ puts "Error adjust HTML images - check images in Canvas"
204
+ end
152
205
  else
153
206
  image_source
154
207
  end
@@ -178,12 +231,12 @@ class RepositoryConverter
178
231
  def self.add_fis_links(options, html)
179
232
  repo_info = self.get_repo_info(options[:filepath])
180
233
  html = html.sub(/<div id="git-data-element.*<header class="fis-header.*<\/header>/,'') # remove existing fis header
181
- header = self.create_github_link_header(repo_info[:repo_path], options[:forkable])
182
- data_element = self.create_data_element(repo_info[:repo_org], repo_info[:repo_name], options[:aaq])
234
+ header = self.create_github_link_header(repo_info[:repo_path], options)
235
+ data_element = self.create_data_element(repo_info[:repo_org], repo_info[:repo_name], options[:aaq], options[:prework])
183
236
  data_element + header + html
184
237
  end
185
238
 
186
- def self.create_github_link_header(repo_path, forkable)
239
+ def self.create_github_link_header(repo_path, options)
187
240
  # add link to associated repository
188
241
  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>"
189
242
 
@@ -191,20 +244,19 @@ class RepositoryConverter
191
244
  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>"
192
245
 
193
246
  # add link to fork (forking handled by separate Flatiron server, generation of link handled via custom Canvas JS theme file)
194
- if (forkable)
195
- 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>"
247
+
248
+ if (options[:forkable])
249
+ github_fork_link = "<a class='fis-fork-link' id='fork-link' href='#{repo_path}/fork' target='_blank' rel='noopener'><img id='fork-img' title='Fork This Assignment' alt='Fork This Assignment' /></a>"
196
250
  "<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_repo_link}#{github_issue_link}</header>"
251
+ elsif options[:git_links]
252
+ "<header class='fis-header'>#{github_repo_link}#{github_issue_link}</header>"
197
253
  else
198
254
  "<header class='fis-header' style='visibility: hidden;'>#{github_repo_link}#{github_issue_link}</header>"
199
255
  end
200
256
  end
201
257
 
202
- def self.create_data_element(repo_org, repo_name, aaq)
203
- if (aaq)
204
- "<div id='git-data-element' data-aaq='enabled' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
205
- else
206
- "<div id='git-data-element' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
207
- end
258
+ def self.create_data_element(repo_org, repo_name, aaq, prework)
259
+ "<div id='git-data-element' #{prework ? "data-prework='true'" : ""} #{aaq ? "data-aaq='enabled'" : ""} data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
208
260
  end
209
261
 
210
262
 
@@ -1,3 +1,3 @@
1
1
  class GithubToCanvas
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.9"
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.1.3
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - maxwellbenton
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  requirements: []
111
- rubygems_version: 3.0.8
111
+ rubygems_version: 3.2.3
112
112
  signing_key:
113
113
  specification_version: 4
114
114
  summary: github-to-canvas is a tool for migrating and aligning GitHub content with