d2l_sdk 0.1.8 → 0.1.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a6e8ed075f1d0e73100f4d1da16fd39626b49b3
4
- data.tar.gz: 7fa70c1917e6c0a4aeb4f9cb853df0e68da0689e
3
+ metadata.gz: 88964b8ade0908b80eda0463f78cc82a18ca4c6a
4
+ data.tar.gz: 855c097579e67071038f779cee78e7b82daafddb
5
5
  SHA512:
6
- metadata.gz: 81d1fe998f56240a5af90ab20402589278ddce187048b09c16ce87454550c262e4959b1dd4d5fcec9ce6ab73d0bce65b0aa5fc468e30065866368d65b2121027
7
- data.tar.gz: 499ce6508d9320c0c3daeb4f641dee939e30dd41ebf4ff1cb811798227764357016364952e0b28930275b854d56d8e882f14a54bb5d4e4f23db9a05e26580d79
6
+ metadata.gz: f7c1ccbd845a45c2f51680e603309f5b9a72f0572b32213c6a2350012fa29331f9fed7708ea494b73df3bd356472489522b7275d06f26d863afd4006e5c0ef0d
7
+ data.tar.gz: d8476be7c9e325f11421bb91ff2cb11f1fe4622c11f026c93f5b94ece96020cf08694f30fc12f9ef2368c10ec6b3bf216a0ca8838f751d57fe9b9cebe1cc1ffd
@@ -1,16 +1,18 @@
1
- require_relative 'd2l_sdk/course_template'
2
- require_relative 'd2l_sdk/course'
3
- require_relative 'd2l_sdk/datahub'
4
- require_relative 'd2l_sdk/enroll'
5
- require_relative 'd2l_sdk/group'
6
- require_relative 'd2l_sdk/org_unit'
7
- require_relative 'd2l_sdk/section'
8
- require_relative 'd2l_sdk/semester'
9
- require_relative 'd2l_sdk/user'
10
- require_relative 'd2l_sdk/config_variables'
11
- require_relative 'd2l_sdk/demographics'
12
- require_relative 'd2l_sdk/logging'
13
- require_relative 'd2l_sdk/course_content'
14
-
1
+ require_relative 'd2l_sdk/setup_versions' # Checked
2
+ require_relative 'd2l_sdk/course_template' # Checked
3
+ require_relative 'd2l_sdk/course' # Checked
4
+ require_relative 'd2l_sdk/datahub' # Checked
5
+ require_relative 'd2l_sdk/enroll' # Checked
6
+ require_relative 'd2l_sdk/group' # Checked
7
+ require_relative 'd2l_sdk/org_unit' # Checked
8
+ require_relative 'd2l_sdk/section' # Checked
9
+ require_relative 'd2l_sdk/semester' # Checked
10
+ require_relative 'd2l_sdk/user' # Checked
11
+ require_relative 'd2l_sdk/config_variables' # Checked
12
+ require_relative 'd2l_sdk/demographics' # Checked
13
+ require_relative 'd2l_sdk/logging' # Checked
14
+ require_relative 'd2l_sdk/course_content' # Checked
15
+ require_relative 'd2l_sdk/grades' # Checked -- added 3/21
16
+ require_relative 'd2l_sdk/news' # Checked -- added 3/21
15
17
 
16
18
  puts "d2l_sdk loaded"
@@ -2,7 +2,7 @@ require 'rubygems' # useful
2
2
  require 'awesome_print' # useful for debugging
3
3
  require 'base64' # NEEDED
4
4
  require 'json' # NEEDED
5
- require 'restclient' # NEEDED
5
+ require 'rest-client' # NEEDED
6
6
  require 'openssl' # NEEDED
7
7
  require 'open-uri' # NEEDED
8
8
  require 'colorize' # useful
@@ -1,26 +1,37 @@
1
1
  require_relative 'auth'
2
2
 
3
+
4
+ @debug = false
5
+
3
6
  ########################
4
- # CONFIG VARIABLES:#####
7
+ # DEFINITIONS:##########
5
8
  ########################
6
- @debug = false
9
+ # NOTE: These provide access to the definition meta-data
10
+ # surrounding configuration variables.
7
11
 
8
- #Retrieve the definitions for all the configuration variables the user has access to view.
12
+ # Retrieve the definitions for all the configuration variables the
13
+ # user has access to view.
9
14
  def get_all_config_var_definitions(search='', bookmark='')
10
15
  path = "/d2l/api/lp/#{$lp_ver}/configVariables/definitions/"
11
16
  path += "?search=#{search}" if search != ''
12
17
  path += "?bookmark=#{bookmark}" if bookmark != ''
13
18
  _get(path)
14
- #returns paged result set of Definition JSON data blocks
19
+ # returns paged result set of Definition JSON data blocks
15
20
  end
16
21
 
17
- #Retrieve the definitions for a configuration variable.
22
+ # Retrieve the definitions for a configuration variable.
18
23
  def get_config_var_definitions(variable_id)
19
24
  path = "/d2l/api/lp/#{$lp_ver}/configVariables/(#{variable_id}/definition"
20
25
  _get(path)
21
26
  # returns Definition JSON data block
22
27
  end
23
28
 
29
+ ########################
30
+ # VALUES:###############
31
+ ########################
32
+ # NOTE: These provide access to the values assigned to configuration
33
+ # variables in the running back-end service.
34
+
24
35
  #Retrieve the value summary for a configuration variable.
25
36
  def get_config_var_values(variable_id)
26
37
  path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/values"
@@ -50,6 +61,7 @@ def get_config_var_org_unit_override_value(variable_id, org_unit_id)
50
61
  # returns OrgUnitValue JSON block
51
62
  end
52
63
 
64
+ # NOTE: UNSTABLE!!!
53
65
  # Retrieve the effective value for a configuration variable within an org unit.
54
66
  def get_config_var_org_unit_effective_value(variable_id, org_unit_id)
55
67
  path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/effectiveValues/orgUnits/#{org_unit_id}"
@@ -75,7 +87,71 @@ def get_config_var_system_value(variable_id)
75
87
  _get(path)
76
88
  end
77
89
 
90
+ # REVIEW: Set a new org value for a configuration variable.
91
+ def set_config_var_org_value(variable_id, org_value)
92
+ path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/values/org"
93
+ if org_value.is_a? String || org_value.nil?
94
+ payload = {"OrgValue" => org_value}
95
+ _put(path, payload)
96
+ else
97
+ raise ArgumentError, "Argument 'org_value' is not a String or nil"
98
+ end
99
+ end
100
+
101
+ # REVIEW: Set a new org unit override value for a configuration variable.
102
+ def set_config_var_override_value(variable_id, org_unit_id, org_unit_value)
103
+ path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/values/orgUnits/#{org_unit_id}"
104
+ if org_unit_value.is_a? String || org_unit_value.nil?
105
+ payload = {"OrgUnitValue" => org_unit_value}
106
+ _put(path, payload)
107
+ else
108
+ raise ArgumentError, "Argument 'org_unit_value' is not a String or nil"
109
+ end
110
+ end
111
+
112
+ # REVIEW: Set a new role override value for a configuration variable.
113
+ def set_config_var_role_value(variable_id, role_id, role_value)
114
+ path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/values/roles/#{role_id}"
115
+ if role_value.is_a? String || role_value.nil?
116
+ payload = {"RoleValue" => role_value}
117
+ _put(path, payload)
118
+ else
119
+ raise ArgumentError, "Argument 'role_value' is not a String or nil"
120
+ end
121
+ end
122
+
123
+ # REVIEW: Set a new system value for a configuration variable.
124
+ def set_config_var_system_value(variable_id, system_value)
125
+ path = "/d2l/api/lp/#{$lp_ver}/configVariables/#{variable_id}/values/system"
126
+ if system_value.is_a?(String) || system_value.nil?
127
+ payload = {"SystemValue" => system_value}
128
+ _put(path, payload)
129
+ else
130
+ raise ArgumentError, "Argument 'system_value' is not a String or nil"
131
+ end
132
+ end
133
+
134
+ ########################
135
+ # RESOLVER:#############
136
+ ########################
137
+ # NOTE: These provide a way to manage a configuration variable’s
138
+ # resolution strategy.
139
+
140
+ # NOTE: UNSTABLE!!!
141
+ # TODO: UNSTABLE!!! --Restore the default resolution strategy for an org unit configuration variable.
142
+ def restore_default_org_unit_config_var_resolution(variable_id)
143
+ # DELETE /d2l/api/lp/(version)/configVariables/(variableId)/resolver
144
+ end
145
+
146
+ # NOTE: UNSTABLE!!!
147
+ # REVIEW: Retrieve the resolution strategy for an org unit configuration variable.
78
148
  def get_config_var_resolver(variable_id)
79
149
  path = "/d2l/api/lp/#{lp_ver}/configVariables/#{variable_id}/resolver"
80
150
  _get(path)
81
151
  end
152
+
153
+ # NOTE: UNSTABLE!!!
154
+ # TODO: Update the resolution strategy for an org unit configuration variable.
155
+ def update_org_unit_config_var_resolution(resolver_value)
156
+ # PUT /d2l/api/lp/(version)/configVariables/(variableId)/resolver
157
+ end
@@ -1,9 +1,48 @@
1
1
  require_relative 'requests'
2
2
  require 'json-schema'
3
+
3
4
  ########################
4
- # COURSES:##############
5
+ # ACTIONS:##############
5
6
  ########################
6
7
 
8
+ # Deletes a course based, referencing it via its org_unit_id
9
+ # This reference is created through a formatted path appended with the id.
10
+ # Then, a delete http method is executed using this path, deleting the course.
11
+ def delete_course_by_id(org_unit_id)
12
+ path = "/d2l/api/lp/#{$lp_ver}/courses/#{org_unit_id}" # setup user path
13
+ #ap path
14
+ _delete(path)
15
+ puts '[+] Course data deleted successfully'.green
16
+ end
17
+
18
+ # retrieve the list of parent org unit type constraints for course offerings
19
+ def get_parent_outypes_courses_schema_constraints
20
+ path = "/d2l/api/lp/#{$lp_ver}/courses/schema"
21
+ _get(path)
22
+ # returns a JSON array of SchemaElement blocks
23
+ end
24
+
25
+ # Performs a get request to retrieve a particular course using the org_unit_id
26
+ # of this particular course. If the course does not exist, as specified by the
27
+ # org_unit_id, the response is typically a 404 error.
28
+ #
29
+ # returns: JSON object of the course
30
+ def get_course_by_id(org_unit_id)
31
+ path = "/d2l/api/lp/#{$lp_ver}/courses/#{org_unit_id}"
32
+ _get(path)
33
+ # returns: JSON object of the course
34
+ end
35
+
36
+
37
+ def get_course_image(org_unit_id, width = 0, height = 0)
38
+ path = "/d2l/api/lp/#{lp_ver}/courses/#{org_unit_id}/image"
39
+ if width > 0 && height > 0
40
+ path += "?width=#{width}"
41
+ path += "&height=#{height}"
42
+ end
43
+ _get(path)
44
+ end
45
+
7
46
  # Checks whether the created course data conforms to the valence api for the
8
47
  # course data JSON object. If it does conform, then nothing happens and it
9
48
  # simply returns true. If it does not conform, then the JSON validator raises
@@ -59,93 +98,7 @@ def create_course_data(course_data)
59
98
  # requires: CreateCourseOffering JSON block
60
99
  path = "/d2l/api/lp/#{$lp_ver}/courses/"
61
100
  _post(path, payload)
62
- puts '[+] Course creation completed successfully'.green
63
- end
64
-
65
- # In order to retrieve an entire department's class list, this method uses a
66
- # predefined org_unit identifier. This identifier is then appended to a path
67
- # and all classes withiin the department are returned as JSON objects in an arr.
68
- #
69
- # returns: JSON array of classes.
70
- def get_org_department_classes(org_unit_id)
71
- path = "/d2l/api/lp/#{$lp_ver}/orgstructure/#{org_unit_id}"
72
- _get(path)
73
- # returns: JSON array of classes.
74
- end
75
-
76
- # Performs a get request to retrieve a particular course using the org_unit_id
77
- # of this particular course. If the course does not exist, as specified by the
78
- # org_unit_id, the response is typically a 404 error.
79
- #
80
- # returns: JSON object of the course
81
- def get_course_by_id(org_unit_id)
82
- path = "/d2l/api/lp/#{$lp_ver}/courses/#{org_unit_id}"
83
- _get(path)
84
- # returns: JSON object of the course
85
- end
86
-
87
- def get_all_courses
88
- path = "/d2l/api/lp/#{$lp_ver}/orgstructure/6606/descendants/?ouTypeId=3"
89
- _get(path)
90
- end
91
-
92
- # much slower means of getting courses if less than 100 courses
93
- def get_courses_by_code(org_unit_code)
94
- all_courses = get_all_courses
95
- courses = []
96
- all_courses.each do |course|
97
- courses.push(course) if course["Code"].downcase.include? "#{org_unit_code}".downcase
98
- end
99
- courses
100
- end
101
- # Retrieves all courses that have a particular string (org_unit_name) within
102
- # their names. This is done by first defining that none are found yet and then
103
- # searching through all course for ones that do have a particular string within
104
- # their name, the matches are pushed into the previously empty array of matches.
105
- # This array is subsequently returned; if none were found, a message is returned
106
- #
107
- # returns: JSON array of matching course data objects
108
- def get_courses_by_name(org_unit_name)
109
- get_courses_by_property_by_string('Name', org_unit_name)
110
- end
111
-
112
- # Retrieves all matching courses that are found using a property and a search
113
- # string. First, it is considered that the class is not found. Then, all courses
114
- # are retrieved and stored as a JSON array in the varaible +results+. After this
115
- # each of the +results+ is iterated, downcased, and checked for their matching
116
- # of the particular search string. If there is a match, they are pushed to
117
- # an array called +courses_results+. This is returned at the end of this op.
118
- #
119
- # returns: array of JSON course objects (that match the search string/property)
120
- def get_courses_by_property_by_string(property, search_string)
121
- puts "[+] Searching for courses using search string: #{search_string}".yellow +
122
- + " -- And property: #{property}"
123
- courses_results = []
124
- results = get_all_courses
125
- results.each do |x|
126
- if x[property].downcase.include? search_string.downcase
127
- courses_results.push(x)
128
- end
129
- end
130
- courses_results
131
- # returns array of all matching courses in JSON format.
132
- end
133
-
134
- # Retrieves all courses that have the specified prop match a regular expression.
135
- # This is done by iterating through all courses and returning an array of all
136
- # that match a regular expression.
137
- #
138
- # returns: array of JSON course objects (with property that matches regex)
139
- def get_courses_by_property_by_regex(property, regex)
140
- puts "[+] Searching for courses using regex: #{regex}".yellow +
141
- + " -- And property: #{property}"
142
- courses_results = []
143
- results = get_all_courses
144
- results.each do |x|
145
- courses_results.push(x) if (x[property] =~ regex) != nil
146
- end
147
- courses_results
148
- # returns array of all matching courses in JSON format.
101
+ #puts '[+] Course creation completed successfully'.green
149
102
  end
150
103
 
151
104
  # Checks whether the updated course data conforms to the valence api for the
@@ -192,16 +145,30 @@ def update_course_data(course_id, new_data)
192
145
  # Provide feedback that the update was successful
193
146
  end
194
147
 
195
- def is_course_component(key)
196
- valid_components = %w(AttendanceRegisters Glossary News Checklists
197
- Grades QuestionLibrary Competencies GradesSettings
198
- Quizzes Content Groups ReleaseConditions CourseFiles
199
- Homepages Rubrics Discussions IntelligentAgents
200
- Schedule DisplaySettings Links SelfAssessments
201
- Dropbox LtiLink Surveys Faq LtiTP ToolNames Forms
202
- Navbars Widgets)
203
- valid_components.include?(key)
204
- # returns whether the key is actually a course component
148
+ # TODO: Update the course image for a course offering.
149
+ def update_course_image(org_unit_id, image_file)
150
+ # PUT /d2l/api/lp/(version)/courses/(orgUnitId)/image
151
+ end
152
+
153
+ ########################
154
+ # COURSE TEMPLATES:#####
155
+ ########################
156
+ # NOTE: Course template related functions are now in 'course_template.rb'
157
+
158
+ ########################
159
+ # COPYING COURSES:######
160
+ ########################
161
+
162
+ def get_copy_job_request_status(org_unit_id, job_token)
163
+ path = "/d2l/api/le/#{le_ver}/import/#{org_unit_id}/copy/#{job_token}"
164
+ _get(path)
165
+ # returns GetCopyJobResponse JSON block
166
+ # GetImportJobResponse:
167
+ # {"JobToken" => <string:COPYJOBSTATUS_T>,
168
+ # "TargetOrgUnitID" => <number:D2LID>,
169
+ # "Status" => <string:IMPORTJOBTSTATUS_T>}
170
+ # States of getImport: UPLOADING, PROCESSING, PROCESSED, IMPORTING,
171
+ # IMPORTFAILED, COMPLETED
205
172
  end
206
173
 
207
174
  def check_create_copy_job_request_validity(create_copy_job_request)
@@ -223,6 +190,19 @@ def check_create_copy_job_request_validity(create_copy_job_request)
223
190
  JSON::Validator.validate!(schema, create_copy_job_request, validate_schema: true)
224
191
  end
225
192
 
193
+ # simple schema check to assure the course component is an actual course component
194
+ # returns: boolean
195
+ def is_course_component(key)
196
+ valid_components = %w(AttendanceRegisters Glossary News Checklists
197
+ Grades QuestionLibrary Competencies GradesSettings
198
+ Quizzes Content Groups ReleaseConditions CourseFiles
199
+ Homepages Rubrics Discussions IntelligentAgents
200
+ Schedule DisplaySettings Links SelfAssessments
201
+ Dropbox LtiLink Surveys Faq LtiTP ToolNames Forms
202
+ Navbars Widgets)
203
+ valid_components.include?(key)
204
+ # returns whether the key is actually a course component
205
+ end
226
206
 
227
207
  def create_new_copy_job_request(org_unit_id, create_copy_job_request)
228
208
  payload =
@@ -247,27 +227,26 @@ def create_new_copy_job_request(org_unit_id, create_copy_job_request)
247
227
  # Returns CreateCopyJobResponse JSON block
248
228
  end
249
229
 
250
- def get_copy_job_request_status(org_unit_id, job_token)
251
- path = "/d2l/api/le/#{le_ver}/import/#{org_unit_id}/copy/#{job_token}"
252
- _get(path)
253
- # returns GetCopyJobResponse JSON block
254
- # GetImportJobResponse:
255
- # {"JobToken" => <string:COPYJOBSTATUS_T>,
256
- # "TargetOrgUnitID" => <number:D2LID>,
257
- # "Status" => <string:IMPORTJOBTSTATUS_T>}
258
- # States of getImport: UPLOADING, PROCESSING, PROCESSED, IMPORTING,
259
- # IMPORTFAILED, COMPLETED
230
+ # NOTE: UNSTABLE!!!!
231
+ # TODO: --UNSTABLE-- Retrieve the list of logs for course copy jobs.
232
+ # Query Params:
233
+ # --OPTIONAL--
234
+ # -bookmark : string
235
+ # -page_size : number
236
+ # -source_org_unit_id : number
237
+ # -destination_org_unit_id : number
238
+ # -start_date : UTCDateTime
239
+ # -end_date : UTCDateTime
240
+ # RETURNS: An object list page containing the resulting CopyCourseLogMessage data blocks
241
+ def get_copy_jobs_logs(bookmark = '', page_size = 0, source_org_unit_id = 0,
242
+ destination_org_unit_id = 0, start_date = '', end_date = '')
243
+ # GET /d2l/api/le/(version)/ccb/logs
260
244
  end
261
- #########
262
- =begin
263
- def create_course_import_request(org_unit_id, callback_url = '')
264
- path = "/d2l/le/#{le_ver}/import/#{org_unit_id}/imports/"
265
- path += "?callbackUrl=#{callback_url}" if callback_url != ''
266
- #_post(path, payload)
267
- #_upload(path, json, file, 'POST', 'file', filename)
268
245
 
269
- end
270
- =end
246
+ ########################
247
+ # IMPORTING COURSES:####
248
+ ########################
249
+
271
250
  def get_course_import_job_request_status(org_unit_id, job_token)
272
251
  path = "/d2l/api/le/#{le_ver}/import/#{org_unit_id}/imports/#{job_token}"
273
252
  _get(path)
@@ -284,28 +263,97 @@ def get_course_import_job_request_logs(org_unit_id, job_token, bookmark = '')
284
263
  # returns PAGED RESULT of ImportCourseLog JSON blocks following bookmark param
285
264
  end
286
265
 
287
- # Deletes a course based, referencing it via its org_unit_id
288
- # This reference is created through a formatted path appended with the id.
289
- # Then, a delete http method is executed using this path, deleting the course.
290
- def delete_course_by_id(org_unit_id)
291
- path = "/d2l/api/lp/#{$lp_ver}/courses/#{org_unit_id}" # setup user path
292
- #ap path
293
- _delete(path)
294
- puts '[+] Course data deleted successfully'.green
266
+ # TODO: Create a new course import job request.
267
+ # INPUT: simple file upload process
268
+ def create_course_import_request(org_unit_id, callback_url = '')
269
+ #path = "/d2l/le/#{le_ver}/import/#{org_unit_id}/imports/"
270
+ #path += "?callbackUrl=#{callback_url}" if callback_url != ''
271
+ #_post(path, payload)
272
+ #_upload(path, json, file, 'POST', 'file', filename)
295
273
  end
296
274
 
297
- # retrieve the list of parent org unit type constraints for course offerings
298
- def get_parent_outypes_courses_schema_constraints
299
- path = "/d2l/api/lp/#{$lp_ver}/courses/schema"
300
- _get(path)
301
- # returns a JSON array of SchemaElement blocks
275
+ ################################################################################
276
+ ################################################################################
277
+
278
+
279
+ ###########################
280
+ # ADDITIONAL FUNCTIONS:####
281
+ ###########################
282
+
283
+
284
+ # In order to retrieve an entire department's class list, this method uses a
285
+ # predefined org_unit identifier. This identifier is then appended to a path
286
+ # and all classes withiin the department are returned as JSON objects in an arr.
287
+ #
288
+ # returns: JSON array of classes.
289
+ def get_org_department_classes(org_unit_id)
290
+ path = "/d2l/api/lp/#{$lp_ver}/orgstructure/#{org_unit_id}"
291
+ _get(path)
292
+ # returns: JSON array of classes.
302
293
  end
303
294
 
304
- def get_course_image(org_unit_id, width = 0, height = 0)
305
- path = "/d2l/api/lp/#{lp_ver}/courses/#{org_unit_id}/image"
306
- if width > 0 && height > 0
307
- path += "?width=#{width}"
308
- path += "&height=#{height}"
295
+
296
+
297
+ def get_all_courses
298
+ path = "/d2l/api/lp/#{$lp_ver}/orgstructure/6606/descendants/?ouTypeId=3"
299
+ _get(path)
300
+ end
301
+
302
+ # much slower means of getting courses if less than 100 courses
303
+ def get_courses_by_code(org_unit_code)
304
+ all_courses = get_all_courses
305
+ courses = []
306
+ all_courses.each do |course|
307
+ courses.push(course) if course["Code"].downcase.include? "#{org_unit_code}".downcase
309
308
  end
310
- _get(path)
309
+ courses
310
+ end
311
+ # Retrieves all courses that have a particular string (org_unit_name) within
312
+ # their names. This is done by first defining that none are found yet and then
313
+ # searching through all course for ones that do have a particular string within
314
+ # their name, the matches are pushed into the previously empty array of matches.
315
+ # This array is subsequently returned; if none were found, a message is returned
316
+ #
317
+ # returns: JSON array of matching course data objects
318
+ def get_courses_by_name(org_unit_name)
319
+ get_courses_by_property_by_string('Name', org_unit_name)
320
+ end
321
+
322
+ # Retrieves all matching courses that are found using a property and a search
323
+ # string. First, it is considered that the class is not found. Then, all courses
324
+ # are retrieved and stored as a JSON array in the varaible +results+. After this
325
+ # each of the +results+ is iterated, downcased, and checked for their matching
326
+ # of the particular search string. If there is a match, they are pushed to
327
+ # an array called +courses_results+. This is returned at the end of this op.
328
+ #
329
+ # returns: array of JSON course objects (that match the search string/property)
330
+ def get_courses_by_property_by_string(property, search_string)
331
+ puts "[+] Searching for courses using search string: #{search_string}".yellow +
332
+ + " -- And property: #{property}"
333
+ courses_results = []
334
+ results = get_all_courses
335
+ results.each do |x|
336
+ if x[property].downcase.include? search_string.downcase
337
+ courses_results.push(x)
338
+ end
339
+ end
340
+ courses_results
341
+ # returns array of all matching courses in JSON format.
342
+ end
343
+
344
+ # Retrieves all courses that have the specified prop match a regular expression.
345
+ # This is done by iterating through all courses and returning an array of all
346
+ # that match a regular expression.
347
+ #
348
+ # returns: array of JSON course objects (with property that matches regex)
349
+ def get_courses_by_property_by_regex(property, regex)
350
+ puts "[+] Searching for courses using regex: #{regex}".yellow +
351
+ + " -- And property: #{property}"
352
+ courses_results = []
353
+ results = get_all_courses
354
+ results.each do |x|
355
+ courses_results.push(x) if (x[property] =~ regex) != nil
356
+ end
357
+ courses_results
358
+ # returns array of all matching courses in JSON format.
311
359
  end