bright 1.3 → 2.0

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