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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Rakefile +0 -1
- data/bright.gemspec +12 -14
- data/lib/bright/address.rb +5 -5
- data/lib/bright/connection.rb +7 -9
- data/lib/bright/contact.rb +7 -9
- data/lib/bright/cursor_response_collection.rb +8 -10
- data/lib/bright/email_address.rb +1 -2
- data/lib/bright/enrollment.rb +2 -2
- data/lib/bright/errors.rb +0 -1
- data/lib/bright/helpers/blank_helper.rb +0 -2
- data/lib/bright/model.rb +13 -13
- data/lib/bright/phone_number.rb +1 -2
- data/lib/bright/response_collection.rb +8 -8
- data/lib/bright/school.rb +1 -4
- data/lib/bright/sis_apis/aeries.rb +18 -19
- data/lib/bright/sis_apis/base.rb +3 -5
- data/lib/bright/sis_apis/bright_sis.rb +82 -84
- data/lib/bright/sis_apis/focus.rb +78 -84
- data/lib/bright/sis_apis/one_roster/infinite_campus.rb +15 -0
- data/lib/bright/sis_apis/one_roster/skyward.rb +6 -0
- data/lib/bright/sis_apis/{infinite_campus.rb → one_roster.rb} +91 -100
- data/lib/bright/sis_apis/power_school.rb +105 -107
- data/lib/bright/sis_apis/synergy.rb +6 -8
- data/lib/bright/sis_apis/tsis.rb +54 -54
- data/lib/bright/student.rb +15 -19
- data/lib/bright/version.rb +1 -1
- data/lib/bright.rb +14 -12
- metadata +6 -5
- data/lib/bright/sis_apis/skyward.rb +0 -277
@@ -1,9 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "oauth"
|
2
2
|
|
3
3
|
module Bright
|
4
4
|
module SisApi
|
5
5
|
class Focus < Base
|
6
|
-
|
7
6
|
@@description = "Connects to the Focus OneRoster API for accessing student information"
|
8
7
|
@@doc_url = ""
|
9
8
|
@@api_version = "1.1"
|
@@ -13,12 +12,12 @@ module Bright
|
|
13
12
|
DEFAULT_NO_THREADS = 2
|
14
13
|
|
15
14
|
DEMOGRAPHICS_CONVERSION = {
|
16
|
-
"americanIndianOrAlaskaNative"=>"American Indian Or Alaska Native",
|
17
|
-
"asian"=>"Asian",
|
18
|
-
"blackOrAfricanAmerican"=>"Black Or African American",
|
19
|
-
"nativeHawaiianOrOtherPacificIslander"=>"Native Hawaiian Or Other Pacific Islander",
|
20
|
-
"white"=>"White",
|
21
|
-
"hispanicOrLatinoEthnicity"=>"Hispanic Or Latino"
|
15
|
+
"americanIndianOrAlaskaNative" => "American Indian Or Alaska Native",
|
16
|
+
"asian" => "Asian",
|
17
|
+
"blackOrAfricanAmerican" => "Black Or African American",
|
18
|
+
"nativeHawaiianOrOtherPacificIslander" => "Native Hawaiian Or Other Pacific Islander",
|
19
|
+
"white" => "White",
|
20
|
+
"hispanicOrLatinoEthnicity" => "Hispanic Or Latino"
|
22
21
|
}
|
23
22
|
|
24
23
|
def initialize(options = {})
|
@@ -33,26 +32,26 @@ module Bright
|
|
33
32
|
end
|
34
33
|
|
35
34
|
def api_version
|
36
|
-
Gem::Version.new(
|
35
|
+
Gem::Version.new(connection_options.dig(:api_version) || @@api_version)
|
37
36
|
end
|
38
37
|
|
39
38
|
def get_student_by_api_id(api_id, params = {})
|
40
|
-
st_hsh =
|
39
|
+
st_hsh = request(:get, "students/#{api_id}", params)
|
41
40
|
Student.new(convert_to_user_data(st_hsh["user"])) if st_hsh and st_hsh["user"]
|
42
41
|
end
|
43
42
|
|
44
43
|
def get_student(params = {}, options = {})
|
45
|
-
|
44
|
+
get_students(params, options.merge(limit: 1, wrap_in_collection: false)).first
|
46
45
|
end
|
47
46
|
|
48
47
|
def get_students(params = {}, options = {})
|
49
48
|
params[:limit] = params[:limit] || options[:limit] || 100
|
50
|
-
students_response_hash =
|
49
|
+
students_response_hash = request(:get, "students", map_search_params(params))
|
51
50
|
total_results = students_response_hash[:response_headers]["x-total-count"].to_i
|
52
51
|
if students_response_hash and students_response_hash["users"]
|
53
52
|
students_hash = [students_response_hash["users"]].flatten
|
54
53
|
|
55
|
-
students = students_hash.compact.collect {|st_hsh|
|
54
|
+
students = students_hash.compact.collect { |st_hsh|
|
56
55
|
Student.new(convert_to_user_data(st_hsh))
|
57
56
|
}
|
58
57
|
end
|
@@ -61,14 +60,14 @@ module Bright
|
|
61
60
|
load_more_call = proc { |page|
|
62
61
|
# pages start at one, so add a page here
|
63
62
|
params[:offset] = (params[:limit].to_i * page)
|
64
|
-
api.get_students(params, {:
|
63
|
+
api.get_students(params, {wrap_in_collection: false})
|
65
64
|
}
|
66
65
|
ResponseCollection.new({
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
66
|
+
seed_page: students,
|
67
|
+
total: total_results,
|
68
|
+
per_page: params[:limit],
|
69
|
+
load_more_call: load_more_call,
|
70
|
+
no_threads: options[:no_threads] || DEFAULT_NO_THREADS
|
72
71
|
})
|
73
72
|
else
|
74
73
|
students
|
@@ -84,22 +83,22 @@ module Bright
|
|
84
83
|
end
|
85
84
|
|
86
85
|
def get_school_by_api_id(api_id, params = {})
|
87
|
-
sc_hsh =
|
86
|
+
sc_hsh = request(:get, "schools/#{api_id}", params)
|
88
87
|
School.new(convert_to_school_data(sc_hsh["org"])) if sc_hsh and sc_hsh["org"]
|
89
88
|
end
|
90
89
|
|
91
90
|
def get_school(params = {}, options = {})
|
92
|
-
|
91
|
+
get_schools(params, options.merge(limit: 1, wrap_in_collection: false)).first
|
93
92
|
end
|
94
93
|
|
95
94
|
def get_schools(params = {}, options = {})
|
96
95
|
params[:limit] = params[:limit] || options[:limit] || 100
|
97
|
-
schools_response_hash =
|
96
|
+
schools_response_hash = request(:get, "schools", map_school_search_params(params))
|
98
97
|
total_results = schools_response_hash[:response_headers]["x-total-count"].to_i
|
99
98
|
if schools_response_hash and schools_response_hash["orgs"]
|
100
99
|
schools_hash = [schools_response_hash["orgs"]].flatten
|
101
100
|
|
102
|
-
schools = schools_hash.compact.collect {|sc_hsh|
|
101
|
+
schools = schools_hash.compact.collect { |sc_hsh|
|
103
102
|
School.new(convert_to_school_data(sc_hsh))
|
104
103
|
}
|
105
104
|
end
|
@@ -108,27 +107,27 @@ module Bright
|
|
108
107
|
load_more_call = proc { |page|
|
109
108
|
# pages start at one, so add a page here
|
110
109
|
params[:offset] = (params[:limit].to_i * page)
|
111
|
-
api.get_schools(params, {:
|
110
|
+
api.get_schools(params, {wrap_in_collection: false})
|
112
111
|
}
|
113
112
|
ResponseCollection.new({
|
114
|
-
:
|
115
|
-
:
|
116
|
-
:
|
117
|
-
:
|
118
|
-
:
|
113
|
+
seed_page: schools,
|
114
|
+
total: total_results,
|
115
|
+
per_page: params[:limit],
|
116
|
+
load_more_call: load_more_call,
|
117
|
+
no_threads: options[:no_threads]
|
119
118
|
})
|
120
119
|
else
|
121
120
|
schools
|
122
121
|
end
|
123
122
|
end
|
124
123
|
|
125
|
-
def get_contact_by_api_id(api_id, params ={})
|
126
|
-
contact_hsh =
|
124
|
+
def get_contact_by_api_id(api_id, params = {})
|
125
|
+
contact_hsh = request(:get, "users/#{api_id}", params)
|
127
126
|
Contact.new(convert_to_user_data(contact_hsh["user"], bright_type: "Contact")) if contact_hsh and contact_hsh["user"]
|
128
127
|
end
|
129
128
|
|
130
129
|
def request(method, path, params = {})
|
131
|
-
uri
|
130
|
+
uri = "#{connection_options[:uri]}/#{path}"
|
132
131
|
body = nil
|
133
132
|
if method == :get
|
134
133
|
query = URI.encode_www_form(params)
|
@@ -139,7 +138,7 @@ module Bright
|
|
139
138
|
|
140
139
|
response = connection_retry_wrapper {
|
141
140
|
connection = Bright::Connection.new(uri)
|
142
|
-
headers =
|
141
|
+
headers = headers_for_auth(uri)
|
143
142
|
connection.request(method, body, headers)
|
144
143
|
}
|
145
144
|
|
@@ -158,46 +157,45 @@ module Bright
|
|
158
157
|
def headers_for_auth(uri)
|
159
158
|
case api_version
|
160
159
|
when Gem::Version.new("1.1")
|
161
|
-
site = URI.parse(
|
160
|
+
site = URI.parse(connection_options[:uri])
|
162
161
|
site = "#{site.scheme}://#{site.host}"
|
163
|
-
consumer = OAuth::Consumer.new(
|
164
|
-
options = {:
|
162
|
+
consumer = OAuth::Consumer.new(connection_options[:client_id], connection_options[:client_secret], {site: site, scheme: :header})
|
163
|
+
options = {timestamp: Time.now.to_i, nonce: SecureRandom.uuid}
|
165
164
|
{"Authorization" => consumer.create_signed_request(:get, uri, nil, options)["Authorization"]}
|
166
165
|
when Gem::Version.new("1.2")
|
167
|
-
if
|
168
|
-
|
166
|
+
if connection_options[:access_token].nil? or connection_options[:access_token_expires] < Time.now
|
167
|
+
retrieve_access_token
|
169
168
|
end
|
170
169
|
{
|
171
|
-
"Authorization" => "Bearer #{
|
170
|
+
"Authorization" => "Bearer #{connection_options[:access_token]}",
|
172
171
|
"Accept" => "application/json;charset=UTF-8",
|
173
|
-
"Content-Type" =>"application/json;charset=UTF-8"
|
172
|
+
"Content-Type" => "application/json;charset=UTF-8"
|
174
173
|
}
|
175
174
|
end
|
176
175
|
end
|
177
176
|
|
178
177
|
def retrieve_access_token
|
179
|
-
connection = Bright::Connection.new(
|
178
|
+
connection = Bright::Connection.new(connection_options[:token_uri])
|
180
179
|
response = connection.request(:post,
|
181
180
|
{
|
182
181
|
"grant_type" => "client_credentials",
|
183
|
-
"username" =>
|
184
|
-
"password" =>
|
182
|
+
"username" => connection_options[:client_id],
|
183
|
+
"password" => connection_options[:client_secret]
|
185
184
|
},
|
186
|
-
|
187
|
-
)
|
185
|
+
headers_for_access_token)
|
188
186
|
if !response.error?
|
189
187
|
response_hash = JSON.parse(response.body)
|
190
188
|
end
|
191
189
|
if response_hash["access_token"]
|
192
|
-
|
193
|
-
|
190
|
+
connection_options[:access_token] = response_hash["access_token"]
|
191
|
+
connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
|
194
192
|
end
|
195
193
|
response_hash
|
196
194
|
end
|
197
195
|
|
198
196
|
def headers_for_access_token
|
199
197
|
{
|
200
|
-
"Authorization" => "Basic #{Base64.strict_encode64("#{
|
198
|
+
"Authorization" => "Basic #{Base64.strict_encode64("#{connection_options[:client_id]}:#{connection_options[:client_secret]}")}",
|
201
199
|
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
202
200
|
}
|
203
201
|
end
|
@@ -207,7 +205,7 @@ module Bright
|
|
207
205
|
default_params = {}
|
208
206
|
|
209
207
|
filter = []
|
210
|
-
params.each do |k,v|
|
208
|
+
params.each do |k, v|
|
211
209
|
case k.to_s
|
212
210
|
when "first_name"
|
213
211
|
filter << "givenName='#{v}'"
|
@@ -228,14 +226,14 @@ module Bright
|
|
228
226
|
unless filter.empty?
|
229
227
|
params = {"filter" => filter.join(" AND ")}
|
230
228
|
end
|
231
|
-
default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
229
|
+
default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
232
230
|
end
|
233
231
|
|
234
232
|
def map_school_search_params(params)
|
235
233
|
params = params.dup
|
236
234
|
default_params = {}
|
237
235
|
filter = []
|
238
|
-
params.each do |k,v|
|
236
|
+
params.each do |k, v|
|
239
237
|
case k.to_s
|
240
238
|
when "number"
|
241
239
|
filter << "identifier='#{v}'"
|
@@ -248,29 +246,28 @@ module Bright
|
|
248
246
|
unless filter.empty?
|
249
247
|
params = {"filter" => filter.join(" AND ")}
|
250
248
|
end
|
251
|
-
default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
|
249
|
+
default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
|
252
250
|
end
|
253
251
|
|
254
252
|
def convert_to_school_data(school_params)
|
255
253
|
return {} if school_params.blank?
|
256
|
-
|
257
|
-
:
|
258
|
-
:
|
259
|
-
:
|
260
|
-
:
|
254
|
+
{
|
255
|
+
api_id: school_params["sourcedId"],
|
256
|
+
name: school_params["name"],
|
257
|
+
number: school_params["identifier"],
|
258
|
+
last_modified: school_params["dateLastModified"]
|
261
259
|
}
|
262
|
-
return school_data_hsh
|
263
260
|
end
|
264
261
|
|
265
262
|
def convert_to_user_data(user_params, bright_type: "Student")
|
266
263
|
return {} if user_params.blank?
|
267
264
|
user_data_hsh = {
|
268
|
-
:
|
269
|
-
:
|
270
|
-
:
|
271
|
-
:
|
272
|
-
:
|
273
|
-
}.reject{|k,v| v.blank?}
|
265
|
+
api_id: user_params["sourcedId"],
|
266
|
+
first_name: user_params["givenName"],
|
267
|
+
middle_name: user_params["middleName"],
|
268
|
+
last_name: user_params["familyName"],
|
269
|
+
last_modified: user_params["dateLastModified"]
|
270
|
+
}.reject { |k, v| v.blank? }
|
274
271
|
unless user_params["identifier"].blank?
|
275
272
|
user_data_hsh[:sis_student_id] = user_params["identifier"]
|
276
273
|
end
|
@@ -282,14 +279,14 @@ module Bright
|
|
282
279
|
end
|
283
280
|
unless user_params["email"].blank?
|
284
281
|
user_data_hsh[:email_address] = {
|
285
|
-
:
|
282
|
+
email_address: user_params["email"]
|
286
283
|
}
|
287
284
|
end
|
288
285
|
unless user_params["orgs"].blank?
|
289
|
-
if (s = user_params["orgs"].detect{|org| org["href"] =~ /\/schools\//})
|
286
|
+
if (s = user_params["orgs"].detect { |org| org["href"] =~ /\/schools\// })
|
290
287
|
self.schools_cache ||= {}
|
291
288
|
if (attending_school = self.schools_cache[s["sourcedId"]]).nil?
|
292
|
-
attending_school =
|
289
|
+
attending_school = get_school_by_api_id(s["sourcedId"])
|
293
290
|
self.schools_cache[attending_school.api_id] = attending_school
|
294
291
|
end
|
295
292
|
end
|
@@ -298,26 +295,24 @@ module Bright
|
|
298
295
|
end
|
299
296
|
end
|
300
297
|
unless user_params["phone"].blank?
|
301
|
-
user_data_hsh[:phone_numbers] = [{:
|
298
|
+
user_data_hsh[:phone_numbers] = [{phone_number: user_params["phone"]}]
|
302
299
|
end
|
303
300
|
unless user_params["sms"].blank?
|
304
301
|
user_data_hsh[:phone_numbers] ||= []
|
305
|
-
user_data_hsh[:phone_numbers] << {:
|
302
|
+
user_data_hsh[:phone_numbers] << {phone_number: user_params["sms"]}
|
306
303
|
end
|
307
304
|
|
308
|
-
#add the demographic information
|
305
|
+
# add the demographic information
|
309
306
|
demographics_hash = get_demographic_information(user_data_hsh[:api_id])
|
310
307
|
user_data_hsh.merge!(demographics_hash) unless demographics_hash.blank?
|
311
308
|
|
312
|
-
#if you're a student, build the contacts too
|
309
|
+
# if you're a student, build the contacts too
|
313
310
|
if bright_type == "Student" and !user_params["agents"].blank?
|
314
311
|
user_data_hsh[:contacts] = user_params["agents"].collect do |agent_hsh|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
raise e
|
320
|
-
end
|
312
|
+
get_contact_by_api_id(agent_hsh["sourcedId"])
|
313
|
+
rescue Bright::ResponseError => e
|
314
|
+
if !e.message.to_s.include?("404")
|
315
|
+
raise e
|
321
316
|
end
|
322
317
|
end.compact
|
323
318
|
user_data_hsh[:grade] = (user_params["grades"] || []).first
|
@@ -326,7 +321,7 @@ module Bright
|
|
326
321
|
end
|
327
322
|
end
|
328
323
|
|
329
|
-
|
324
|
+
user_data_hsh
|
330
325
|
end
|
331
326
|
|
332
327
|
def get_demographic_information(api_id)
|
@@ -335,7 +330,7 @@ module Bright
|
|
335
330
|
begin
|
336
331
|
demographics_params = request(:get, "demographics/#{api_id}")["demographics"]
|
337
332
|
rescue Bright::ResponseError => e
|
338
|
-
if e.message.to_s.include?(
|
333
|
+
if e.message.to_s.include?("404")
|
339
334
|
return demographic_hsh
|
340
335
|
else
|
341
336
|
raise e
|
@@ -358,22 +353,21 @@ module Bright
|
|
358
353
|
end
|
359
354
|
end
|
360
355
|
end
|
361
|
-
|
356
|
+
demographic_hsh
|
362
357
|
end
|
363
358
|
|
364
359
|
def get_grade_school_year(date = Date.today)
|
365
360
|
# return the school year of a specific date
|
366
361
|
self.school_years_cache ||= {}
|
367
362
|
if self.school_years_cache[date].nil?
|
368
|
-
academic_periods_params =
|
369
|
-
school_years = academic_periods_params.map{|ap| ap["schoolYear"]}.uniq
|
363
|
+
academic_periods_params = request(:get, "academicSessions", {"filter" => "startDate<='#{date}' AND endDate>='#{date}' AND status='active'"})["academicSessions"]
|
364
|
+
school_years = academic_periods_params.map { |ap| ap["schoolYear"] }.uniq
|
370
365
|
if school_years.size == 1
|
371
366
|
self.school_years_cache[date] = school_years.first
|
372
367
|
end
|
373
368
|
end
|
374
|
-
|
369
|
+
self.school_years_cache[date]
|
375
370
|
end
|
376
|
-
|
377
371
|
end
|
378
372
|
end
|
379
373
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Bright
|
2
|
+
module SisApi
|
3
|
+
class OneRoster::InfiniteCampus < OneRoster
|
4
|
+
def convert_to_user_data(user_params, bright_type: "Student")
|
5
|
+
user_data_hsh = super
|
6
|
+
|
7
|
+
unless user_params["userMasterIdentifier"].blank?
|
8
|
+
user_data_hsh[:state_student_id] = user_params["userMasterIdentifier"]
|
9
|
+
end
|
10
|
+
|
11
|
+
user_data_hsh
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|