github-to-canvas 0.1.1 → 0.1.7.pre

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: a091b1eff741a97c405fa521cdc476c674f0d3dedb915d919045fab6244b5037
4
- data.tar.gz: 5c384485dfcbb6da42dcf8db87115173d72b1ef548d3bfe99cfe6fec3af9ce98
3
+ metadata.gz: 53c9c96308fae1d78f27bc68e80fee55baf2ff23d381866edfd1d114b30601ec
4
+ data.tar.gz: bf7570a5be4657e102659454295beb72023864ceb20562b51858fa094997b5f7
5
5
  SHA512:
6
- metadata.gz: 5ae4d1c9c1ade17a0a15d148267f2e9c5949857c3f76ce0a65c1a0f6ac5e7c382ab29c2ae1ef9c37ace078178a7ae8a342e3f543813384d350279093cd483233
7
- data.tar.gz: b2165b3675bc12d80149975edeaf77341ccade1687b1558a4463613853df78362c16f3520f1ae5baf394854cb06f4e21e1c90525feefeecccbd2103b684f712d
6
+ metadata.gz: adbf272b0121b81582d6520bc0c3881980276ede161cb97515d1792563cb29a603c93e7bf35790db1eacc89fb471b68127dccaf24fa43f3205cd758fa53739c2
7
+ data.tar.gz: 45182fbe2c428468ed967650a5e42ad496af4fa8dca236b61ec52ef9aa0ace3c209ece9a52eadd46849252a7dd6f9fa7c047a5017057bb96ca5143ee3155784a
data/README.md CHANGED
@@ -6,7 +6,7 @@ The `github-to-canvas` gem is designed to aid in integrating GitHub and the
6
6
  Canvas LMS. This gem takes a GitHub repository's `README.md` file, converts it
7
7
  to HTML, and pushes it to Canvas using the Canvas API. This gem can also update
8
8
  existing Canvas lessons, allowing continuous alignment of content between GitHub
9
- and Canvas, using the GitHub repository as the single source of truth.
9
+ and Canvas.
10
10
 
11
11
  This gem is built for use internally at [Flatiron School][], so some features may be
12
12
  specific to Flatiron School branding and needs. Access to the
@@ -63,44 +63,21 @@ are present by running `ENV` and finding them in the output list.
63
63
 
64
64
  ## Common Uses
65
65
 
66
- ### Creating and Updating Canvas Lessons
66
+ The GitHub to Canvas gem can be used for the following:
67
67
 
68
- Relevant options:
68
+ - [Create a Canvas Lesson from a Local Repository](#create)
69
+ - [Create a Canvas Lesson from a Remote Repository](#createremote)
70
+ - [Read a Remote Repository as HTML](#read)
71
+ - [Update a Canvas Lesson from a Local Repository](#update)
72
+ - [Update a Canvas Lesson from a Remote Repository](#updateremote)
73
+ - [Retrieve Canvas Course Information as YAML Markdown](#query)
74
+ - [Map GitHub Repositories to a Canvas Course YAML file](#map)
75
+ - [Create New Canvas Course from a YAML file](#buildcourse)
76
+ - [Update Lessons in an Existing Course from a YAML file](#updatecourse)
69
77
 
70
- - `--create-lesson`, `-c`: Requires a Canvas course ID. Creates a new Canvas
71
- lesson, converting the local repository's README.md to HTML. Adds `.canvas`
72
- file to remote repository
73
- - `--align`, `-a`: Updates a canvas lesson based on the local repository's
74
- README.md. If no other options are used, `--align` will look for a `.canvas`
75
- file to know what to lesson to update
76
- - `--course`: Provide a specific course ID. When used with `--id`, this can
77
- override the default behavior for `--align`, allowing you to update any
78
- existing lesson and ignore the `.canvas` file if present.
79
- - `--id`: Provide a specific lesson ID. This can be found in the URL of the
80
- specific lesson. For Pages, used the slugified lesson title.
81
- - `--type`: Sets the type of Canvas lesson to be created (page, assignment or
82
- discussion). If no type, type decided based on repository structure.
83
- - `--name`: Can be used to override default naming behavior. By default, Canvas
84
- lesson names are determined by the first top-level (`#`) header in the
85
- repository's markdown file.
86
- - `--fis-links`, `-l`: Adds additional Flatiron School HTML header after
87
- markdown conversion, including links back to the GitHub repo and it's issue
88
- form.
89
- - `--forkable`: Adds a **Fork** button to the Flatiron School HTML header. For
90
- use with custom Canvas JS to enable Canvas assignment forking workflow for
91
- Flatiron School students.
92
- - `--remove-header-and-footer`, `-r`: Removes top lesson header and any Flatiron
93
- School specific footer links before converting to HTML. Removing top lesson
94
- header prevent duplicate titles while viewing in Canvas.
95
- - `--create-from-github`: Requires a GitHub repository URL. Also requires
96
- `--course` and `--type`. Creates a Canvas lesson, reading from the remote repo
97
- instead of a local repository. Repository must be public.
98
- - `--align-from-github`: Requires a GitHub repo URL, `--course`, `--id`, and
99
- `--type`. Updates a Canvas lesson from a remote repository.
100
- - `--read-from-github`: Requires a GitHub repo URL. Reads a remote repository
101
- and converts its contents to HTML, but does not push to Canvas.
78
+ ### Creating and Updating Canvas Lessons
102
79
 
103
- #### Create a Canvas Lesson from a Local Repository
80
+ #### Create a Canvas Lesson from a Local Repository <a name="create"></a>
104
81
 
105
82
  Navigate into a repository folder cloned down to your local machine and run:
106
83
 
@@ -114,16 +91,15 @@ branded footers. It will also add an HTML header for Canvas that includes links
114
91
  back to the repository.
115
92
 
116
93
  If the lesson type is an assignment, a Fork button will also be added to the
117
- HTML header. Because the command didn't specify, the type of lesson is
118
- determined based on the structure of the local repo - if it has sub-folders, the
119
- lesson will become an assignment; if there are no sub-folders, the lesson will
120
- become a page. If the lesson type is a page, the `--forkable` option will be
121
- ignored.
94
+ HTML header. Because the command didn't specify, the type of lesson is determined
95
+ based on the local repo structure - if it has sub-folders, the lesson will become
96
+ an assignment; if there are no sub-folders, the lesson will become a page. If the
97
+ lesson type is a page, the `--forkable` option will be ignored.
122
98
 
123
99
  Creating a lesson this way will also produce a `.canvas` file. This file
124
100
  contains info about the Canvas lesson that was created.
125
101
 
126
- #### Create a Canvas Lesson from a Remote Repository
102
+ #### Create a Canvas Lesson from a Remote Repository <a name="createremote"></a>
127
103
 
128
104
  To create from a remote repo, run the following command:
129
105
 
@@ -139,7 +115,7 @@ lesson the same way as before.
139
115
 
140
116
  The repository must be public in order to read the markdown file.
141
117
 
142
- #### Read a Remote Repository as HTML
118
+ #### Read a Remote Repository as HTML <a name="read"></a>
143
119
 
144
120
  To read the contents of a remote repo:
145
121
 
@@ -150,11 +126,11 @@ github-to-canvas --read-from-github <URL>
150
126
  This will produce an HTML conversion of the repository's markdwon. This HTML can
151
127
  be directly pasted into Canvas' HTML editor if a manual process is needed.
152
128
 
153
- #### Update a Canvas Lesson from a Local Repository
129
+ #### Update a Canvas Lesson from a Local Repository <a name="update"></a>
154
130
 
155
131
  If you previously created a Canvas lesson from a local repository, you should
156
132
  have a `.canvas` file present in the repo. If that file is present, you can run
157
- the following command to automatically update that same Canvas lesson:
133
+ the following command to update the listed Canvas lesson automatically:
158
134
 
159
135
  ```sh
160
136
  github-to-canvas -a -lr --forkable
@@ -169,7 +145,7 @@ github-to-canvas -a --course <CANVAS_COURSE_ID> --id <CANVAS_LESSON_ID> -lr --fo
169
145
 
170
146
  Canvas course and lesson IDs can be found in the URL.
171
147
 
172
- #### Update a Canvas Lesson from a Remote Repository
148
+ #### Update a Canvas Lesson from a Remote Repository <a name="updateremote"></a>
173
149
 
174
150
  You can update an existing Canvas course using a remote GitHub repository like so:
175
151
 
@@ -182,7 +158,7 @@ using the info provided. Type must match the existing lesson type.
182
158
 
183
159
  ### Course Creation
184
160
 
185
- This gem has the ability to create Canvas courses from scratch. These features
161
+ This gem can create Canvas courses from scratch. These features
186
162
  are still in development and may not work for all course designs. Quiz and
187
163
  Discussion Topic lesson creation is still under development and will not work.
188
164
 
@@ -191,7 +167,7 @@ course, add in modules, and populate those modules with pages and assignments.
191
167
  The required YAML file must follow a specific structure. Using the steps below,
192
168
  this gem can create the necessary YAML markup from existing Canvas courses.
193
169
 
194
- #### Retrieve Canvas Course Information as YAML
170
+ #### Retrieve Canvas Course Information as YAML Markdown <a name="query"></a>
195
171
 
196
172
  To create YAML markup of an existing Canvas course, use the following:
197
173
 
@@ -243,7 +219,7 @@ The output will look similar to this:
243
219
 
244
220
  The output YAML will not include associated GitHub repository information.
245
221
 
246
- #### Map GitHub Repositories to a Canvas Course YAML
222
+ #### Map GitHub Repositories to a Canvas Course YAML file <a name="map"></a>
247
223
 
248
224
  To associate repositories to an existing course YAML, the following command can be used:
249
225
 
@@ -264,7 +240,7 @@ github-to-canvas --map query_results.yml > course_structure.yml
264
240
  The resulting YAML file will contain course information, the module and lesson
265
241
  structure, and each lesson's associated GitHub repository.
266
242
 
267
- #### Create New Canvas Course from YAML
243
+ #### Create New Canvas Course from a YAML file <a name="buildcourse"></a>
268
244
 
269
245
  To create a Canvas course with this gem, you will need a correctly structured
270
246
  YAML file with the course info, modules, lessons and associated lesson
@@ -288,18 +264,18 @@ This command will cause the following to happen:
288
264
  - Create the second lesson and add it to the module...
289
265
  - Repeate process until all modules and lessons are created
290
266
 
291
- #### Align an Existing Course from YAML
267
+ #### Update Lessons in an Existing Course from a YAML file <a name="updatecourse"></a>
292
268
 
293
- After you've created a course using the previous process, go through the
294
- previous steps of `--query` and `--map` to get a fully updated YAML for your
295
- newly created course.
269
+ The GitHub to Canvas gem can be used to update all lessons in a course
270
+ with a single command. To do this, you will need an up-to-date course YAML file with repositories
271
+ mapped to each lesson.
296
272
 
297
273
  ```sh
298
274
  github-to-canvas --query <COURSE_ID> > query_results.yml
299
275
  github-to-canvas --map query_results.yml > your_new_course.yml
300
276
  ```
301
277
 
302
- With this data file, you can use the following command to update all lessons in
278
+ Use the resulting file (in this example, `your_new_course.yml`) to update all lessons in
303
279
  a course based on their GitHub repo:
304
280
 
305
281
  ```sh
@@ -314,33 +290,49 @@ associated repository.
314
290
  ### HTML Code Snippets Do Not Render
315
291
 
316
292
  The Canvas API renders all HTML it receives. If your repository's markdown
317
- includes HTML that is not meant to be rendered (i.e. lessons on HTML or
318
- JavaScript that include HTML code snippets), the content will be rendered as
319
- part of the page's HTML, resulting in unusual display errors in Canvas.
320
-
321
- To fix any rendering issues in Canvas, go to the Canvas WYSIWYG editor for the
322
- afflicted lesson. Click the HTML editor option (`</>` button in the lower right) to
323
- switch to HTML.
324
-
325
- Read the GitHub repo as HTML:
326
-
327
- ```sh
328
- github-to-canvas --read-from-github URL
329
- ```
330
-
331
- Copy the output HTML and paste it in to the Canvas editor. This should clear up
332
- some larger page rendering issues, but may not fix all code snippets issues. To
333
- fix these, switch back to the regular Canvas WYSIWYG editor, then open a second
334
- tab to the GitHub repo you're converting from. Copy any HTML code snippets from
335
- GitHub and paste them into the Canvas editor where they should be displayed.
293
+ includes HTML that is not meant to be rendered, the content will be rendered as
294
+ part of the page's HTML, resulting in unusual display errors in Canvas. Examples of
295
+ this would be lessons on HTML or JavaScript that include HTML code snippets.
296
+
297
+ To prevent HTML from being rendered, include the `--contains-html` option when
298
+ running the GitHub to Canvas gem. This replaces `<` and `>` characters with HTML
299
+ charset values wrapped in `span` elements. This will stop Canvas from rendering
300
+ the HTML.
301
+
302
+ If your markdown contains a mix of HTML that should and should not be rendered,
303
+ you will need to either replace HTML that you want to be rendered with markdown
304
+ syntax equivalents. For example, HTML you want to display as code and an `<img>`
305
+ element you want to render as the image itself, replace the `<img>` tag with
306
+ markdown syntax (`![alt text](url)`).
307
+
308
+ The one exception is the `<iframe>` element. There is no way to easily embed
309
+ videos in GitHub markdown without HTML, so this tag will always be allowed to
310
+ render in Canvas, whether or not you use `--contains-html`.
311
+
312
+ If you have HTML related rendering issues in Canvas that can't be fixed with
313
+ `--contains-html`:
314
+
315
+ - Go to the Canvas WYSIWYG editor for the afflicted lesson.
316
+ - Click the HTML editor option (`</>` button in the lower right) to switch to
317
+ HTML.
318
+ - Read the GitHub repo as HTML:
319
+
320
+ ```sh
321
+ github-to-canvas --read-from-github URL
322
+ ```
323
+
324
+ - Copy the output HTML and paste it in to the Canvas editor. This should clear up
325
+ some larger page rendering issues, but may not fix all code snippets issues.
326
+ - Switch back to the regular Canvas WYSIWYG editor
327
+ - Open a second tab to the GitHub repo you're converting from.
328
+ - Copy any HTML code snippets from GitHub and paste them into the Canvas editor
329
+ where they should be displayed.
336
330
 
337
331
  The Canvas editor will treat the pasted HTML content as code and will
338
332
  automatically replace some characters, escaping the code from the
339
333
  normal rendering process.
340
334
 
341
- Note that realigning after fixing this content with the gem will break the
342
- rendering for these lessons again. A fix is planned for this issue, but has not
343
- been implemented.
335
+ Note that realigning after fixing this content may overwrite fixes.
344
336
 
345
337
  ### Multi-Line Code Snippets Render as a Single Line
346
338
 
@@ -352,9 +344,17 @@ issues, please open a new issue with a markdown example to replicate the error.
352
344
 
353
345
  ### Markdown Formatting Issues Cause Errors in Canvas
354
346
 
355
- Individual markdown headers, paragraphs and code snippets should be separated by
356
- an empty line in the markdown. Without these empty lines, the contents will be
357
- interpretted as one continuous paragraph and ignore formatting.
347
+ An empty line should separate individual markdown headers, paragraphs and code snippets
348
+ in the markdown. Without these empty lines, the contents will be interpretted as one
349
+ continuous paragraph and ignore formatting.
350
+
351
+ ### New Repos That Use a `main` Branch
352
+
353
+ If you are using a new GitHub repository that uses a `main` branch, you may not be able to
354
+ create or update from a remote repository. You can still create and update from a local
355
+ repository by using the `--branch` (`-b`) option and specifying `main` as the branch.
356
+
357
+ A fix is planned for this issue, but not implemented.
358
358
 
359
359
  ## Overview of GitHub to Canvas workflows
360
360
 
@@ -362,9 +362,8 @@ Using this gem, you can maintain Canvas courses in multiple ways - either by
362
362
  creating and updating individual Canvas lessons or through the YAML file process.
363
363
 
364
364
  At Flatiron School, we use the Canvas blueprint course feature. We use the
365
- github-to-canvas gem to update the blueprint copy of lessons. These updates will
366
- appear in future copies of the course, or can be synced down to existing course
367
- copies.
365
+ github-to-canvas gem to update the blueprint copy of lessons. These updates will appear
366
+ in future copies of the course or when synced down associated courses in Canvas.
368
367
 
369
368
  ![github-to-canvas workflow chart](./images/github-to-canvas_workflow.png)
370
369
 
@@ -375,18 +374,46 @@ If you are using github-to-canvas in this way, changes should always be made on
375
374
  the repository, not on Canvas. Any changes made only on Canvas will get
376
375
  overwritten if the lesson is updated using the gem.
377
376
 
378
- ## Additional Options
379
-
380
- ### Specify Branch
377
+ ## Common Options
381
378
 
382
- When creating or aligning content locally, you can use `--branch` (`-b`) to
383
- specify which branch you want to use. If you have a newer repository with a
384
- `main` branch instead of `master`, use this option.
385
-
386
- If you are are creating or aligning content locally, the `.canvas` file is not
387
- automatically committed to the repo. You can automatically commit this file by
388
- including the `--save-to-github` (`-s`) option. This option will attempt to
389
- commit and push the `.canvas` file to the remote repository.
379
+ - `--create-lesson`, `-c`: Requires a Canvas course ID. Creates a new Canvas
380
+ lesson, converting the local repository's README.md to HTML. Adds `.canvas`
381
+ file to remote repository
382
+ - `--align`, `-a`: Updates a canvas lesson based on the local repository's
383
+ README.md. If no other options are used, `--align` will look for a `.canvas`
384
+ file to know what to lesson to update
385
+ - `--course`: Provide a specific course ID. When used with `--id`, this can
386
+ override the default behavior for `--align`, allowing you to update any
387
+ existing lesson and ignore the `.canvas` file if present.
388
+ - `--id`: Provide a specific lesson ID. This can be found in the URL of the
389
+ specific lesson. For Pages, used the slugified lesson title.
390
+ - `--type`: Sets the type of Canvas lesson to be created (page, assignment or
391
+ discussion). If no type, type decided based on repository structure.
392
+ - `--name`: Can be used to override default naming behavior. By default, Canvas
393
+ lesson names are determined by the first top-level (`#`) header in the
394
+ repository's markdown file.
395
+ - `--fis-links`, `-l`: Adds additional Flatiron School HTML header after
396
+ markdown conversion, including links back to the GitHub repo and it's issue
397
+ form.
398
+ - `--forkable`: Adds a **Fork** button to the Flatiron School HTML header. For
399
+ use with custom Canvas JS to enable Canvas assignment forking workflow for
400
+ Flatiron School students.
401
+ - `--remove-header-and-footer`, `-r`: Removes top lesson header and any Flatiron
402
+ School specific footer links before converting to HTML. Removing top lesson
403
+ header prevents duplicate titles while viewing in Canvas.
404
+ - `--create-from-github`: Requires a GitHub repository URL. Also requires
405
+ `--course` and `--type`. Creates a Canvas lesson, reading from the remote repo
406
+ instead of a local repository. Repository must be public.
407
+ - `--align-from-github`: Requires a GitHub repo URL, `--course`, `--id`, and
408
+ `--type`. Updates a Canvas lesson from a remote repository.
409
+ - `--read-from-github`: Requires a GitHub repo URL. Reads a remote repository
410
+ and converts its contents to HTML, but does not push to Canvas.
411
+ - `--branch`, `-b`: Can be used when creating or aligning with a local repo to
412
+ specify which branch to use. Use this if you have a new repository that uses a
413
+ `main` branch instead of `master`.
414
+ - `--save-to-github`, `-s`: If you are are creating or aligning content locally,
415
+ the `.canvas` file is not automatically committed to the repo. This option will
416
+ attempt to commit and push the `.canvas` file to the remote repository.
390
417
 
391
418
  Run `github-to-canvas --help` for additional options not listed in this Readme.
392
419
 
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ require 'byebug'
4
+
2
5
  require 'optparse'
3
6
  require 'github-to-canvas'
4
7
 
@@ -75,12 +78,15 @@ OptionParser.new do |opts|
75
78
  end
76
79
  opts.on("-tTYPE", "--type TYPE",
77
80
  "Sets the type Canvas lesson to be created (page or assignment). If no type, type decided based on repository structure") do |type|
78
- if type == 'page' || type == 'assignment' || type == 'discussion'
79
- options[:type] = type
80
- else
81
- puts "Invalid type. Defaulting to page"
82
- options[:type] = "page"
83
- end
81
+ # byebug
82
+ options[:type] = type.downcase
83
+ abort if type == 'quiz' || type == 'discussion'
84
+ # if type == 'page' || type == 'assignment' || type == 'discussion' || type == 'quiz' || type == 'Page' || type == 'Assignment' || type == 'Discussion' || type == 'Quiz'
85
+
86
+ # else
87
+ # puts "Invalid type. Defaulting to page"
88
+ # options[:type] = "page"
89
+ # end
84
90
  end
85
91
  opts.on("-fFILE", "--file FILE",
86
92
  "Looks for and uses a markdown file in the currentt folder as source for conversion. Default file is README.md. Skips writing .canvas to repository") do |file|
@@ -102,6 +108,14 @@ OptionParser.new do |opts|
102
108
  "Adds additional Flatiron School HTML after markdown conversion") do |f|
103
109
  options[:fis] = true
104
110
  end
111
+ opts.on("-g", "--git-links",
112
+ "Adds additional GitHub after markdown conversion") do |f|
113
+ options[:git_links] = true
114
+ end
115
+ opts.on("--aaq",
116
+ "Adds AAQ flag to HTML header appended with --fis-links") do |aaq|
117
+ options[:aaq] = aaq
118
+ end
105
119
  opts.on("--forkable",
106
120
  "Used with --fis-links, adds fork button to HTML header injected into Canvas lesson") do |remote|
107
121
  options[:forkable] = true
@@ -130,6 +144,14 @@ OptionParser.new do |opts|
130
144
  "REQUIRES -f or --file Associates canvas lessons with repositories. Use query to create required YAML file") do |file|
131
145
  options[:map] = file
132
146
  end
147
+ opts.on("--urls-only",
148
+ "Use with --map. Outputs repo URLs instead of YAML") do |urls|
149
+ options[:urls_only] = urls
150
+ end
151
+ # opts.on("--csv COURSE",
152
+ # "Returns a course's lesson struction as CSV") do |course|
153
+ # options[:csv] = course
154
+ # end
133
155
  opts.on("--read-from-canvas CANVAS_URL",
134
156
  "Retrieves an existing Canvas lesson using the provided URL") do |url|
135
157
  options[:read_from_canvas] = url
@@ -162,6 +184,23 @@ OptionParser.new do |opts|
162
184
  "Updates all lessons in a course using remote repos in provided YAML file") do |file|
163
185
  options[:update_course_lessons] = file
164
186
  end
187
+ opts.on("--clone-from-yaml YAML_FILE",
188
+ "Iterates over provided course YAML file and clones repos locally") do |file|
189
+ options[:clone_from_yaml] = file
190
+ end
191
+ opts.on("--contains-html",
192
+ "Escapes all HTML included in source markdown by replacing '<' and '>' with HTML charset values") do |html|
193
+ options[:contains_html] = html
194
+ end
195
+ opts.on("--canvas-to-canvas COURSE",
196
+ "Copies an existing Canvas lesson into another Canvas lesson") do |canvas_to_canvas|
197
+ options[:canvas_to_canvas] = canvas_to_canvas
198
+ end
199
+ opts.on("--build-from-csv CSV",
200
+ "Build a course usin a CSV of lesson repos, names, modules, and types") do |csv_build|
201
+ options[:csv_build] = csv_build
202
+ end
203
+
165
204
 
166
205
  end.parse!
167
206
 
@@ -171,12 +210,29 @@ if options[:version]
171
210
  end
172
211
 
173
212
  if options[:read_from_canvas]
174
- GithubToCanvas.new(mode: 'canvas_read', filepath: options[:read_from_canvas])
213
+ GithubToCanvas.new(mode: 'canvas_read',
214
+ filepath: options[:read_from_canvas])
215
+ abort
216
+ end
217
+
218
+ if options[:canvas_to_canvas]
219
+ GithubToCanvas.new(mode: 'canvas_copy',
220
+ filepath: options[:canvas_to_canvas],
221
+ course_id: options[:course_id],
222
+ type: options[:type],
223
+ id: options[:id]
224
+ )
175
225
  abort
176
226
  end
177
227
 
178
228
  if options[:read_from_github]
179
- GithubToCanvas.new(mode: 'github_read', filepath: options[:read_from_github])
229
+ GithubToCanvas.new(mode: 'github_read',
230
+ filepath: options[:read_from_github],
231
+ remove_header_and_footer: !!options[:remove_header_and_footer],
232
+ forkable: !!options[:forkable],
233
+ fis_links: !!options[:fis],
234
+ aaq: !!options[:aaq],
235
+ contains_html: options[:contains_html])
180
236
  abort
181
237
  end
182
238
 
@@ -186,9 +242,12 @@ if options[:create_from_github]
186
242
  filepath: options[:create_from_github],
187
243
  course_id: options[:course_id],
188
244
  type: options[:type],
245
+ name: options[:name],
189
246
  remove_header_and_footer: !!options[:remove_header_and_footer],
190
247
  forkable: !!options[:forkable],
191
- fis_links: !!options[:fis])
248
+ fis_links: !!options[:fis],
249
+ aaq: !!options[:aaq],
250
+ contains_html: options[:contains_html])
192
251
  else
193
252
  puts 'Canvas course ID and lesson type required. Example: github-to-canvas --create-from-github URL --course ID --type TYPE'
194
253
  end
@@ -202,9 +261,12 @@ if options[:align_from_github]
202
261
  course_id: options[:course_id],
203
262
  type: options[:type],
204
263
  id: options[:id],
264
+ name: options[:name],
205
265
  remove_header_and_footer: !!options[:remove_header_and_footer],
206
266
  forkable: !!options[:forkable],
207
- fis_links: !!options[:fis])
267
+ fis_links: !!options[:fis],
268
+ aaq: !!options[:aaq],
269
+ contains_html: options[:contains_html])
208
270
  else
209
271
  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'
210
272
  end
@@ -217,7 +279,28 @@ if options[:query]
217
279
  end
218
280
 
219
281
  if options[:map]
220
- GithubToCanvas.new(mode: 'map', file_to_convert: options[:map])
282
+ GithubToCanvas.new(mode: 'map',
283
+ file_to_convert: options[:map],
284
+ urls_only: !!options[:urls_only])
285
+ abort
286
+ end
287
+
288
+ if options[:csv]
289
+ GithubToCanvas.new(mode: 'csv', file_to_convert: options[:csv])
290
+ abort
291
+ end
292
+
293
+ if options[:csv_build]
294
+ GithubToCanvas.new(mode: 'csv_build',
295
+ file_to_convert: options[:csv_build],
296
+ course_id: options[:course_id],
297
+ fis_links: !!options[:fis],
298
+ remove_header_and_footer: !!options[:remove_header_and_footer],
299
+ aaq: !!options[:aaq],
300
+ forkable: !!options[:forkable],
301
+ branch: options[:branch],
302
+ contains_html: options[:contains_html],
303
+ git_links: !!options[:git_links])
221
304
  abort
222
305
  end
223
306
 
@@ -226,7 +309,10 @@ if options[:build_course]
226
309
  file_to_convert: options[:build_course],
227
310
  fis_links: !!options[:fis],
228
311
  remove_header_and_footer: !!options[:remove_header_and_footer],
229
- forkable: !!options[:forkable])
312
+ aaq: !!options[:aaq],
313
+ forkable: !!options[:forkable],
314
+ contains_html: options[:contains_html],
315
+ git_links: !!options[:git_links])
230
316
  abort
231
317
  end
232
318
 
@@ -237,7 +323,10 @@ if options[:add_to_course]
237
323
  file_to_convert: options[:add_to_course],
238
324
  fis_links: !!options[:fis],
239
325
  remove_header_and_footer: !!options[:remove_header_and_footer],
240
- forkable: !!options[:forkable])
326
+ forkable: !!options[:forkable],
327
+ aaq: !!options[:aaq],
328
+ contains_html: options[:contains_html],
329
+ git_links: !!options[:git_links])
241
330
  else
242
331
  puts '--course required'
243
332
  end
@@ -249,10 +338,18 @@ if options[:update_course_lessons]
249
338
  file_to_convert: options[:update_course_lessons],
250
339
  fis_links: !!options[:fis],
251
340
  remove_header_and_footer: !!options[:remove_header_and_footer],
252
- forkable: !!options[:forkable])
341
+ forkable: !!options[:forkable],
342
+ aaq: !!options[:aaq],
343
+ contains_html: options[:contains_html],
344
+ git_links: !!options[:git_links])
253
345
  abort
254
346
  end
255
347
 
348
+ if options[:clone_from_yaml]
349
+ GithubToCanvas.new(mode: 'clone_course',
350
+ file_to_convert: options[:clone_from_yaml])
351
+ abort
352
+ end
256
353
 
257
354
  if !options[:type]
258
355
  if Dir.glob("**/*/").empty?
@@ -304,9 +401,12 @@ if options[:create_lesson]
304
401
  type: options[:type],
305
402
  save_to_github: !!options[:save_to_github],
306
403
  fis_links: !!options[:fis],
404
+ git_links: !!options[:git_links],
307
405
  remove_header_and_footer: !!options[:remove_header_and_footer],
308
406
  only_update_content: !!options[:only_content],
309
- forkable: !!options[:forkable])
407
+ forkable: !!options[:forkable],
408
+ aaq: !!options[:aaq],
409
+ contains_html: options[:contains_html])
310
410
  end
311
411
 
312
412
  if options[:align]
@@ -319,8 +419,11 @@ if options[:align]
319
419
  name: options[:name],
320
420
  type: options[:type],
321
421
  save_to_github: !!options[:save_to_github],
322
- fis_links: !!options[:fis],
422
+ fis_links: !!options[:fis],
423
+ git_links: !!options[:git_links],
323
424
  remove_header_and_footer: !!options[:remove_header_and_footer],
324
425
  only_update_content: !!options[:only_content],
325
- forkable: !!options[:forkable])
426
+ forkable: !!options[:forkable],
427
+ aaq: !!options[:aaq],
428
+ contains_html: options[:contains_html])
326
429
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug'
2
+ require 'csv'
1
3
  require_relative './github-to-canvas/create_canvas_lesson'
2
4
  require_relative './github-to-canvas/update_canvas_lesson'
3
5
  require_relative './github-to-canvas/canvas_dotfile'
@@ -20,12 +22,16 @@ class GithubToCanvas
20
22
  when 'query'
21
23
  CanvasInterface.get_course_info(options[:course_id], options[:id])
22
24
  when 'map'
23
- CanvasInterface.map_course_info(options[:file_to_convert])
25
+ CanvasInterface.map_course_info(options)
26
+ when 'csv'
27
+ CanvasInterface.csv(options[:file_to_convert])
24
28
  when 'canvas_read'
25
29
  puts CanvasInterface.read_lesson(options[:filepath])
30
+ when 'canvas_copy'
31
+ CanvasInterface.copy_lesson(options)
26
32
  when 'github_read'
27
- markdown = GithubInterface.read_remote(options[:filepath])
28
- puts RepositoryConverter.convert_to_html(markdown)
33
+ html = RepositoryConverter.remote_file_conversion(options)
34
+ puts RepositoryConverter.adjust_converted_html(options, html)
29
35
  when 'create' # used with a local repo
30
36
  html = RepositoryConverter.local_file_conversion(options)
31
37
  name = RepositoryInterface.get_name(options[:filepath], html)
@@ -35,21 +41,30 @@ class GithubToCanvas
35
41
  puts "Canvas lesson created. Lesson available at #{response['html_url']}"
36
42
  when 'align' # used with a local repo
37
43
  html = RepositoryConverter.local_file_conversion(options)
38
- name = RepositoryInterface.get_name(options[:filepath], html)
44
+ name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
39
45
  html = RepositoryConverter.adjust_converted_html(options, html)
40
46
  CanvasInterface.update_all_related_lessons(options, name, html)
41
47
 
42
48
  when 'github_create'
49
+ if (!options[:branch])
50
+ options[:branch] = 'master'
51
+ end
43
52
  html = RepositoryConverter.remote_file_conversion(options)
44
- name = RepositoryInterface.get_name(options[:filepath], html)
45
- html = RepositoryConverter.adjust_converted_html(options, html)
46
53
 
54
+ html = RepositoryConverter.adjust_converted_html(options, html)
55
+ name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
56
+ byebug
57
+ puts name
47
58
  response = CanvasInterface.create_lesson(options, name, html)
48
59
 
49
60
  puts "Canvas lesson created. Lesson available at #{response['html_url']}"
50
61
  when 'github_align'
62
+ if (!options[:branch])
63
+ options[:branch] = 'master'
64
+ end
51
65
  html = RepositoryConverter.remote_file_conversion(options)
52
- name = RepositoryInterface.get_name(options[:filepath], html)
66
+ name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
67
+
53
68
  html = RepositoryConverter.adjust_converted_html(options, html)
54
69
  response = CanvasInterface.update_existing_lesson(options, name, html)
55
70
  puts "Canvas lesson updated. Lesson available at #{response['html_url']}"
@@ -69,10 +84,8 @@ class GithubToCanvas
69
84
  options[:course_id] = created_course_info["id"]
70
85
  options[:filepath] = lesson["repository"]
71
86
 
72
-
73
87
  html = RepositoryConverter.remote_file_conversion(options)
74
88
  # Add each lesson to it's module
75
-
76
89
  html = RepositoryConverter.adjust_converted_html(options, html)
77
90
  created_lesson_info = CanvasInterface.create_lesson(options, lesson["title"], html)
78
91
  lesson = lesson.merge(created_lesson_info)
@@ -133,6 +146,78 @@ class GithubToCanvas
133
146
  sleep(1)
134
147
  }
135
148
  }
149
+ when 'clone_course'
150
+ course_yaml = YAML.load(File.read(options[:file_to_convert]))
151
+ new_dir = "#{course_yaml[:name].downcase.gsub(' ','-')}"
152
+ cmd = "mkdir #{new_dir}"
153
+ `#{cmd}`
154
+ course_yaml[:modules].each { |module_info|
155
+ puts "Cloning #{module_info[:name]}"
156
+ module_info[:lessons].each { |lesson|
157
+ if lesson["repository"] == ""
158
+ puts "No repository found for #{lesson['title']}"
159
+ next
160
+ else
161
+ cmd = "git clone #{lesson['repository']}"
162
+ puts cmd
163
+ GithubInterface.cd_into_and(new_dir, cmd)
164
+ end
165
+ }
166
+ }
167
+ when 'csv_build'
168
+ if !options[:course_id]
169
+ course_info = {
170
+ name: "CSV Build Test",
171
+ course_code: "CSV-TEST"
172
+ }
173
+ created_course_info = CanvasInterface.create_course(course_info)
174
+ puts "Course created - #{created_course_info["id"]}"
175
+ puts "Make sure to add yourself as a teacher to this course before continuing, then press Enter/Return"
176
+ input = gets
177
+ options[:course_id] = created_course_info["id"]
178
+ else
179
+ puts "Adding to course #{options[:course_id]}"
180
+ end
181
+
182
+ csv_data = CSV.read(options[:file_to_convert])
183
+ created_module_info = {
184
+ "id" => "",
185
+ "name" => ""
186
+ }
187
+
188
+ csv_data.each { |lesson|
189
+ # lesson[0] == repo
190
+ # lesson[1] == name
191
+ # lesson[2] == module
192
+ # lesson[3] == type
193
+ # lesson[4] == yes/no contains HTML
194
+ module_info = {
195
+ name: lesson[2]
196
+ }
197
+ if created_module_info["name"] != module_info[:name]
198
+ created_module_info = CanvasInterface.create_module(options[:course_id], module_info)
199
+ puts "New module created - #{created_module_info["id"]} - #{created_module_info["name"]}"
200
+ end
201
+
202
+ options[:filepath] = lesson[0]
203
+ options[:name] = lesson[1]
204
+ options[:type] = lesson[3]
205
+ options[:branch] = "master" if !options[:branch]
206
+ if !options[:contains_html]
207
+ options[:contains_html] = (lesson[4] == "yes" || lesson[4] == "Yes") ? true : false
208
+ end
209
+
210
+
211
+ html = RepositoryConverter.remote_file_conversion(options)
212
+ html = RepositoryConverter.adjust_converted_html(options, html)
213
+ created_lesson_info = CanvasInterface.create_lesson(options, lesson[1], html)
214
+ created_lesson_info["page_url"] = created_lesson_info["url"] if !created_lesson_info["page_url"]
215
+ created_lesson_info["id"] = created_lesson_info["page_url"] if !created_lesson_info["id"]
216
+ created_lesson_info["type"] = options[:type]
217
+ puts "Creating lesson - #{options[:name]}"
218
+ response = CanvasInterface.add_to_module(options[:course_id], created_module_info, created_lesson_info)
219
+
220
+ }
136
221
  else
137
222
  puts VERSION
138
223
  end
@@ -1,3 +1,4 @@
1
+ require 'byebug'
1
2
  require 'json'
2
3
  require 'rest-client'
3
4
  require 'yaml'
@@ -46,41 +47,39 @@ class CanvasInterface
46
47
  JSON.parse(response.body)
47
48
  end
48
49
 
49
- def self.create_quiz(options, quiz_data)
50
-
51
- end
52
-
53
50
  def self.add_to_module(course_id, module_info, lesson_info)
54
51
  # POST /api/v1/courses/:course_id/modules/:module_id/items
55
52
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/modules/#{module_info["id"]}/items"
56
53
 
57
- if lesson_info["type"] == "Page"
54
+ if lesson_info["type"] == "Page" || lesson_info["type"] == "page"
58
55
  payload = {
59
- 'module_item[title]' => lesson_info["title"],
60
- 'module_item[type]' => lesson_info["type"],
61
- 'module_item[indent]' => 0,
62
- 'module_item[completion_requirement][type]' => 'must_view'
63
- }
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
+ }
64
62
  elsif lesson_info["type"] == "Quiz"
65
63
  puts "Quiz needs to be added manually - #{lesson_info['title']} - lesson_info["
66
64
  else
67
65
 
68
66
  payload = {
69
67
  'module_item[title]' => lesson_info["title"],
70
- 'module_item[type]' => lesson_info["type"],
68
+ 'module_item[type]' => lesson_info["type"].capitalize,
71
69
  'module_item[indent]' => 1,
70
+ 'module_item[content_id]' => lesson_info["id"],
72
71
  'module_item[completion_requirement][type]' => 'must_submit'
73
72
  }
74
73
  end
75
74
  begin
76
75
  response = RestClient.post(url, payload, self.headers)
77
76
  rescue
78
- puts "Something went wrong while add lesson #{lesson_info["id"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Assignment"
79
- puts "Something went wrong while add lesson #{lesson_info["page_url"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Page"
77
+ byebug
78
+
79
+ puts "Something went wrong while adding lesson #{lesson_info["id"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Assignment"
80
+ puts "Something went wrong while adding lesson #{lesson_info["page_url"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Page"
80
81
  abort
81
82
  end
82
-
83
-
84
83
  response
85
84
 
86
85
  end
@@ -95,7 +94,7 @@ class CanvasInterface
95
94
 
96
95
  begin
97
96
  headers = self.headers
98
- if options[:type] == 'page'
97
+ if options[:type] == 'page' || options[:type] == 'Page'
99
98
  response = RestClient.get(url, headers)
100
99
  lesson_info = JSON.parse(response)
101
100
  url = url.sub(/[^\/]+$/, lesson_info["page_id"].to_s)
@@ -170,6 +169,7 @@ class CanvasInterface
170
169
  [info, type]
171
170
  end
172
171
 
172
+
173
173
  def self.get_course_info(course, id)
174
174
  if id
175
175
  lesson_data = self.get_lesson_info(course, id)
@@ -195,6 +195,7 @@ class CanvasInterface
195
195
  while !!index
196
196
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/modules?page=#{index}&per_page=20"
197
197
  index += 1
198
+
198
199
  response = RestClient.get(url, self.headers)
199
200
  modules = JSON.parse(response.body)
200
201
 
@@ -202,7 +203,7 @@ class CanvasInterface
202
203
  course_info[:modules] = course_info[:modules] + modules
203
204
  else
204
205
  index = nil
205
- end
206
+ end
206
207
  end
207
208
 
208
209
  course_info[:modules] = course_info[:modules].map do |mod|
@@ -215,11 +216,12 @@ class CanvasInterface
215
216
  while !!index
216
217
  url = "#{ENV['CANVAS_API_PATH']}/courses/#{course}/modules/#{mod['id']}/items?page=#{index}&per_page=20"
217
218
  index += 1
218
- response = RestClient.get(url, headers={
219
- "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
220
- })
219
+ response = RestClient.get(url, self.headers)
221
220
  lessons = JSON.parse(response.body)
222
221
  lessons = lessons.map do |lesson|
222
+ if lesson["type"] == "ExternalUrl"
223
+ next
224
+ end
223
225
  lesson = lesson.slice("id","title","name","indent","type","html_url","page_url","url","completion_requirement", "published")
224
226
  lesson["repository"] = ""
225
227
  lesson['id'] = lesson['url'].gsub(/^(.*[\\\/])/,'')
@@ -234,16 +236,65 @@ class CanvasInterface
234
236
  end
235
237
  new_mod
236
238
  end
237
-
239
+
238
240
  puts course_info.to_yaml
239
241
 
240
242
  rescue
243
+ byebug
241
244
  puts "Something went wrong while getting info about course #{course}"
242
245
  abort
243
246
  end
244
247
  end
245
248
 
246
- def self.map_course_info(file_to_convert)
249
+ def self.map_course_info(options)
250
+ course_info = YAML.load(File.read("#{Dir.pwd}/#{options[:file_to_convert]}"))
251
+ course_info[:modules] = course_info[:modules].map do |mod|
252
+ mod[:lessons] = mod[:lessons].map do |lesson|
253
+
254
+ url = lesson["url"]
255
+ response = RestClient.get(url, headers={
256
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
257
+ })
258
+ begin
259
+ lesson_data = JSON.parse(response)
260
+ contents = lesson_data["body"] if lesson["type"] == "Page"
261
+ contents = lesson_data["message"] if lesson["type"] == "Discussion"
262
+ contents = lesson_data["description"] if lesson["type"] == "Assignment" || lesson["type"] == "Quiz"
263
+ if contents.nil?
264
+ repo = ""
265
+ else
266
+ if contents[/data-repo=\"(.*?)"/]
267
+ repo = contents[/data-repo=\"(.*?)"/]
268
+ repo = repo.slice(11..-2)
269
+ elsif contents[/class=\"fis-git-link\" href=\"(.*?)"/]
270
+ repo = contents[/class=\"fis-git-link\" href=\"(.*?)"/]
271
+ repo = repo.slice(27..-2)
272
+ else
273
+ repo = ""
274
+ end
275
+ end
276
+ rescue
277
+ puts 'Error while mapping course info.'
278
+ abort
279
+ end
280
+
281
+ if repo != nil && repo != ""
282
+ if repo.include?('https://github.com/learn-co-curriculum/')
283
+ lesson["repository"] = repo
284
+ else
285
+ lesson["repository"] = "https://github.com/learn-co-curriculum/" + repo
286
+ puts lesson["repository"] if options[:urls_only]
287
+ end
288
+ end
289
+ sleep(1)
290
+ lesson
291
+ end
292
+ mod
293
+ end
294
+ puts course_info.to_yaml if !options[:urls_only]
295
+ end
296
+
297
+ def self.csv(file_to_convert)
247
298
  course_info = YAML.load(File.read("#{Dir.pwd}/#{file_to_convert}"))
248
299
  course_info[:modules] = course_info[:modules].map do |mod|
249
300
  mod[:lessons] = mod[:lessons].map do |lesson|
@@ -287,15 +338,41 @@ class CanvasInterface
287
338
  end
288
339
  mod
289
340
  end
341
+ byebug
290
342
  puts course_info.to_yaml
291
343
  end
292
344
 
293
- def self.submit_to_canvas(course_id, type, name, readme)
294
-
295
- end
345
+ def self.copy_lesson(options)
346
+ types = ["page", "assignment", "quiz", "discussion"]
347
+ url = options[:filepath]
348
+ type = types.find {|type| url.match(type)}
349
+ options[:type] = type
350
+ if !url.include?(ENV['CANVAS_API_PATH'])
351
+ url = url.sub(/^.*\/\/.*?\//,"#{ENV['CANVAS_API_PATH']}/")
352
+ end
296
353
 
297
-
354
+ response = RestClient.get(url, headers={
355
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
356
+ })
298
357
 
358
+ lesson_info = JSON.parse(response)
359
+ lesson_info = lesson_info.slice("title",
360
+ "name",
361
+ "description",
362
+ "body",
363
+ "message",
364
+ "shuffle_answers",
365
+ "allowed_attempts",
366
+ "question_count"
367
+ )
368
+ if options[:type] == "page"
369
+ self.update_existing_lesson(options, lesson_info["title"], lesson_info["body"])
370
+ else
371
+ self.update_existing_lesson(options, lesson_info["name"], lesson_info["description"])
372
+ end
373
+
374
+
375
+ end
299
376
 
300
377
  def self.build_payload(options, name, html)
301
378
  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
 
@@ -17,7 +17,7 @@ class RepositoryConverter
17
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]
21
21
  markdown = self.fix_local_images(options, markdown, raw_remote_url)
22
22
  html = self.convert_to_html(markdown)
23
23
  # self.fix_local_html_links(options, html, options[:filepath])
@@ -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
+ 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
29
40
  markdown = self.fix_local_images(options, markdown, raw_remote_url)
30
41
  html = self.convert_to_html(markdown)
31
42
  # self.fix_local_html_links(options, html, options[:filepath])
32
43
  end
33
44
 
34
45
  def self.convert_to_html(markdown)
35
- 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})
36
48
  html = redcarpet.render(markdown)
37
- self.remove_line_breaks(html)
49
+ # self.remove_line_breaks(html)
38
50
  end
39
51
 
40
52
  def self.adjust_converted_html(options, html)
@@ -43,12 +55,52 @@ class RepositoryConverter
43
55
  html = self.remove_header_and_footer(html)
44
56
  end
45
57
 
46
- if options[:fis_links]
58
+ if options[:fis_links] || options[:git_links]
47
59
  html = self.add_fis_links(options, html)
48
60
  end
61
+
62
+ if options[:contains_html]
63
+ html = self.fix_escaped_inline_html_code(html)
64
+ end
65
+
49
66
  html
50
67
  end
51
68
 
69
+ def self.fix_escaped_inline_html_code(html)
70
+
71
+ # stops HTML/JSX code blocks from rendering as HTML in Canvas
72
+ html = html.gsub("&amp;gt;</code>", "&gt;</code>")
73
+ html = html.gsub("&amp;gt;</code>", "&gt;</code>")
74
+
75
+ # fixes < and > code snippets
76
+ html = html.gsub("&amp;lt;", "&lt;")
77
+ html = html.gsub("&amp;gt;", "&gt;")
78
+
79
+ # # fixes blockquotes
80
+ # html = html.gsub(/\n<p>&gt\;(.*)\n&gt\;/) { |bq|
81
+ # bq.delete_prefix!("\n<p>&gt;")
82
+ # "\n<blockquote>" + bq
83
+ # }
84
+ # html = html.gsub(/\n&gt\;(.*)\n&gt\;/) { |bq|
85
+ # bq.delete_prefix!("\n&gt;")
86
+ # " " + bq
87
+ # }
88
+ # html = html.gsub(/\n&gt\;(.*)<\/p>/) { |bq|
89
+ # bq.delete_prefix!("\n&gt\;")
90
+ # bq.delete_suffix!("</p>")
91
+ # " " + bq + "</blockquote>"
92
+ # }
93
+
94
+ html
95
+ end
96
+
97
+
98
+ def self.escape_existing_html(markdown)
99
+ markdown = markdown.gsub(/<\/(?!iframe)/, "&lt;/")
100
+ markdown = markdown.gsub(/<(?!iframe)/, "&lt;")
101
+ markdown = markdown.gsub(/(?<!iframe)>/, "&gt;")
102
+ end
103
+
52
104
  def self.remove_header_and_footer(html)
53
105
  new_html = self.remove_html_header(html)
54
106
  new_html = self.remove_footer(new_html)
@@ -56,12 +108,15 @@ class RepositoryConverter
56
108
  end
57
109
 
58
110
  def self.remove_header(readme)
59
- readme.gsub!(/^# .+?\n\n/,"")
111
+ readme = readme.gsub(/^# .+?\n\n/,"")
60
112
  readme.gsub(/^# .+?\n/,"")
61
113
  end
62
114
 
63
115
  def self.remove_footer(readme)
64
116
  readme.gsub(/<p class='util--hide'(.+?)<\/p>/,"")
117
+ readme.gsub(/<p data-visibility='hidden'(.+?)<\/p>/,"")
118
+ readme.gsub(/<p>&lt\;p data-visibility=&#39\;hidden&#39(.+?)<\/p>/,"")
119
+ readme.gsub(/<p>&lt\;p class=&#39;util--hide&#39\;(.+?)<\/p>/,"")
65
120
  end
66
121
 
67
122
  def self.remove_html_header(html)
@@ -114,7 +169,7 @@ class RepositoryConverter
114
169
  end
115
170
 
116
171
  def self.adjust_local_markdown_images(readme, raw_remote_url, branch)
117
- readme.gsub!(/\!\[.+\]\(.+\)/) {|image_markdown|
172
+ readme.gsub(/\!\[.+\]\(.+\)/) {|image_markdown|
118
173
  if !image_markdown.match?('amazonaws.com') && !image_markdown.match?('https://') && !image_markdown.match?('http://') && !image_markdown.match?('youtube')
119
174
  image_markdown.gsub!(/\(.+\)/) { |path|
120
175
  path.delete_prefix!("(")
@@ -127,12 +182,18 @@ class RepositoryConverter
127
182
  end
128
183
 
129
184
  def self.adjust_local_html_images(readme, raw_remote_url, branch)
130
- readme.gsub!(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
131
- if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube')
132
- image_source.gsub!(/(\'|\")/, "")
133
- image_source.gsub!(/src=/, '')
134
- image_source.strip!
135
- 'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
185
+ readme.gsub(/src=(\'|\")[\s\S]*?(\'|\")/) { |image_source|
186
+
187
+ if !image_source.match?('amazonaws.com') && !image_source.match?('https://') && !image_source.match?('http://') && !image_source.match?('youtube') && !image_source.match(/src=(\'|\")(?=<%)/)
188
+ image_source = image_source.gsub(/(\'|\")/, "")
189
+ image_source = image_source.gsub(/src=/, '')
190
+ image_source = image_source.strip
191
+
192
+ begin
193
+ 'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
194
+ rescue
195
+ byebug
196
+ end
136
197
  else
137
198
  image_source
138
199
  end
@@ -162,12 +223,12 @@ class RepositoryConverter
162
223
  def self.add_fis_links(options, html)
163
224
  repo_info = self.get_repo_info(options[:filepath])
164
225
  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])
226
+ header = self.create_github_link_header(repo_info[:repo_path], options)
227
+ data_element = self.create_data_element(repo_info[:repo_org], repo_info[:repo_name], options[:aaq])
167
228
  data_element + header + html
168
229
  end
169
230
 
170
- def self.create_github_link_header(repo_path, forkable)
231
+ def self.create_github_link_header(repo_path, options)
171
232
  # add link to associated repository
172
233
  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>"
173
234
 
@@ -175,16 +236,23 @@ class RepositoryConverter
175
236
  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>"
176
237
 
177
238
  # add link to fork (forking handled by separate Flatiron server, generation of link handled via custom Canvas JS theme file)
178
- if (forkable)
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>"
239
+
240
+ if (options[:forkable])
241
+ 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>"
180
242
  "<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_repo_link}#{github_issue_link}</header>"
243
+ elsif options[:git_links]
244
+ "<header class='fis-header'>#{github_repo_link}#{github_issue_link}</header>"
181
245
  else
182
246
  "<header class='fis-header' style='visibility: hidden;'>#{github_repo_link}#{github_issue_link}</header>"
183
247
  end
184
248
  end
185
249
 
186
- def self.create_data_element(repo_org, repo_name)
187
- "<div id='git-data-element' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
250
+ def self.create_data_element(repo_org, repo_name, aaq)
251
+ if (aaq)
252
+ "<div id='git-data-element' data-aaq='enabled' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
253
+ else
254
+ "<div id='git-data-element' data-org='#{repo_org}' data-repo='#{repo_name}'></div>"
255
+ end
188
256
  end
189
257
 
190
258
 
@@ -1,3 +1,3 @@
1
1
  class GithubToCanvas
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.7"
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.1
4
+ version: 0.1.7.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - maxwellbenton
@@ -104,11 +104,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
104
  version: '0'
105
105
  required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
107
+ - - ">"
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: 1.3.1
110
110
  requirements: []
111
- rubygems_version: 3.1.4
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