github-to-canvas 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 157424448fb4396e7ae200733bf3c27fb45b9d74546f026bf1c9aad55fe958f1
4
+ data.tar.gz: a675bce4eb13531be6b80867798bf260ecc6edba8ef0e555bbb7b861d24397b3
5
+ SHA512:
6
+ metadata.gz: df3a924b7ab026c0101af16e538b333f9b0aac17e4f9a5e66301d5ad690bad3ec7c229aa1547254f532b8d69ca5a27468c6935ee4db69e1544b57add7d0d8859
7
+ data.tar.gz: 51f8d7055e94c7cc0deaf11defa4a5c9a39ab7300dc10e69f337578a6417f4da4a95ebad9223d46cb22539ec6b3d59f091a2467cb2952cd26c4aaedba768cbdc
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,39 @@
1
+ # Contributing to Learn.co Curriculum
2
+
3
+ We're really excited that you're about to contribute to the
4
+ [open curriculum](https://learn.co/content-license) on
5
+ [Learn.co](https://learn.co). If this is your first time contributing, please
6
+ continue reading to learn how to make the most meaningful and useful impact
7
+ possible.
8
+
9
+ ## Raising an Issue to Encourage a Contribution
10
+
11
+ If you notice a problem with the curriculum that you believe needs improvement
12
+ , but you're unable to make the change yourself, you should raise a Github issue
13
+ containing a clear description of the problem. Include relevant snippets of the
14
+ content and screenshots if applicable. Curriculum owners regularly review
15
+ issue lists, and your issue will be prioritized and addressed as appropriate.
16
+
17
+ ## Submitting a Pull Request to Suggest an Improvement
18
+
19
+ If you see an opportunity for improvement and can make the change yourself go
20
+ ahead and use a typical git workflow to make it happen:
21
+
22
+ * Fork this curriculum repository
23
+ * Make the change on your fork, with descriptive commits in the standard format
24
+ * Open a Pull Request against this repo
25
+
26
+ A curriculum owner will review your change and approve or comment on it in due
27
+ course.
28
+
29
+ ## Why Contribute?
30
+
31
+ Curriculum on Learn is publicly and freely available under Learn's
32
+ [Educational Content License](https://learn.co/content-license). By embracing an
33
+ open-source contribution model, our goal is for the curriculum on Learn to
34
+ become, in time, the best educational content the world has ever seen.
35
+
36
+ We need help from the community of Learners to maintain and improve the
37
+ educational content. Everything from fixing typos, to correcting out-dated
38
+ information, to improving exposition, to adding better examples, to fixing
39
+ tests—all contributions to making the curriculum more effective are welcome.
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ ruby "2.6.1"
6
+
7
+ gem 'require_all'
8
+ gem 'json'
9
+ gem 'redcarpet'
10
+ gem 'rest-client'
11
+ # Specify your gem's dependencies in github-to-canvas.gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,24 @@
1
+ # Learn.co Educational Content License
2
+
3
+ Copyright (c) 2020 Flatiron School, Inc
4
+
5
+ The Flatiron School, Inc. owns this Educational Content. However, the Flatiron
6
+ School supports the development and availability of educational materials in the
7
+ public domain. Therefore, the Flatiron School grants Users of the Flatiron
8
+ Educational Content set forth in this repository certain rights to reuse, build
9
+ upon and share such Educational Content subject to the terms of the Educational
10
+ Content License set forth
11
+ [here](http://learn.co/content-license)(http://learn.co/content-license). You
12
+ must read carefully the terms and conditions contained in the Educational
13
+ Content License as such terms govern access to and use of the Educational
14
+ Content.
15
+
16
+ Flatiron School is willing to allow you access to and use of the Educational
17
+ Content only on the condition that you accept all of the terms and conditions
18
+ contained in the Educational Content License set forth
19
+ [here](http://learn.co/content-license) (http://learn.co/content-license). By
20
+ accessing and/or using the Educational Content, you are agreeing to all of the
21
+ terms and conditions contained in the Educational Content License. If you do
22
+ not agree to any or all of the terms of the Educational Content License, you are
23
+ prohibited from accessing, reviewing or using in any way the Educational
24
+ Content.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # GitHub to Canvas Gem
2
+
3
+ ## Introduction
4
+
5
+ The `github-to-canvas` gem is designed to enable GitHub to Canvas LMS
6
+ integration. This gem is designed to take a GitHub repository's `README.md`
7
+ file, convert it to HTML, and push it to Canvas. The gem also updates the
8
+ repository to include a `.canvas` file containing Canvas specific information.
9
+
10
+ With the `.canvas` file in place, this gem can be used to continuously align
11
+ content between GitHub and Canvas.
12
+
13
+ This gem is built for use internally at [Flatiron School][]. Access to the
14
+ [Canvas LMS API][] and the ability to add pages and assignments to a Canvas
15
+ course are required.
16
+
17
+ ## Installation
18
+
19
+ `gem install github-to-canvas`
20
+
21
+ ## Setup
22
+
23
+ ### Generate Canvas API Key
24
+
25
+ In order to access the Canvas API, you must first generate an API key. Go to
26
+ your Canvas Account Settings and under **Approved Integrations**, create a
27
+ **New Access Token**. You will need to store this API key as an `ENV` variable
28
+ called `CANVAS_API_KEY`. Use the following command to add your new key to
29
+ `~/.zshrc`:
30
+
31
+ ```sh
32
+ echo "$(echo 'CANVAS_API_KEY=<your-new-API-key-here>' | cat - ~/.zshrc)" > ~/.zshrc
33
+ ```
34
+
35
+ > **Note:** The command above assumes you are using Zsh. Change the dotfile if
36
+ > you are using something else like Bash.
37
+
38
+ ### Add Canvas API Base Path
39
+
40
+ The exact Canvas API path is specific to where you Canvas LMS is located. For example,
41
+ Flatiron School's base path is `https://learning.flatironschool.com/api/v1`. Add this path
42
+ as an `ENV` variable like the API key. **Do not add a `/` at the end after `/api/v1`.**
43
+
44
+ ```sh
45
+ echo "$(echo 'CANVAS_API_PATH=<your-base-api-path>' | cat - ~/.zshrc)" > ~/.zshrc
46
+ ```
47
+
48
+ After both the API key and path are added to `~/.zshrc`, run `source ~/.zshrc`
49
+ to make them available in your current terminal. You can verify these variables
50
+ are present by running `ENV`.
51
+
52
+ ## Usage
53
+
54
+ To migrate a GitHub `README.md` file to Canvas, at minimum, you will need to know the
55
+ Canvas course id you are going to add to. This id can be found in the URL of the course.
56
+
57
+ 1. clone down the repository to a local folder and change directory into it.
58
+ 2. Run `github-to-canvas --create <your-course-id>`
59
+
60
+ If everything is set up properly, `github-to-canvas` will create a Canvas lesson
61
+ using `master` branch `README.md` and the name of the current folder. By
62
+ default, if the repository contains folders, an **assignment** will be created.
63
+ Otherwise, a **page** will be created.
64
+
65
+ After a successful lesson creation, `github-to-canvas` will use the API response
66
+ to build a `.canvas` YAML file. This file contains the course id, the newly created
67
+ page id, and the Canvas URL to the lesson for future reference.
68
+
69
+ ### Options
70
+
71
+ You can override the default behaviors with the following arguments:
72
+
73
+ * `--name NAME` uses the provided name instead of the repository's folder name
74
+ * `--branch BRANCH` uses the provided git branch instead of `master`
75
+ * `--type TYPE` will accept either `'page'` or `'assignment'` and create the
76
+ appropriate Canvas lesson type instead of relying on the repository's
77
+ directory structure
78
+
79
+ [Canvas LMS API]: https://canvas.instructure.com/doc/api/index.html
80
+ [Flatiron School]: https://flatironschool.com/
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'github-to-canvas'
5
+
6
+ options = {}
7
+ OptionParser.new do |opts|
8
+ opts.banner = <<-EOBANNER
9
+ GitHub To Canvas
10
+ ====================
11
+ A tool for migrating and aligning GitHub content with the Canvas LMS. Access
12
+ to the Canvas API and a GitHub org required. For configuration and setup, visit
13
+ https://github.com/learn-co-curriculum/github-to-canvas
14
+
15
+ Commands:
16
+ github-to-canvas --create COURSE
17
+ github-to-canvas --create COURSE [--branch BRANCH]
18
+ github-to-canvas --create COURSE [--branch BRANCH] [--name NAME]
19
+ github-to-canvas --create COURSE [--branch BRANCH] [--name NAME] [--type TYPE]
20
+ github-to-canvas --align
21
+ github-to-canvas --reverse-align
22
+ github-to-canvas --version
23
+
24
+ Run these commands from inside a local GitHub repository. This gem is built for Flatiron School's internal use.
25
+ Some default behaviors assume this, like the default Canvas API path.
26
+
27
+ Example usage:
28
+
29
+ github-to-canvas --create 154 -> Creates a lesson in course 154, deriving the name and type from the local repo
30
+ github-to-canvas --create 154 --name "Fetch Lab" -> Creates a lesson in course 154 with the provided name, deriving the type from the local repo
31
+ github-to-canvas --create 154 --name "Fetch Lab" --type assignment -> Creates an assignment in course 154 with the provided name
32
+ github-to-canvas --create 154 --name "Fetch Lab" --branch solution -> Creates a lesson in course 154 with the provided name, using the repositorie's solution branch and deriving the type from the local repo
33
+
34
+ EOBANNER
35
+
36
+ opts.on("-cCOURSE", "--create COURSE",
37
+ "Creates a new canvas lesson, converting the local repository's README.md to HTML. Adds .canvas file to remote repository") do |course|
38
+ options[:create] = true
39
+ options[:course] = course
40
+ end
41
+ opts.on("-bBRANCH", "--branch BRANCH",
42
+ "Sets the repository branch used for lesson creation") do |branch|
43
+ options[:branch] = branch
44
+ end
45
+ opts.on("-nNAME", "--name NAME",
46
+ "Sets the name of the new Canvas lesson to be created. If no name is given, repository folder name is used") do |name|
47
+ options[:name] = name
48
+ end
49
+ opts.on("-tTYPE", "--type TYPE",
50
+ "Sets the type Canvas lesson to be created (page or assignment). If no type, type decided based on repository structure") do |type|
51
+ if t == 'page' || t == 'assignment'
52
+ options[:type] = type
53
+ else
54
+ puts "Invalid type. Defaulting to page"
55
+ options[:type] = "page"
56
+ end
57
+ end
58
+ opts.on("-a", "--align",
59
+ "Updates a canvas lesson based on the local repository's README.md") do |a|
60
+ options[:align] = true
61
+ end
62
+ opts.on("-r", "--reverse-align",
63
+ "Updates a remote repository, converting the Canvas lesson body to markdown and pushing it remotely as the README.md") do |r|
64
+ options[:reverse_align] = true
65
+ end
66
+ opts.on("-v", "--version",
67
+ "Displays current gem version") do |v|
68
+ options[:version] = true
69
+ end
70
+
71
+ end.parse!
72
+
73
+ if options[:version]
74
+ GithubToCanvas.new(mode: 'version', course: nil)
75
+ end
76
+
77
+ if Dir.entries(Dir.pwd).select {|entry| File.directory? entry and !(entry =='.' || entry == '..')}.empty?
78
+ options[:type] = "page"
79
+ else
80
+ options[:type] = "assignment"
81
+ end
82
+
83
+ if !options[:branch]
84
+ options[:branch] = 'master'
85
+ end
86
+
87
+ if !options[:name]
88
+ options[:name] = File.basename(Dir.getwd)
89
+ end
90
+
91
+ if options[:create]
92
+ GithubToCanvas.new(mode: "create", course: options[:course], filepath: Dir.pwd, branch: options[:branch], name: options[:name], type: options[:type])
93
+ end
94
+
95
+ if options[:align]
96
+ puts 'feature not working yet'
97
+ end
98
+
99
+ if options[:reverse_align]
100
+ puts 'feature not working yet'
101
+ end
@@ -0,0 +1,18 @@
1
+ require_relative './github-to-canvas/create-canvas-lesson'
2
+ require_relative './github-to-canvas/version'
3
+
4
+ class GithubToCanvas
5
+
6
+ def initialize(mode:, course:, filepath:Dir.pwd, branch:'master', name:File.basename(Dir.getwd), type:"page")
7
+ if mode == 'version'
8
+ puts VERSION
9
+ return
10
+ end
11
+
12
+ if mode == 'create'
13
+ puts "github-to-canvas will now create a Canvas lesson based on the current repo"
14
+ CreateCanvasLesson.new(course, filepath, branch, name, type)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,156 @@
1
+ require 'redcarpet'
2
+ require 'rest-client'
3
+ require 'json'
4
+ require 'yaml'
5
+ require 'byebug'
6
+
7
+ class CreateCanvasLesson
8
+
9
+ def initialize(course, filepath, branch, name, type)
10
+ @course = course
11
+ @filepath = filepath
12
+ @branch = branch
13
+ @name = name.split(/[ -]/).map(&:capitalize).join(' ')
14
+ @type = type
15
+ @renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options={tables: true, autolink: true, fenced_code_blocks: true})
16
+ @original_readme = File.read("#{filepath}/README.md")
17
+ if !@original_readme
18
+ puts 'README.md not found in current directory. Exiting...'
19
+ abort
20
+ end
21
+ create_canvas_lesson
22
+ end
23
+
24
+ def create_canvas_lesson
25
+ git_co_branch
26
+ git_pull
27
+ @raw_remote_url = set_raw_image_remote_url
28
+ adjust_local_markdown_images
29
+ adjust_local_html_images
30
+ @new_readme = @renderer.render(@original_readme)
31
+ write_to_html
32
+ @response = push_to_canvas
33
+ if @response.code != 200
34
+ puts "Canvas push failed. #{@response.code} status code returned "
35
+ end
36
+ @response = JSON.parse(@response.body)
37
+ create_canvas_dotfile
38
+ commit_canvas_dotfile
39
+ git_push
40
+ end
41
+
42
+ def cd_into_and(command)
43
+ cmd = "cd #{@filepath} && #{command}"
44
+ puts cmd
45
+ `#{cmd}`
46
+ end
47
+
48
+ def git_co_branch
49
+ cmd = "git co #{@branch}"
50
+ branch = cd_into_and(cmd)
51
+ if branch.to_s.strip.empty?
52
+ puts "#{b@ranch} branch not found. Exiting..."
53
+ abort
54
+ end
55
+ end
56
+
57
+ def git_pull
58
+ if @branch != 'master'
59
+ cmd = "git pull #{@branch}"
60
+ else
61
+ cmd = "git pull"
62
+ end
63
+ puts "git pulling latest version of #{@branch}"
64
+ cd_into_and(cmd)
65
+ end
66
+
67
+ def git_remote
68
+ cmd = "git config --get remote.origin.url"
69
+ cd_into_and(cmd)
70
+ end
71
+
72
+ def git_add(file)
73
+ cmd = "git add #{file}"
74
+ puts "git adding #{file}"
75
+ cd_into_and(cmd)
76
+ end
77
+
78
+ def git_commit(message)
79
+ cmd = "git commit -m '#{message}'"
80
+ puts "git commit: '#{message}'"
81
+ cd_into_and(cmd)
82
+ end
83
+
84
+ def git_push
85
+ cmd = "git push"
86
+ puts "git pushing #{@branch}"
87
+ cd_into_and(cmd)
88
+ end
89
+
90
+ def set_raw_image_remote_url
91
+ remote = git_remote
92
+ remote.gsub!("git@github.com:","https://raw.githubusercontent.com/")
93
+ remote.gsub!(/.git$/,"")
94
+ remote.strip!
95
+ end
96
+
97
+ def adjust_local_markdown_images
98
+ @original_readme.gsub!(/\!\[.+\]\(.+\)/) {|image|
99
+ if !image.match('amazonaws.com') && !image.match('https://')
100
+ image.gsub!(/\(.+\)/) { |path|
101
+ path.delete_prefix!("(")
102
+ path.delete_suffix!(")")
103
+ "(" + remote + "/#{@branch}/" + path + ")"
104
+ }
105
+ end
106
+ image
107
+ }
108
+ end
109
+
110
+ def adjust_local_html_images
111
+ @original_readme.gsub!(/src=\"[\s\S]*?" /) { |img|
112
+ img.gsub!(/\"/, "")
113
+ img.gsub!(/src=/, '')
114
+ img.strip!
115
+ 'src="' + @raw_remote_url + '/master/' + img + '"'
116
+ }
117
+ end
118
+
119
+ def write_to_html
120
+ File.write("#{@filepath}/README.html", @new_readme)
121
+ end
122
+
123
+ def push_to_canvas
124
+ url = "#{ENV['CANVAS_API_PATH']}/courses/#{@course}/#{@type}s"
125
+ if @type == "assignment"
126
+ payload = {
127
+ 'assignment[name]' => @name,
128
+ 'assignment[description]' => @new_readme
129
+ }
130
+ else
131
+ payload = {
132
+ 'wiki_page[title]' => @name,
133
+ 'wiki_page[body]' => @new_readme,
134
+ 'wiki_page[editing_roles]' => "teachers"
135
+ }
136
+ end
137
+
138
+ RestClient.post(url, payload, headers={
139
+ "Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
140
+ })
141
+ end
142
+
143
+ def create_canvas_dotfile
144
+ canvas_data = {
145
+ page_id: @response['page_id'],
146
+ course_id: @course.to_i,
147
+ canvas_url: @response['html_url']
148
+ }
149
+ File.write("#{@filepath}/.canvas", canvas_data.to_yaml)
150
+ end
151
+
152
+ def commit_canvas_dotfile
153
+ git_add('.canvas')
154
+ git_commit('AUTO: add .canvas file after migration')
155
+ end
156
+ end
@@ -0,0 +1,3 @@
1
+ class LearnTool
2
+ VERSION = "0.0.8"
3
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github-to-canvas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - maxwellbenton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.15'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redcarpet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.3'
69
+ description:
70
+ email: maxwell@flatironschool.com
71
+ executables:
72
+ - github-to-canvas
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - CONTRIBUTING.md
77
+ - Gemfile
78
+ - LICENSE.md
79
+ - README.md
80
+ - Rakefile
81
+ - bin/github-to-canvas
82
+ - lib/github-to-canvas.rb
83
+ - lib/github-to-canvas/create-canvas-lesson.rb
84
+ - lib/github-to-canvas/version.rb
85
+ homepage: https://github.com/learn-co-curriculum/github-to-canvas
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 3.0.8
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: github-to-canvas is a tool for migrating and aligning GitHub content with
108
+ the Canvas LMS
109
+ test_files: []