d2l_api 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []