d2l_api 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,172 @@
1
+ require_relative 'requests'
2
+ require 'thread'
3
+
4
+ ########################
5
+ # USERS:################
6
+ ########################
7
+ # Creates the user using user_data as an argument.
8
+ # A Hash is merged with the user_data. The data types for each Hash key is
9
+ # specified below. For the ExternalEmail, there must be either nil for the value
10
+ # or a WELL FORMED email address. The username must be unique, meaning no other
11
+ # user has that name. All of the rest can remain the same, assuming roleId 110
12
+ # exists in your system.
13
+ def create_user_data(user_data)
14
+ # Define a valid, empty payload and merge! with the user_data. Print it.
15
+ payload = { 'OrgDefinedId' => '', # String
16
+ 'FirstName' => 'TestUser', # String
17
+ 'MiddleName' => 'Test', # String
18
+ 'LastName' => 'Test', # String
19
+ 'ExternalEmail' => nil, # String (nil or well-formed email addr)
20
+ 'UserName' => 'test12345a', # String
21
+ 'RoleId' => 110, # number
22
+ 'IsActive' => false, # bool
23
+ 'SendCreationEmail' => false, # bool
24
+ }.merge!(user_data)
25
+ #ap payload
26
+ # Define a path referencing the course data using the course_id
27
+ path = "/d2l/api/lp/#{$version}/users/"
28
+ _post(path, payload)
29
+ puts '[+] User creation completed successfully'.green
30
+ end
31
+
32
+ #Retrieves the whoami of the user authenticated through the config file.
33
+ #returns: JSON whoami response
34
+ def get_whoami
35
+ path = "/d2l/api/lp/#{$version}/users/whoami"
36
+ _get(path)
37
+ end
38
+
39
+ # Retrieves a user based upon an explicitly defined username.
40
+ # Returns: JSON response of this user.
41
+ def get_user_by_username(username)
42
+ path = "/d2l/api/lp/#{$version}/users/?userName=#{username}"
43
+ _get(path)
44
+ end
45
+
46
+ # Uses a min and max to create a range.
47
+ # returns: range obj
48
+ def create_range(min, max)
49
+ (min..max)
50
+ end
51
+
52
+ # Checks whether a username already exists
53
+ # returns: true if the the user exists already
54
+ def does_user_exist(username)
55
+ if get_user_by_username(username.to_s) != nil
56
+ return true
57
+ else
58
+ return false
59
+ end
60
+ end
61
+
62
+ # Initiates a multithreaded search to streamline the search of a user based upon
63
+ # a part of their search str. This calls +get_user_by_string+, which is actually
64
+ # using a bookmarked search. This brings the search time down from 15+ minutes
65
+ # to only ~10-13 seconds, depending upon the computer. This can be sped up MUCH
66
+ # more by using a computer with more cores. Anyways, based upon the number of
67
+ # threads used, iterations are performed, specifying certain ranges for each
68
+ # thread to search by using +get_user_by_string+. Upon all of the threads
69
+ # joining, the thread_results are returned (as they are all the matching names)
70
+ #
71
+ # returns: Array::param_values_with_string_included
72
+ def multithreaded_user_search(parameter, search_string, num_of_threads)
73
+ # Assumed: there is only up to 60,000 users.
74
+ # Start from 1, go up to max number of users for this search...
75
+ max_users = 60_000
76
+ range_min = 1
77
+ # range max = the upper limit for the search for a thread
78
+ range_max = max_users / num_of_threads + 1
79
+ threads = []
80
+ thread_results = []
81
+ #ap "creating #{num_of_threads} threads..."
82
+ # from 0 up until max number of threads..
83
+ (0...num_of_threads - 1).each do |iteration|
84
+ # setup range limits for the specific thread
85
+ min = range_min + range_max * iteration
86
+ max = range_max + (range_max - 1) * iteration
87
+ range = create_range(min, max)
88
+ # push thread to threads arr and start thread search of specified range.
89
+ threads[iteration] = Thread.new do
90
+ get_user_by_string(parameter, search_string, range).each do |match|
91
+ thread_results.push(match)
92
+ end
93
+ end
94
+ end
95
+ # Join all of the threads
96
+ threads.each(&:join)
97
+ puts "returning search results for #{parameter}::#{search_string}"
98
+ # Return an array of users that exist with the search_string in the param.
99
+ thread_results
100
+ end
101
+
102
+ # get_user_by_string uses arguments search_string and range. To use these,
103
+ # a range is created, an array of matching names is initialized, and then
104
+ # the entire range is iterated to check for names that have the search_string
105
+ # in them. Upon reaching a page that has an empty items JSON array, the search
106
+ # ends. This is due to the fact that pages with zero items will not have any
107
+ # more users past them. The array of matching names is then returned.
108
+ #
109
+ # returns: array::matching_names
110
+ def get_user_by_string(parameter, search_string, range)
111
+ # puts "searching from #{range.min.to_s} to #{range.max.to_s}"
112
+ i = range.min
113
+ matching_names = []
114
+ # Average difference between each paged bookmarks beginnings is 109.6
115
+ while i.to_i < range.max
116
+ path = "/d2l/api/lp/#{$version}/users/?bookmark=" + i.to_s
117
+ response = _get(path)
118
+ if response['PagingInfo']["HasMoreItems"] == false
119
+ #ap 'response returned zero items, last page possible for this thread..'
120
+ return matching_names
121
+ end
122
+ response['Items'].each do |user|
123
+ matching_names.push(user) if user[parameter].include? search_string
124
+ end
125
+ i = response['PagingInfo']['Bookmark']
126
+ end
127
+ matching_names
128
+ end
129
+
130
+ # Retrieves a user based upon an explicitly pre-defined user_id. This is also
131
+ # known as the Identifier of this user object. Upon retrieving the user, it
132
+ # is then returned.
133
+ #
134
+ # returns: JSON user object.
135
+ def get_user_by_user_id(user_id)
136
+ path = "/d2l/api/lp/#{$version}/users/" + user_id.to_s
137
+ _get(path)
138
+ end
139
+
140
+ # Updates the user's data (identified by user_id)
141
+ # By merging input, named new_data, with a payload, the user_data is guarenteed
142
+ # to at least be formatted correctly. The data, itself, depends upon the api
143
+ # user. Once this is merged, a put http method is utilized to update the user
144
+ # data.
145
+ def update_user_data(user_id, new_data)
146
+ # Define a valid, empty payload and merge! with the user_data. Print it.
147
+ payload = {
148
+ 'OrgDefinedId' => '',
149
+ 'FirstName' => '',
150
+ 'MiddleName' => '',
151
+ 'LastName' => '',
152
+ 'ExternalEmail' => nil, # Predefines user data, in the case that
153
+ 'UserName' => '', # there is are variables left out in the JSON
154
+ 'Activation' => {
155
+ 'IsActive' => false
156
+ }
157
+ }.merge!(new_data)
158
+ # Define a path referencing the user data using the user_id
159
+ path = "/d2l/api/lp/#{$version}/users/" + user_id.to_s
160
+ _put(path, payload)
161
+ puts '[+] User data updated successfully'.green
162
+ end
163
+
164
+ # Deletes the user's data (identified by user_id). By forming a path that is
165
+ # correctly referencing this user's data, a delete http method is executed and
166
+ # effectively deleted the user that is referenced.
167
+ def delete_user_data(user_id)
168
+ # Define a path referencing the user data using the user_id
169
+ path = "/d2l/api/lp/#{$version}/users/" + user_id.to_s # setup user path
170
+ _delete(path)
171
+ puts '[+] User data deleted successfully'.green
172
+ end
@@ -0,0 +1,3 @@
1
+ module D2lApi
2
+ VERSION = "0.1.2"
3
+ end
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: d2l_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kulpa
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: awesome_print
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rest-client
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: colorize
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.8'
111
+ - !ruby/object:Gem::Dependency
112
+ name: test-unit
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.1'
125
+ description: Simple Ruby Gem to utilize the Valence/D2L API; requires config file
126
+ to have variables declared.
127
+ email:
128
+ - AJ-Kulpa@wiu.edu
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".DS_Store"
134
+ - ".gitignore"
135
+ - ".rspec"
136
+ - ".travis.yml"
137
+ - CODE_OF_CONDUCT.md
138
+ - Gemfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - bin/.DS_Store
143
+ - bin/console
144
+ - bin/setup
145
+ - d2l_api.gemspec
146
+ - lib/.DS_Store
147
+ - lib/d2l_api.rb
148
+ - lib/d2l_api/.DS_Store
149
+ - lib/d2l_api/auth.rb
150
+ - lib/d2l_api/config.rb
151
+ - lib/d2l_api/course.rb
152
+ - lib/d2l_api/course_template.rb
153
+ - lib/d2l_api/org_unit.rb
154
+ - lib/d2l_api/requests.rb
155
+ - lib/d2l_api/semester.rb
156
+ - lib/d2l_api/user.rb
157
+ - lib/d2l_api/version.rb
158
+ homepage: https://gitlab.wiu.edu/ajk142/valence_testing
159
+ licenses:
160
+ - MIT
161
+ metadata: {}
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 2.6.8
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: Simple Ruby Gem to utilize the Valence/D2L API
182
+ test_files: []