d2l_sdk 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -59,12 +59,14 @@ def get_user_demographics(user_id, field_ids = '', bookmark = '')
59
59
  path += "?"
60
60
  path += "fieldIds=#{field_ids}&" if field_ids != ''
61
61
  path += "bookmark=#{bookmark}" if bookmark != ''
62
+ _get(path)
62
63
  end
63
64
 
64
- def check_demographics_user_entry_data_validity(demographics_user_entry_data)
65
+ def check_demographics_entry_data_validity(demographics_entry_data)
65
66
  # A hash with one value, "EntryValues", which is an array of hashes that
66
67
  # include the keys "Name" and "Values", where "Name" is a string and "Values"
67
68
  # is an array of string.
69
+ # { "key" => [ { "key" => "string", "key" => [] } ] }
68
70
  schema = {
69
71
  'type' => 'object',
70
72
  'required' => %w(EntryValues),
@@ -94,14 +96,27 @@ def check_demographics_user_entry_data_validity(demographics_user_entry_data)
94
96
  }
95
97
  }
96
98
  }
97
- JSON::Validator.validate!(schema, demographics_user_entry_data, validate_schema: true)
99
+ JSON::Validator.validate!(schema, demographics_entry_data, validate_schema: true)
98
100
  end
99
101
 
100
102
 
101
- # TODO: Update the demographics entries for a single user.
103
+ # REVIEW: Update the demographics entries for a single user.
102
104
  # Return: a DemographicsUserEntryData JSON block containing the user’s updated entries.
103
105
  def update_user_demographics(user_id, demographics_entry_data)
106
+ payload =
107
+ {
108
+ "EntryValues" =>
109
+ [
110
+ {
111
+ "Name" => "placeholder_name",
112
+ "Values" => %w(value1 value2)
113
+ }
114
+ ]
115
+ }.merge!(demographics_entry_data)
104
116
  # PUT /d2l/api/lp/(version)/demographics/users/(userId)
117
+ path = "/d2l/api/lp/#{$lp_ver}/demographics/users/#{user_id}"
118
+ check_demographics_user_entry_data_validity(payload)
119
+ _put(path, payload)
105
120
  end
106
121
 
107
122
  ########################
@@ -117,7 +132,7 @@ end
117
132
  # Retrieve list of all demographics fields
118
133
  def get_all_demographic_fields(bookmark = '')
119
134
  path = "/d2l/api/lp/#{$lp_ver}/demographics/fields/"
120
- path += "#{bookmark}" if bookmark != ''
135
+ path += bookmark.to_s if bookmark != ''
121
136
  _get(path)
122
137
  # returns paged result set of DemographicsField JSON blocks
123
138
  end
@@ -154,7 +169,7 @@ def create_demographic_field(demographics_field)
154
169
  "Name" => "String",
155
170
  "Description" => "String",
156
171
  "DataTypeId" => "String:GUID"
157
- }
172
+ }.merge!(demographics_field)
158
173
  check_create_demographics_field(payload)
159
174
  _post(path, payload)
160
175
  # RETURNS: fetch form of a DemographicsField JSON block
@@ -168,7 +183,7 @@ def check_update_demographics_field(demographics_data)
168
183
  'required' => %w(Name Description),
169
184
  'properties' => {
170
185
  'Name' => { 'type' => 'string' },
171
- 'Description' => { 'type' => 'string' },
186
+ 'Description' => { 'type' => 'string' }
172
187
  }
173
188
  }
174
189
  JSON::Validator.validate!(schema, demographics_data, validate_schema: true)
@@ -184,7 +199,7 @@ def update_demographics_field(field_id, demographics_field)
184
199
  "Name" => "String",
185
200
  "Description" => "String",
186
201
  "DataTypeId" => "String:GUID"
187
- }
202
+ }.merge!(demographics_field)
188
203
  check_update_demographics_field(payload)
189
204
  _put(path, payload)
190
205
  # RETURNS: fetch form of a DemographicsField JSON block
@@ -198,7 +213,7 @@ end
198
213
  # uses DataTypeId's as a paging control value
199
214
  def get_all_demographic_types(bookmark = '')
200
215
  path = "/d2l/api/lp/#{$lp_ver}/demographics/dataTypes/"
201
- path += "#{bookmark}" if bookmark != ''
216
+ path += bookmark.to_s if bookmark != ''
202
217
  _get(path)
203
218
  # returns paged result set of DemographicsDataType JSON blocks
204
219
  end
@@ -6,29 +6,61 @@ require 'json-schema'
6
6
  ##################
7
7
 
8
8
  # REVIEW: Delete a particular discussion forum from an org unit.
9
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
10
- def dete_org_unit_discussion(org_unit_id, forum_id)
9
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
10
+ def delete_org_unit_discussion(org_unit_id, forum_id)
11
11
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}"
12
12
  _delete(path)
13
13
  end
14
14
 
15
15
  # REVIEW: Retrieve a list of all discussion forums for an org unit.
16
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/
16
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/
17
17
  def get_org_unit_discussions(org_unit_id)
18
18
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/"
19
19
  _get(path)
20
20
  end
21
21
 
22
22
  # REVIEW: Retrieve a particular discussion forum for an org unit.
23
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
23
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
24
24
  def get_org_unit_discussion(org_unit_id, forum_id)
25
25
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}"
26
26
  _get(path)
27
27
  end
28
28
 
29
- # TODO: Validate input of create_org_unit_discussion
30
- # Create a new forum for an org unit.
31
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/
29
+ def check_forum_data_validity(forum_data)
30
+ schema = {
31
+ 'type' => 'object',
32
+ 'required' => %w(Name Description ShowDescriptionInTopics StartDate
33
+ EndDate PostStartDate PostEndDate IsHidden
34
+ IsLocked RequiresApproval MustPostToParticipate
35
+ DisplayInCalendar DisplayPostDatesInCalendar),
36
+ 'properties' => {
37
+ 'Name' => { 'type' => 'string' },
38
+ 'Description' => {
39
+ 'type' => 'object',
40
+ 'properties' =>
41
+ {
42
+ "Text" => { 'type' => "string" },
43
+ "Html" => { 'type' => %w(string null) }
44
+ }
45
+ },
46
+ 'ShowDescriptionInTopics' => { 'type' => %w(boolean null) },
47
+ 'StartDate' => { 'type' => %w(string null) },
48
+ 'EndDate' => { 'type' => %w(string null) },
49
+ 'PostStartDate' => { 'type' => %w(string null) },
50
+ 'PostEndDate' => { 'type' => %w(string null) },
51
+ 'IsHidden' => { 'type' => 'boolean' },
52
+ 'IsLocked' => { 'type' => 'boolean' },
53
+ 'RequiresApproval' => { 'type' => 'boolean' }, #: <boolean>,
54
+ 'MustPostToParticipate' => { 'type' => %w(boolean null) },
55
+ 'DisplayInCalendar' => { 'type' => %w(boolean null) }, # Added with LE API v1.11
56
+ 'DisplayPostDatesInCalendar' => { 'type' => %w(boolean null) }
57
+ }
58
+ }
59
+ JSON::Validator.validate!(schema, forum_data, validate_schema: true)
60
+ end
61
+
62
+ # REVIEW: Create a new forum for an org unit.
63
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/
32
64
  def create_org_unit_discussion(org_unit_id, forum_data)
33
65
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/"
34
66
  payload =
@@ -36,10 +68,10 @@ def create_org_unit_discussion(org_unit_id, forum_data)
36
68
  'Name' => '', #: <string>,
37
69
  'Description' => #: { <composite:RichText> },
38
70
  {
39
- "Text" => "",#<string:plaintext_version_of_text>,
40
- "Html" => nil #<string:HTML_formatted_version_of_text>|null
71
+ "Text" => "", # <string:plaintext_version_of_text>,
72
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
41
73
  },
42
- 'ShowDescriptionInTopics' => nil, #: <boolean>|null, // Added with LE API v1.14
74
+ 'ShowDescriptionInTopics' => nil, # : <boolean>|null, // Added with LE API v1.14
43
75
  'StartDate' => nil, #: <string:UTCDateTime>|null,
44
76
  'EndDate' => nil, #: <string:UTCDateTime>|null,
45
77
  'PostStartDate' => nil, #: <string:UTCDateTime>|null,
@@ -52,75 +84,240 @@ def create_org_unit_discussion(org_unit_id, forum_data)
52
84
  'DisplayInCalendar' => nil, #: <boolean>|null, // Added with LE API v1.11
53
85
  'DisplayPostDatesInCalendar' => nil, #: <boolean>|null // Added with LE API v1.11
54
86
  }.merge!(forum_data)
55
- # TODO: Validate payload
87
+ # REVIEW: Validate payload
88
+ check_forum_data_validity(payload)
56
89
  _post(path, payload)
57
90
  end
58
91
 
59
- # TODO: Update a forum for an org unit.
60
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
92
+ # REVIEW: Update a forum for an org unit.
93
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
94
+ # NOTE: < LE v 1.10 ignores date filed of the forum_data
95
+ # NOTE: >= LE v 1.11 applies date fields that are sent, otherwise they're
96
+ # assumed null.
97
+ def update_forum(org_unit_id, forum_id, forum_data)
98
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/"
99
+ payload =
100
+ {
101
+ 'Name' => '', #: <string>,
102
+ 'Description' => #: { <composite:RichText> },
103
+ {
104
+ "Text" => "", # <string:plaintext_version_of_text>,
105
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
106
+ },
107
+ 'ShowDescriptionInTopics' => nil, #: <boolean>|null, // Added with LE API v1.14
108
+ 'StartDate' => nil, #: <string:UTCDateTime>|null,
109
+ 'EndDate' => nil, #: <string:UTCDateTime>|null,
110
+ 'PostStartDate' => nil, #: <string:UTCDateTime>|null,
111
+ 'PostEndDate' => nil, # <string:UTCDateTime>|null,
112
+ 'AllowAnonymous' => false, # <boolean>,
113
+ 'IsLocked' => false, #: <boolean>,
114
+ 'IsHidden' => false, #: <boolean>,
115
+ 'RequiresApproval' => '', #: <boolean>,
116
+ 'MustPostToParticipate' => nil, #: <boolean>|null,
117
+ 'DisplayInCalendar' => nil, #: <boolean>|null, // Added with LE API v1.11
118
+ 'DisplayPostDatesInCalendar' => nil, #: <boolean>|null // Added with LE API v1.11
119
+ }.merge!(forum_data)
120
+ # REVIEW: Validate payload
121
+ check_forum_data_validity(payload)
122
+ _put(path, payload)
123
+ # RETURNS: Forum JSON block
124
+ end
61
125
 
62
126
  ##################
63
127
  ## TOPICS: #######
64
128
  ##################
65
129
 
66
- # TODO: Delete a particular topic from the provided discussion forum in an org unit.
67
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
68
- # TODO: Delete a group restriction for a discussion forum topic.
69
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
130
+ # REVIEW: Delete a particular topic from the provided discussion forum in an org unit.
131
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
132
+ def delete_topic(org_unit_id, forum_id, topic_id)
133
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
134
+ _delete(path)
135
+ end
136
+
137
+ # REVIEW: Delete a group restriction for a discussion forum topic.
138
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
139
+ def delete_topic_group_restriction(org_unit_id, forum_id, topic_id)
140
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
141
+ _delete(path)
142
+ end
143
+
70
144
  # REVIEW: Retrieve topics from the provided discussion forum in an org unit.
71
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/
145
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/
72
146
  def get_forum_topics(org_unit_id, forum_id)
73
147
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/"
74
148
  _get(path)
75
149
  end
76
150
 
77
151
  # REVIEW: Retrieve a particular topic from the provided discussion forum in an org unit.
78
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
152
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
79
153
  def get_forum_topic(org_unit_id, forum_id, topic_id)
80
154
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
81
155
  _get(path)
82
156
  end
83
157
 
84
158
  # REVIEW: Retrieve the group restrictions for a discussion forum topic.
85
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
159
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
86
160
  def get_forum_topic_group_restrictions(org_unit_id, forum_id, topic_id)
87
161
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
88
162
  _get(path)
89
163
  end
90
164
 
91
- # TODO: Create a new topic for the provided discussion forum in an org unit.
92
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/
93
- # TODO: Update an existing topic for the provided discussion forum in an org unit.
94
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
95
- # TODO: Add a group to the group restriction list for a discussion forum topic.
96
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
165
+ def check_create_topic_data_validity(create_topic_data)
166
+ schema = {
167
+ 'type' => 'object',
168
+ 'required' => %w(Name Description AllowAnonymousPosts StartDate
169
+ EndDate UnlockStartDate UnlockEndDate IsHidden
170
+ IsLocked RequiresApproval ScoreOutOf IsAutoScore
171
+ IncludeNonScoredValues ScoringType MustPostToParticipate
172
+ RatingType DisplayInCalendar DisplayUnlockDatesInCalendar),
173
+ 'properties' =>
174
+ {
175
+ 'Name' => { 'type' => 'string' },
176
+ 'Description' =>
177
+ {
178
+ 'type' => 'object',
179
+ 'properties' =>
180
+ {
181
+ "Content" => { 'type' => "string" },
182
+ "Type" => { 'type' => "string" }
183
+ }
184
+ },
185
+ 'AllowAnonymousPosts' => { 'type' => 'boolean' },
186
+ 'StartDate' => { 'type' => %w(string null) },
187
+ 'EndDate' => { 'type' => %w(string null) },
188
+ 'UnlockStartDate' => { 'type' => %w(string null) },
189
+ 'UnlockEndDate' => { 'type' => %w(string null) },
190
+ 'IsHidden' => { 'type' => 'boolean' },
191
+ 'IsLocked' => { 'type' => 'boolean' },
192
+ 'RequiresApproval' => { 'type' => 'boolean' }, #: <boolean>,
193
+ 'ScoreOutOf' => { 'type' => %w(integer null) },
194
+ 'IsAutoScore' => { 'type' => 'boolean' }, # Added with LE API v1.11
195
+ 'IncludeNonScoredValues' => { 'type' => 'boolean' },
196
+ 'ScoringType' => { 'type' => %w(string null) },
197
+ 'MustPostToParticipate' => { 'type' => 'boolean' }, #: <boolean>,
198
+ 'RatingType' => { 'type' => %w(string null) },
199
+ 'DisplayInCalendar' => { 'type' => %w(boolean null) }, # Added with LE API v1.12
200
+ 'DisplayUnlockDatesInCalendar' => { 'type' => %w(boolean null) } # Added with LE API v1.12
201
+ }
202
+ }
203
+ JSON::Validator.validate!(schema, create_topic_data, validate_schema: true)
204
+ end
205
+
206
+ # REVIEW: Create a new topic for the provided discussion forum in an org unit.
207
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/
208
+ def create_forum_topic(org_unit_id, forum_id, create_topic_data)
209
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/"
210
+ payload =
211
+ {
212
+ "Name" => "", # : <string>,
213
+ "Description" =>
214
+ {
215
+ "Text" => "", # <string:plaintext_version_of_text>,
216
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
217
+ }, # { <composite:RichTextInput> },
218
+ "AllowAnonymousPosts" => false, # <boolean>,
219
+ "StartDate" => nil, # <string:UTCDateTime>|null,
220
+ "EndDate" => nil, # : <string:UTCDateTime>|null,
221
+ "IsHidden" => false, # : <boolean>,
222
+ "UnlockStartDate" => nil, # : <string:UTCDateTime>|null,
223
+ "UnlockEndDate" => nil, # : <string:UTCDateTime>|null,
224
+ "RequiresApproval" => false, # : <boolean>,
225
+ "ScoreOutOf" => nil, # : <number>|null,
226
+ "IsAutoScore" => false, # : <boolean>,
227
+ "IncludeNonScoredValues" => "", # : <boolean>,
228
+ "ScoringType" => nil, # : <string:SCORING_T>|null,
229
+ "IsLocked" => false, # : <boolean>,
230
+ "MustPostToParticipate" => false, # : <boolean>,
231
+ "RatingType" => nil, # : <string:RATING_T>|null,
232
+ "DisplayInCalendar" => nil, # : <boolean>|null, // Added with LE API v1.12
233
+ "DisplayUnlockDatesInCalendar" => nil, # : <boolean>|null // Added with LE API v1.12
234
+ }.merge!(create_topic_data)
235
+ check_create_topic_data_validity(payload) # REVIEW: Validity check of topic data
236
+ _post(path, payload)
237
+ # RETURNS: Topic JSON data block
238
+ end
239
+
240
+ # REVIEW: Update an existing topic for the provided discussion forum in an org unit.
241
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
242
+ def update_forum_topic(org_unit_id, forum_id, topic_id, create_topic_data)
243
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
244
+ payload =
245
+ {
246
+ "Name" => "", # : <string>,
247
+ "Description" =>
248
+ {
249
+ "Text" => "", # <string:plaintext_version_of_text>,
250
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
251
+ }, # { <composite:RichTextInput> },
252
+ "AllowAnonymousPosts" => false, # <boolean>,
253
+ "StartDate" => nil, # <string:UTCDateTime>|null,
254
+ "EndDate" => nil, # : <string:UTCDateTime>|null,
255
+ "IsHidden" => false, # : <boolean>,
256
+ "UnlockStartDate" => nil, # : <string:UTCDateTime>|null,
257
+ "UnlockEndDate" => nil, # : <string:UTCDateTime>|null,
258
+ "RequiresApproval" => false, # : <boolean>,
259
+ "ScoreOutOf" => nil, # : <number>|null,
260
+ "IsAutoScore" => false, # : <boolean>,
261
+ "IncludeNonScoredValues" => "", # : <boolean>,
262
+ "ScoringType" => nil, # : <string:SCORING_T>|null,
263
+ "IsLocked" => false, # : <boolean>,
264
+ "MustPostToParticipate" => false, # : <boolean>,
265
+ "RatingType" => nil, # : <string:RATING_T>|null,
266
+ "DisplayInCalendar" => nil, # : <boolean>|null, // Added with LE API v1.12
267
+ "DisplayUnlockDatesInCalendar" => nil, # : <boolean>|null // Added with LE API v1.12
268
+ }.merge!(create_topic_data)
269
+ check_create_topic_data_validity(payload) # REVIEW: Validity check of topic data
270
+ _post(path, payload)
271
+ # RETURNS: Topic JSON data block
272
+ end
273
+
274
+ # REVIEW: Add a group to the group restriction list for a discussion forum topic.
275
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
276
+ def add_group_to_group_restriction_list(org_unit_id, forum_id, topic_id, group_id)
277
+ raise ArgumentError, "Argument 'group_id' is not numeric value." unless group_id.is_a? Numeric
278
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
279
+ payload = { "GroupRestriction" => { "GroupId" => group_id } }
280
+ _put(path, payload)
281
+ # RETURNS: ??
282
+ end
97
283
 
98
284
  ##################
99
285
  ## POSTS: ########
100
286
  ##################
101
287
 
102
- # TODO: Delete a particular post from a discussion forum topic.
103
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
104
- # TODO: DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
288
+ # REVIEW: Delete a particular post from a discussion forum topic.
289
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
290
+ def delete_topic_post(org_unit_id, forum_id, topic_id, post_id)
291
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
292
+ _delete(path)
293
+ end
294
+
295
+ # REVIEW: DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
105
296
  # => Delete the current user context’s rating for a particular post from a discussion forum topic.
297
+ def delete_current_user_context_post_rating
298
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
299
+ _delete(path)
300
+ # NOTE: Doing so is actually an update, setting the current user's rating
301
+ # of a post to null
302
+ end
106
303
 
107
304
  # REVIEW: Retrieve all posts in a discussion forum topic.
108
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/
305
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/
109
306
  # RETURNS: JSON array of Post data blocks containing the properties for all the post
110
307
  def get_forum_topic_posts(org_unit_id, forum_id, topic_id, page_size = 0, page_number = 0,
111
308
  threads_only = nil, thread_id = 0, sort = '')
112
309
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/?"
113
- path += "pageSize=#{page_size}&" unless page_size == 0
114
- path += "pageNumber=#{page_number}&" unless page_number == 0
310
+ path += "pageSize=#{page_size}&" unless page_size.zero?
311
+ path += "pageNumber=#{page_number}&" unless page_number.zero?
115
312
  path += "threadsOnly=#{threads_only}&" unless threads_only.nil?
116
- path += "threadId=#{thread_id}&" unless thread_id == 0
313
+ path += "threadId=#{thread_id}&" unless thread_id.zero?
117
314
  path += "sort=#{sort}" unless sort == ''
118
315
  _get(path)
119
316
  # RETURNS: JSON array of Post data blocks containing the properties for all the post
120
317
  end
121
318
 
122
319
  # REVIEW: Retrieve a particular post in a discussion forum topic.
123
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
320
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
124
321
  def get_forum_topic_post(org_unit_id, forum_id, topic_id, post_id)
125
322
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
126
323
  _get(path)
@@ -128,15 +325,15 @@ def get_forum_topic_post(org_unit_id, forum_id, topic_id, post_id)
128
325
  end
129
326
 
130
327
  # REVIEW: Retrieve the approval status for a particular post in a discussion forum topic.
131
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Approval
328
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval
132
329
  def get_forum_topic_post_approval_status(org_unit_id, forum_id, topic_id, post_id)
133
330
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval"
134
331
  _get(path)
135
332
  # RETURNS: ApprovalData JSON data block
136
333
  end
137
334
 
138
- # TODO: Retrieve the flagged status for a particular post in a discussion forum topic.
139
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Flag
335
+ # REVIEW: Retrieve the flagged status for a particular post in a discussion forum topic.
336
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag
140
337
  def get_forum_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id)
141
338
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag"
142
339
  _get(path)
@@ -144,7 +341,7 @@ def get_forum_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id
144
341
  end
145
342
 
146
343
  # REVIEW: Retrieve the rating data for a particular post in a discussion forum topic.
147
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating
344
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating
148
345
  def get_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
149
346
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating"
150
347
  _get(path)
@@ -152,7 +349,7 @@ def get_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
152
349
  end
153
350
 
154
351
  # REVIEW: Retrieve the current user context’s rating data for a particular post in a discussion forum topic.
155
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
352
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
156
353
  def get_current_user_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
157
354
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
158
355
  _get(path)
@@ -160,7 +357,7 @@ def get_current_user_forum_topic_post_rating_data(org_unit_id, forum_id, topic_i
160
357
  end
161
358
 
162
359
  # REVIEW: Retrieve the current read status for a particular post in a discussion forum topic.
163
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/ReadStatus
360
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus
164
361
  def get_forum_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id)
165
362
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus"
166
363
  _get(path)
@@ -168,7 +365,7 @@ def get_forum_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id)
168
365
  end
169
366
 
170
367
  # REVIEW: Retrieve all the vote data for a particular post in a discussion forum topic.
171
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes
368
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes
172
369
  def get_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
173
370
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes"
174
371
  _get(path)
@@ -176,24 +373,132 @@ def get_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
176
373
  end
177
374
 
178
375
  # REVIEW: Retrieve the current user’s vote data for a particular post in a discussion forum topic.
179
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes/MyVote
376
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote
180
377
  def get_current_user_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
181
378
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote"
182
379
  _get(path)
183
380
  # RETURNS: UserVoteData JSON data block
184
381
  end
185
382
 
186
- # TODO: Create a new post in a discussion forum topic.
187
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/
188
- # TODO: Update a particular post in a discussion forum topic.
189
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
190
- # TODO: Update the approval status of a particular post in a discussion forum topic.
191
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Approval
192
- # TODO: Update the flagged status of a particular post in a discussion forum topic.
193
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Flag
194
- # TODO: Update the current user context’s rating for a particular post in a discussion forum topic.
195
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
196
- # TODO: Update the read status of a particular post in a discussion forum topic.
197
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/ReadStatus
198
- # TODO: Update a discussion forum topic post’s vote data for the current user.
199
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes/MyVote
383
+ def check_create_post_data_validity(create_post_data)
384
+ schema = {
385
+ 'type' => 'object',
386
+ 'required' => %w(ParentPostId Subject Message IsAnonymous),
387
+ 'properties' =>
388
+ {
389
+ 'ParentPostId' => { 'type' => %w(integer null) },
390
+ 'Subject' => { 'type' => "string" },
391
+ 'Message' =>
392
+ {
393
+ 'type' => 'object',
394
+ 'properties' =>
395
+ {
396
+ "Content" => { 'type' => "string" },
397
+ "Type" => { 'type' => "string" }
398
+ }
399
+ },
400
+ 'IsAnonymous' => { 'type' => 'boolean' }
401
+ }
402
+ }
403
+ JSON::Validator.validate!(schema, create_post_data, validate_schema: true)
404
+ end
405
+
406
+ # REVIEW: Create a new post in a discussion forum topic.
407
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/
408
+ # NOTE: No file attachments? Send it normally :)
409
+ # NOTE: File attachments? Send using Multipart/Mixed body conforming to RFC2388
410
+ # RETURNS: Post JSON data block
411
+ def create_topic_post(org_unit_id, forum_id, topic_id, create_post_data, files = [])
412
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/"
413
+ payload = {
414
+ "ParentPostId" => nil, # integer or nil
415
+ "Subject" => "",
416
+ "Message" => {
417
+ "Content" => "",
418
+ "Type" => "Text|Html"
419
+ },
420
+ "IsAnonymous" => false
421
+ }.merge!(create_post_data)
422
+ check_create_post_data_validity(payload)
423
+ if files == []
424
+ # can do a simple POST request.
425
+ _post(path, payload)
426
+ else
427
+ # Have to do multipart/mixed body custom POST request.
428
+ _upload_post_data(path, payload, files, "POST")
429
+ end
430
+ end
431
+
432
+ # REVIEW: Update a particular post in a discussion forum topic.
433
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
434
+ # RETURNS: Post JSON data block
435
+ def update_topic_post(org_unit_id, forum_id, topic_id, post_id, create_post_data)
436
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
437
+ payload = {
438
+ "ParentPostId" => nil, # integer or nil
439
+ "Subject" => "",
440
+ "Message" => {
441
+ "Content" => "",
442
+ "Type" => "Text|Html"
443
+ },
444
+ "IsAnonymous" => false
445
+ }.merge!(create_post_data)
446
+ check_create_post_data_validity(payload)
447
+ _put(path, payload)
448
+ end
449
+
450
+ # REVIEW: Update the approval status of a particular post in a discussion forum topic.
451
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval
452
+ # RETURNS: ApprovalData JSON data block
453
+ def update_topic_post_approval_status(org_unit_id, forum_id, topic_id, post_id, is_approved)
454
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval"
455
+ raise ArgumentError, "Argument 'is_approved' is not a boolean value." unless is_approved == true || is_approved == false
456
+ payload = { "IsApproved" => is_approved }
457
+ _put(path, payload)
458
+ end
459
+
460
+
461
+ # REVIEW: Update the flagged status of a particular post in a discussion forum topic.
462
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag
463
+ # RETURNS: FlagData JSON data block
464
+ def update_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id, is_flagged)
465
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag"
466
+ raise ArgumentError, "Argument 'is_flagged' is not a boolean value." unless is_flagged == true || is_flagged == false
467
+ payload = { "IsFlagged" => is_flagged }
468
+ _put(path, payload)
469
+ end
470
+
471
+ # REVIEW: Update the current user context’s rating for a particular post in a discussion forum topic.
472
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
473
+ # RETURNS: UserRatingData JSON data block
474
+ def update_topic_post_current_user_rating(org_unit_id, forum_id, topic_id, post_id, rating)
475
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
476
+ raise ArgumentError, "Argument 'rating' is not a number or null value." unless rating.is_a?(Numeric) || rating.nil?
477
+ payload = { "Rating" => rating }
478
+ _put(path, payload)
479
+ end
480
+
481
+ # REVIEW: Update the read status of a particular post in a discussion forum topic.
482
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus
483
+ # RETURNS: ReadStatusData JSON data block
484
+ def update_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id, is_read)
485
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus"
486
+ raise ArgumentError, "Argument 'is_read' is not a boolean value." unless is_read == true || is_read == false
487
+ payload = { "IsRead" => is_read }
488
+ _put(path, payload)
489
+ end
490
+
491
+ # REVIEW: Update a discussion forum topic post’s vote data for the current user.
492
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote
493
+ # RETURNS: ??
494
+ def update_topic_post_current_user_vote_data(org_unit_id, forum_id, topic_id, post_id, vote)
495
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote"
496
+ unless vote.is_a? String
497
+ raise ArgumentError, "Argument 'vote' is not a string value."
498
+ else
499
+ payload = {
500
+ "Vote" => vote
501
+ }
502
+ _put(path, payload)
503
+ end
504
+ end