bright 1.3 → 2.0

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.
@@ -1,22 +1,21 @@
1
- require 'oauth'
1
+ require "oauth"
2
2
 
3
3
  module Bright
4
4
  module SisApi
5
- class InfiniteCampus < Base
6
-
7
- @@description = "Connects to the Infinite Campus OneRoster API for accessing student information"
8
- @@doc_url = "https://content.infinitecampus.com/sis/latest/documentation/oneroster-api"
9
- @@api_version = "1.1"
5
+ class OneRoster < Base
6
+ @@description = "Connects to the OneRoster API for accessing student information"
7
+ @@doc_url = "https://www.imsglobal.org/sites/default/files/spec/oneroster/v1p2/rostering-informationmodel/OneRosterv1p2RosteringService_InfoModelv1p0.html"
8
+ @@api_version = "1.2"
10
9
 
11
10
  attr_accessor :connection_options, :schools_cache, :school_years_cache
12
11
 
13
12
  DEMOGRAPHICS_CONVERSION = {
14
- "americanIndianOrAlaskaNative"=>"American Indian Or Alaska Native",
15
- "asian"=>"Asian",
16
- "blackOrAfricanAmerican"=>"Black Or African American",
17
- "nativeHawaiianOrOtherPacificIslander"=>"Native Hawaiian Or Other Pacific Islander",
18
- "white"=>"White",
19
- "hispanicOrLatinoEthnicity"=>"Hispanic Or Latino"
13
+ "americanIndianOrAlaskaNative" => "American Indian Or Alaska Native",
14
+ "asian" => "Asian",
15
+ "blackOrAfricanAmerican" => "Black Or African American",
16
+ "nativeHawaiianOrOtherPacificIslander" => "Native Hawaiian Or Other Pacific Islander",
17
+ "white" => "White",
18
+ "hispanicOrLatinoEthnicity" => "Hispanic Or Latino"
20
19
  }
21
20
 
22
21
  def initialize(options = {})
@@ -31,36 +30,36 @@ module Bright
31
30
  end
32
31
 
33
32
  def api_version
34
- Gem::Version.new(self.connection_options.dig(:api_version) || @@api_version)
33
+ Gem::Version.new(connection_options.dig(:api_version) || @@api_version)
35
34
  end
36
35
 
37
36
  def get_student_by_api_id(api_id, params = {})
38
- if api_version <= Gem::Version.new("1.1")
39
- params = {:role => "student"}.merge(params)
37
+ params = if api_version <= Gem::Version.new("1.1")
38
+ {role: "student"}.merge(params)
40
39
  else
41
- params = {:roles => "student"}.merge(params)
40
+ {roles: "student"}.merge(params)
42
41
  end
43
- st_hsh = self.request(:get, "users/#{api_id}", params)
42
+ st_hsh = request(:get, "users/#{api_id}", params)
44
43
  Student.new(convert_to_user_data(st_hsh["user"])) if st_hsh and st_hsh["user"]
45
44
  end
46
45
 
47
46
  def get_student(params = {}, options = {})
48
- self.get_students(params, options.merge(:limit => 1, :wrap_in_collection => false)).first
47
+ get_students(params, options.merge(limit: 1, wrap_in_collection: false)).first
49
48
  end
50
49
 
51
50
  def get_students(params = {}, options = {})
52
- if api_version <= Gem::Version.new("1.1")
53
- params = {:role => "student"}.merge(params)
51
+ params = if api_version <= Gem::Version.new("1.1")
52
+ {role: "student"}.merge(params)
54
53
  else
55
- params = {:roles => "student"}.merge(params)
54
+ {roles: "student"}.merge(params)
56
55
  end
57
56
  params[:limit] = params[:limit] || options[:limit] || 100
58
- students_response_hash = self.request(:get, 'users', self.map_search_params(params))
57
+ students_response_hash = request(:get, "users", map_search_params(params))
59
58
  total_results = students_response_hash[:response_headers]["x-total-count"].to_i
60
59
  if students_response_hash and students_response_hash["users"]
61
60
  students_hash = [students_response_hash["users"]].flatten
62
61
 
63
- students = students_hash.compact.collect {|st_hsh|
62
+ students = students_hash.compact.collect { |st_hsh|
64
63
  Student.new(convert_to_user_data(st_hsh))
65
64
  }
66
65
  end
@@ -69,14 +68,14 @@ module Bright
69
68
  load_more_call = proc { |page|
70
69
  # pages start at one, so add a page here
71
70
  params[:offset] = (params[:limit].to_i * page)
72
- api.get_students(params, {:wrap_in_collection => false})
71
+ api.get_students(params, {wrap_in_collection: false})
73
72
  }
74
73
  ResponseCollection.new({
75
- :seed_page => students,
76
- :total => total_results,
77
- :per_page => params[:limit],
78
- :load_more_call => load_more_call,
79
- :no_threads => options[:no_threads]
74
+ seed_page: students,
75
+ total: total_results,
76
+ per_page: params[:limit],
77
+ load_more_call: load_more_call,
78
+ no_threads: options[:no_threads]
80
79
  })
81
80
  else
82
81
  students
@@ -92,22 +91,22 @@ module Bright
92
91
  end
93
92
 
94
93
  def get_school_by_api_id(api_id, params = {})
95
- sc_hsh = self.request(:get, "schools/#{api_id}", params)
94
+ sc_hsh = request(:get, "schools/#{api_id}", params)
96
95
  School.new(convert_to_school_data(sc_hsh["org"])) if sc_hsh and sc_hsh["org"]
97
96
  end
98
97
 
99
98
  def get_school(params = {}, options = {})
100
- self.get_schools(params, options.merge(:limit => 1, :wrap_in_collection => false)).first
99
+ get_schools(params, options.merge(limit: 1, wrap_in_collection: false)).first
101
100
  end
102
101
 
103
102
  def get_schools(params = {}, options = {})
104
103
  params[:limit] = params[:limit] || options[:limit] || 100
105
- schools_response_hash = self.request(:get, 'schools', self.map_school_search_params(params))
104
+ schools_response_hash = request(:get, "schools", map_school_search_params(params))
106
105
  total_results = schools_response_hash[:response_headers]["x-total-count"].to_i
107
106
  if schools_response_hash and schools_response_hash["orgs"]
108
107
  schools_hash = [schools_response_hash["orgs"]].flatten
109
108
 
110
- schools = schools_hash.compact.collect {|sc_hsh|
109
+ schools = schools_hash.compact.collect { |sc_hsh|
111
110
  School.new(convert_to_school_data(sc_hsh))
112
111
  }
113
112
  end
@@ -116,27 +115,27 @@ module Bright
116
115
  load_more_call = proc { |page|
117
116
  # pages start at one, so add a page here
118
117
  params[:offset] = (params[:limit].to_i * page)
119
- api.get_schools(params, {:wrap_in_collection => false})
118
+ api.get_schools(params, {wrap_in_collection: false})
120
119
  }
121
120
  ResponseCollection.new({
122
- :seed_page => schools,
123
- :total => total_results,
124
- :per_page => params[:limit],
125
- :load_more_call => load_more_call,
126
- :no_threads => options[:no_threads]
121
+ seed_page: schools,
122
+ total: total_results,
123
+ per_page: params[:limit],
124
+ load_more_call: load_more_call,
125
+ no_threads: options[:no_threads]
127
126
  })
128
127
  else
129
128
  schools
130
129
  end
131
130
  end
132
131
 
133
- def get_contact_by_api_id(api_id, params ={})
134
- contact_hsh = self.request(:get, "users/#{api_id}", params)
132
+ def get_contact_by_api_id(api_id, params = {})
133
+ contact_hsh = request(:get, "users/#{api_id}", params)
135
134
  Contact.new(convert_to_user_data(contact_hsh["user"], bright_type: "Contact")) if contact_hsh and contact_hsh["user"]
136
135
  end
137
136
 
138
137
  def request(method, path, params = {})
139
- uri = "#{self.connection_options[:uri]}/#{path}"
138
+ uri = "#{connection_options[:uri]}/#{path}"
140
139
  body = nil
141
140
  if method == :get
142
141
  query = URI.encode_www_form(params)
@@ -147,7 +146,7 @@ module Bright
147
146
 
148
147
  response = connection_retry_wrapper {
149
148
  connection = Bright::Connection.new(uri)
150
- headers = self.headers_for_auth(uri)
149
+ headers = headers_for_auth(uri)
151
150
  connection.request(method, body, headers)
152
151
  }
153
152
 
@@ -166,46 +165,45 @@ module Bright
166
165
  def headers_for_auth(uri)
167
166
  case api_version
168
167
  when Gem::Version.new("1.1")
169
- site = URI.parse(self.connection_options[:uri])
168
+ site = URI.parse(connection_options[:uri])
170
169
  site = "#{site.scheme}://#{site.host}"
171
- consumer = OAuth::Consumer.new(self.connection_options[:client_id], self.connection_options[:client_secret], { :site => site, :scheme => :header })
172
- options = {:timestamp => Time.now.to_i, :nonce => SecureRandom.uuid}
170
+ consumer = OAuth::Consumer.new(connection_options[:client_id], connection_options[:client_secret], {site: site, scheme: :header})
171
+ options = {timestamp: Time.now.to_i, nonce: SecureRandom.uuid}
173
172
  {"Authorization" => consumer.create_signed_request(:get, uri, nil, options)["Authorization"]}
174
173
  when Gem::Version.new("1.2")
175
- if self.connection_options[:access_token].nil? or self.connection_options[:access_token_expires] < Time.now
176
- self.retrieve_access_token
174
+ if connection_options[:access_token].nil? or connection_options[:access_token_expires] < Time.now
175
+ retrieve_access_token
177
176
  end
178
177
  {
179
- "Authorization" => "Bearer #{self.connection_options[:access_token]}",
180
- "Accept" => "application/json;charset=UTF-8",
181
- "Content-Type" =>"application/json;charset=UTF-8"
178
+ "Authorization" => "Bearer #{connection_options[:access_token]}",
179
+ "Accept" => "application/json",
180
+ "Content-Type" => "application/json"
182
181
  }
183
182
  end
184
183
  end
185
184
 
186
185
  def retrieve_access_token
187
- connection = Bright::Connection.new(self.connection_options[:token_uri])
186
+ connection = Bright::Connection.new(connection_options[:token_uri])
188
187
  response = connection.request(:post,
189
188
  {
190
189
  "grant_type" => "client_credentials",
191
- "username" => self.connection_options[:client_id],
192
- "password" => self.connection_options[:client_secret]
190
+ "username" => connection_options[:client_id],
191
+ "password" => connection_options[:client_secret]
193
192
  },
194
- self.headers_for_access_token
195
- )
193
+ headers_for_access_token)
196
194
  if !response.error?
197
195
  response_hash = JSON.parse(response.body)
198
196
  end
199
197
  if response_hash["access_token"]
200
- self.connection_options[:access_token] = response_hash["access_token"]
201
- self.connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
198
+ connection_options[:access_token] = response_hash["access_token"]
199
+ connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
202
200
  end
203
201
  response_hash
204
202
  end
205
203
 
206
204
  def headers_for_access_token
207
205
  {
208
- "Authorization" => "Basic #{Base64.strict_encode64("#{self.connection_options[:client_id]}:#{self.connection_options[:client_secret]}")}",
206
+ "Authorization" => "Basic #{Base64.strict_encode64("#{connection_options[:client_id]}:#{connection_options[:client_secret]}")}",
209
207
  "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
210
208
  }
211
209
  end
@@ -215,7 +213,7 @@ module Bright
215
213
  default_params = {}
216
214
 
217
215
  filter = []
218
- params.each do |k,v|
216
+ params.each do |k, v|
219
217
  case k.to_s
220
218
  when "first_name"
221
219
  filter << "givenName='#{v}'"
@@ -236,14 +234,14 @@ module Bright
236
234
  unless filter.empty?
237
235
  params = {"filter" => filter.join(" AND ")}
238
236
  end
239
- default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
237
+ default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
240
238
  end
241
239
 
242
240
  def map_school_search_params(params)
243
241
  params = params.dup
244
242
  default_params = {}
245
243
  filter = []
246
- params.each do |k,v|
244
+ params.each do |k, v|
247
245
  case k.to_s
248
246
  when "number"
249
247
  filter << "identifier='#{v}'"
@@ -256,50 +254,46 @@ module Bright
256
254
  unless filter.empty?
257
255
  params = {"filter" => filter.join(" AND ")}
258
256
  end
259
- default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
257
+ default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
260
258
  end
261
259
 
262
260
  def convert_to_school_data(school_params)
263
261
  return {} if school_params.blank?
264
- school_data_hsh = {
265
- :api_id => school_params["sourcedId"],
266
- :name => school_params["name"],
267
- :number => school_params["identifier"],
268
- :last_modified => school_params["dateLastModified"]
262
+ {
263
+ api_id: school_params["sourcedId"],
264
+ name: school_params["name"],
265
+ number: school_params["identifier"],
266
+ last_modified: school_params["dateLastModified"]
269
267
  }
270
- return school_data_hsh
271
268
  end
272
269
 
273
270
  def convert_to_user_data(user_params, bright_type: "Student")
274
271
  return {} if user_params.blank?
275
272
  user_data_hsh = {
276
- :api_id => user_params["sourcedId"],
277
- :first_name => user_params["givenName"],
278
- :middle_name => user_params["middleName"],
279
- :last_name => user_params["familyName"],
280
- :last_modified => user_params["dateLastModified"]
281
- }.reject{|k,v| v.blank?}
273
+ api_id: user_params["sourcedId"],
274
+ first_name: user_params["givenName"],
275
+ middle_name: user_params["middleName"],
276
+ last_name: user_params["familyName"],
277
+ last_modified: user_params["dateLastModified"]
278
+ }.reject { |k, v| v.blank? }
282
279
  unless user_params["identifier"].blank?
283
280
  user_data_hsh[:sis_student_id] = user_params["identifier"]
284
281
  end
285
- unless user_params["userMasterIdentifier"].blank?
286
- user_data_hsh[:state_student_id] = user_params["userMasterIdentifier"]
287
- end
288
282
  unless user_params["userIds"].blank?
289
- if (state_id_hsh = user_params["userIds"].detect{|user_id_hsh| user_id_hsh["type"] == "stateID"})
283
+ if (state_id_hsh = user_params["userIds"].detect { |user_id_hsh| user_id_hsh["type"] == "stateID" })
290
284
  user_data_hsh[:state_student_id] = state_id_hsh["identifier"]
291
285
  end
292
286
  end
293
287
  unless user_params["email"].blank?
294
288
  user_data_hsh[:email_address] = {
295
- :email_address => user_params["email"]
289
+ email_address: user_params["email"]
296
290
  }
297
291
  end
298
292
  unless user_params["orgs"].blank?
299
- if (s = user_params["orgs"].detect{|org| org["href"] =~ /\/schools\//})
293
+ if (s = user_params["orgs"].detect { |org| org["href"] =~ /\/schools\// })
300
294
  self.schools_cache ||= {}
301
295
  if (attending_school = self.schools_cache[s["sourcedId"]]).nil?
302
- attending_school = self.get_school_by_api_id(s["sourcedId"])
296
+ attending_school = get_school_by_api_id(s["sourcedId"])
303
297
  self.schools_cache[attending_school.api_id] = attending_school
304
298
  end
305
299
  end
@@ -308,26 +302,24 @@ module Bright
308
302
  end
309
303
  end
310
304
  unless user_params["phone"].blank?
311
- user_data_hsh[:phone_numbers] = [{:phone_number => user_params["phone"]}]
305
+ user_data_hsh[:phone_numbers] = [{phone_number: user_params["phone"]}]
312
306
  end
313
307
  unless user_params["sms"].blank?
314
308
  user_data_hsh[:phone_numbers] ||= []
315
- user_data_hsh[:phone_numbers] << {:phone_number => user_params["sms"]}
309
+ user_data_hsh[:phone_numbers] << {phone_number: user_params["sms"]}
316
310
  end
317
311
 
318
- #add the demographic information
312
+ # add the demographic information
319
313
  demographics_hash = get_demographic_information(user_data_hsh[:api_id])
320
314
  user_data_hsh.merge!(demographics_hash) unless demographics_hash.blank?
321
315
 
322
- #if you're a student, build the contacts too
316
+ # if you're a student, build the contacts too
323
317
  if bright_type == "Student" and !user_params["agents"].blank?
324
318
  user_data_hsh[:contacts] = user_params["agents"].collect do |agent_hsh|
325
- begin
326
- self.get_contact_by_api_id(agent_hsh["sourcedId"])
327
- rescue Bright::ResponseError => e
328
- if !e.message.to_s.include?("404")
329
- raise e
330
- end
319
+ get_contact_by_api_id(agent_hsh["sourcedId"])
320
+ rescue Bright::ResponseError => e
321
+ if !e.message.to_s.include?("404")
322
+ raise e
331
323
  end
332
324
  end.compact
333
325
  user_data_hsh[:grade] = (user_params["grades"] || []).first
@@ -336,7 +328,7 @@ module Bright
336
328
  end
337
329
  end
338
330
 
339
- return user_data_hsh
331
+ user_data_hsh
340
332
  end
341
333
 
342
334
  def get_demographic_information(api_id)
@@ -345,7 +337,7 @@ module Bright
345
337
  begin
346
338
  demographics_params = request(:get, "demographics/#{api_id}")["demographics"]
347
339
  rescue Bright::ResponseError => e
348
- if e.message.to_s.include?('404')
340
+ if e.message.to_s.include?("404")
349
341
  return demographic_hsh
350
342
  else
351
343
  raise e
@@ -368,22 +360,21 @@ module Bright
368
360
  end
369
361
  end
370
362
  end
371
- return demographic_hsh
363
+ demographic_hsh
372
364
  end
373
365
 
374
366
  def get_grade_school_year(date = Date.today)
375
- #return the school year of a specific date
367
+ # return the school year of a specific date
376
368
  self.school_years_cache ||= {}
377
369
  if self.school_years_cache[date].nil?
378
- academic_periods_params = self.request(:get, "academicSessions", {"filter" => "startDate<='#{date.to_s}' AND endDate>='#{date.to_s}' AND status='active'"})["academicSessions"]
379
- school_years = academic_periods_params.map{|ap| ap["schoolYear"]}.uniq
370
+ academic_periods_params = request(:get, "academicSessions", {"filter" => "startDate<='#{date}' AND endDate>='#{date}' AND status='active'"})["academicSessions"]
371
+ school_years = academic_periods_params.map { |ap| ap["schoolYear"] }.uniq
380
372
  if school_years.size == 1
381
373
  self.school_years_cache[date] = school_years.first
382
374
  end
383
375
  end
384
- return self.school_years_cache[date]
376
+ self.school_years_cache[date]
385
377
  end
386
-
387
378
  end
388
379
  end
389
380
  end