d2l_api 0.1.2

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
+ SHA1:
3
+ metadata.gz: 1de2bfe9ffb6a22f36b4ab86aa45e0244d38e10d
4
+ data.tar.gz: eb4bddaade69d7b4ef357affabf8629e4c8275ca
5
+ SHA512:
6
+ metadata.gz: b842d840a58a867170cdad938172d13f54f6f8e08a2478c009c27ccf49bd79e5099894c866e533724d8d4aab225139bff2a9c597fb07824947f6264280afd59f
7
+ data.tar.gz: 2a83647632c0e11a5f08f1b5a0b8a8ae4fdd313a8f83c3bb438c8715535eeea9972b24d03047f4f17c621123f0f36a67e7283c88b6c4d57c00c65d2b9f2dcd33
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.13.6
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at AJ-Kulpa@wiu.edu. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in d2l_api.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Andrew Kulpa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # D2lApi
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/d2l_api`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'd2l_api'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install d2l_api
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/d2l_api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
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
data/bin/.DS_Store ADDED
Binary file
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "d2l_api"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/d2l_api.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'd2l_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "d2l_api"
8
+ spec.version = D2lApi::VERSION
9
+ spec.authors = ["Andrew Kulpa"]
10
+ spec.email = ["AJ-Kulpa@wiu.edu"]
11
+
12
+ spec.summary = %q{Simple Ruby Gem to utilize the Valence/D2L API}
13
+ spec.description = %q{Simple Ruby Gem to utilize the Valence/D2L API; requires config file to have variables declared.}
14
+ spec.homepage = "https://gitlab.wiu.edu/ajk142/valence_testing"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ #if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against " \
23
+ # "public gem pushes."
24
+ # end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.13"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "awesome_print", "~> 0.1"
37
+ spec.add_development_dependency "rest-client", "~> 2.0"
38
+ spec.add_development_dependency "json", "~> 1.8"
39
+ spec.add_development_dependency "colorize", "~> 0.8"
40
+ spec.add_development_dependency "test-unit", "~> 3.1"
41
+ end
data/lib/.DS_Store ADDED
Binary file
data/lib/d2l_api.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "d2l_api/version"
2
+ require_relative 'd2l_api/course_template'
3
+ require_relative 'd2l_api/course'
4
+ require_relative 'd2l_api/org_unit'
5
+ require_relative 'd2l_api/semester'
6
+ require_relative 'd2l_api/user'
7
+
8
+
9
+ module D2lApi
10
+ puts "d2l_api loaded"
11
+ end
Binary file
@@ -0,0 +1,84 @@
1
+ require 'rubygems' # useful
2
+ require 'awesome_print' # useful for debugging
3
+ require 'base64' # NEEDED
4
+ require 'json' # NEEDED
5
+ require 'restclient' # NEEDED
6
+ require 'openssl' # NEEDED
7
+ require 'open-uri' # NEEDED
8
+ require 'colorize' # useful
9
+ require_relative 'config'
10
+
11
+ # Global variables initialized through require_relative 'D2L_Config'
12
+
13
+ # requests input from the user, cuts off any new line and downcases it.
14
+ #
15
+ # returns: String::downcased_user_input
16
+ def prompt(*args)
17
+ print(*args)
18
+ gets.chomp.downcase
19
+ end
20
+
21
+ # Creates an authenticated uniform resource identifier that works with Valence
22
+ # by calling +URI.parse+ using the path downcased, then creating a query string
23
+ # by calling +_get_string+ with the parsed_url and the http_method. These are
24
+ # used as the Variables and then returned as the finished uri.
25
+ #
26
+ # Input that is required is:
27
+ # * path: The path to the resource you are trying to accessing
28
+ # * http_method: The method utilized to access/modify the resource
29
+ #
30
+ # returns: String::uri
31
+ def create_authenticated_uri(path, http_method)
32
+ parsed_url = URI.parse(path.downcase)
33
+ uri_scheme = 'https'
34
+ query_string = _get_string(parsed_url.path, http_method)
35
+ uri = uri_scheme + '://' + $hostname + parsed_url.path + query_string
36
+ uri << '&' + parsed_url.query if parsed_url.query
37
+ uri
38
+ end
39
+
40
+ # Builds an authenticated uniform resource identifier query string that
41
+ # works properly with the Valence API.
42
+ #
43
+ # Required Variables:
44
+ # * app_id, user_id, app_key, user_key
45
+ #
46
+ # returns: String::'authenticated_uri'
47
+ def build_authenticated_uri_query_string(signature, timestamp)
48
+ "?x_a=#{$app_id}"\
49
+ "&x_b=#{$user_id}"\
50
+ "&x_c=#{get_base64_hash_string($app_key, signature)}"\
51
+ "&x_d=#{get_base64_hash_string($user_key, signature)}"\
52
+ "&x_t=#{timestamp}"
53
+ end
54
+
55
+ # uses the path, http_method, and timestamp arguments to create a properly
56
+ # formatted signature. Then, this is returned.
57
+ #
58
+ # returns: String::signature
59
+ def format_signature(path, http_method, timestamp)
60
+ http_method.upcase + '&' + path.encode('UTF-8') + '&' + timestamp.to_s
61
+ end
62
+
63
+ # uses the key and signature as arguments to create a hash using
64
+ # +OpenSSL::HMAC.digest+ with an additional argument denoting the hashing
65
+ # algorithm as 'sha256'. The hash is then encoded properly and all "="
66
+ # are deleted to officially create a base64 hash string.
67
+ #
68
+ # returns: String::base64_hash_string
69
+ def get_base64_hash_string(key, signature)
70
+ hash = OpenSSL::HMAC.digest('sha256', key, signature)
71
+ Base64.urlsafe_encode64(hash).delete('=')
72
+ end
73
+
74
+ # Used as a helper method for create_authenticated_uri in order to properly
75
+ # create a query string that will (hopefully) work with the Valence API.
76
+ # the arguments path and http_method are used as arguments with the current time
77
+ # for +format_signature+ and +build_authenticated_uri_query_string+.
78
+ #
79
+ # returns: String::query_string
80
+ def _get_string(path, http_method)
81
+ timestamp = Time.now.to_i
82
+ signature = format_signature(path, http_method, timestamp)
83
+ build_authenticated_uri_query_string(signature, timestamp)
84
+ end
@@ -0,0 +1,11 @@
1
+
2
+ #This is the host address to the test / production server
3
+ $hostname = '' # set hostname to the test server
4
+ # user_id and user_key are used to recognize this specific user account
5
+ $user_id = ''
6
+ $user_key = ''
7
+ # #App_id and App_key are two other required variables for this to work
8
+ $app_id = ''
9
+ $app_key = ''
10
+ # The version is specific to your environment. This ruby api was created for 1.4
11
+ $version = 1.4
@@ -0,0 +1,109 @@
1
+ require_relative 'requests'
2
+ ########################
3
+ # COURSES:##############
4
+ ########################
5
+
6
+ # Creates the course based upon a merged result of the argument course_data
7
+ # and a preformatted payload. This is then passed as a new payload in the
8
+ # +_post+ method in order to create the defined course.
9
+ # Required: "Name", "Code"
10
+ # Creates the course offering
11
+ def create_course_data(course_data)
12
+ # ForceLocale- course override the user’s locale preference
13
+ # Path- root path to use for this course offering’s course content
14
+ # if your back-end service has path enforcement set on for
15
+ # new org units, leave this property as an empty string
16
+ # Define a valid, empty payload and merge! with the user_data. Print it.
17
+ payload = { 'Name' => '', # String
18
+ 'Code' => 'off_SEMESTERCODE_STARNUM', # String
19
+ 'Path' => '', # String
20
+ 'CourseTemplateId' => 99_989, # number: D2L_ID
21
+ 'SemesterId' => nil, # number: D2L_ID | nil
22
+ 'StartDate' => nil, # String: UTCDateTime | nil
23
+ 'EndDate' => nil, # String: UTCDateTime | nil
24
+ 'LocaleId' => nil, # number: D2L_ID | nil
25
+ 'ForceLocale' => false, # bool
26
+ 'ShowAddressBook' => false # bool
27
+ }.merge!(course_data)
28
+ #ap payload
29
+ path = "/d2l/api/lp/#{$version}/courses/"
30
+ _post(path, payload)
31
+ puts '[+] Course creation completed successfully'.green
32
+ end
33
+
34
+ # In order to retrieve an entire department's class list, this method uses a
35
+ # predefined org_unit identifier. This identifier is then appended to a path
36
+ # and all classes withiin the department are returned as JSON objects in an arr.
37
+ #
38
+ # returns: JSON array of classes.
39
+ def get_org_department_classes(org_unit_id)
40
+ path = "/d2l/api/lp/#{$version}/orgstructure/" + org_unit_id
41
+ _get(path)
42
+ end
43
+
44
+ def get_course_by_id(org_unit_id)
45
+ path = "/d2l/api/lp/#{$version}/courses/#{org_unit_id}"
46
+ _get(path)
47
+ end
48
+ # Retrieves all courses that have a particular string (org_unit_name) within
49
+ # their names. This is done by first defining that none are found yet and then
50
+ # searching through all course for ones that do have a particular string within
51
+ # their name, the matches are pushed into the previously empty array of matches.
52
+ # This array is subsequently returned; if none were found, a message is returned
53
+ #
54
+ # returns: JSON array of matching course data objects
55
+ def get_courses_by_name(org_unit_name)
56
+ get_courses_by_property_by_string("Name", org_unit_name)
57
+ end
58
+
59
+ def get_courses_by_property_by_string(property, search_string)
60
+ class_not_found = true
61
+ puts "[+] Searching for courses using search string: #{search_string}".yellow +
62
+ + " -- And property: #{property}"
63
+ courses_results = []
64
+ path = "/d2l/api/lp/#{$version}/orgstructure/6606/descendants/?ouTypeId=3"
65
+ results = _get(path)
66
+ results.each do |x|
67
+ if x[property].downcase.include? search_string.downcase
68
+ class_not_found = false
69
+ courses_results.push(x)
70
+ end
71
+ end
72
+ if class_not_found
73
+ puts '[-] No courses could be found based upon the search string.'.yellow
74
+ end
75
+ courses_results
76
+ end
77
+
78
+ # Update the course based upon the first argument. This course object is first
79
+ # referenced via the first argument and its data formatted via merging it with
80
+ # a predefined payload. Then, a PUT http method is executed using the new
81
+ # payload.
82
+ # Utilize the second argument and perform a PUT action to replace the old data
83
+ def update_course_data(course_id, new_data)
84
+ # Define a valid, empty payload and merge! with the new data.
85
+ payload = { 'Name' => '', # String
86
+ 'Code' => 'off_SEMESTERCODE_STARNUM', # String
87
+ 'StartDate' => nil, # String: UTCDateTime | nil
88
+ 'EndDate' => nil, # String: UTCDateTime | nil
89
+ 'IsActive' => false # bool
90
+ }.merge!(new_data)
91
+ #ap payload
92
+ # Define a path referencing the courses path
93
+ path = "/d2l/api/lp/#{$version}/courses/" + course_id.to_s
94
+ _put(path, payload)
95
+ puts '[+] Course update completed successfully'.green
96
+ # Define a path referencing the course data using the course_id
97
+ # Perform the put action that replaces the old data
98
+ # Provide feedback that the update was successful
99
+ end
100
+
101
+ # Deletes a course based, referencing it via its org_unit_id
102
+ # This reference is created through a formatted path appended with the id.
103
+ # Then, a delete http method is executed using this path, deleting the course.
104
+ def delete_course_by_id(org_unit_id)
105
+ path = "/d2l/api/lp/#{$version}/courses/#{org_unit_id}" # setup user path
106
+ ap path
107
+ _delete(path)
108
+ puts '[+] Course data deleted successfully'.green
109
+ end