bright 1.3 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,8 @@
1
1
  module Bright
2
2
  module SisApi
3
3
  class PowerSchool < Base
4
- DATE_FORMAT = '%Y-%m-%d'
5
- INVALID_SEARCH_CHAR_RE = /[\,\;]/
4
+ DATE_FORMAT = "%Y-%m-%d"
5
+ INVALID_SEARCH_CHAR_RE = /[,;]/
6
6
 
7
7
  @@description = "Connects to the PowerSchool API for accessing student information"
8
8
  @@doc_url = "http://psimages.sunnysideschools.org/api-developer-guide-1.6.0/"
@@ -22,30 +22,30 @@ module Bright
22
22
  end
23
23
 
24
24
  def get_student_by_api_id(api_id, params = {})
25
- params = self.apply_expansions(params)
26
- st_hsh = self.request(:get, "ws/v1/student/#{api_id}", params)
25
+ params = apply_expansions(params)
26
+ st_hsh = request(:get, "ws/v1/student/#{api_id}", params)
27
27
  Student.new(convert_to_student_data(st_hsh["student"])) if st_hsh and st_hsh["student"]
28
28
  end
29
29
 
30
30
  def get_student(params = {}, options = {})
31
- self.get_students(params, options.merge(:per_page => 1, :wrap_in_collection => false)).first
31
+ get_students(params, options.merge(per_page: 1, wrap_in_collection: false)).first
32
32
  end
33
33
 
34
34
  def get_students(params = {}, options = {})
35
- params = self.apply_expansions(params)
36
- params = self.apply_options(params, options)
35
+ params = apply_expansions(params)
36
+ params = apply_options(params, options)
37
37
 
38
38
  if options[:wrap_in_collection] != false
39
- students_count_response_hash = self.request(:get, 'ws/v1/district/student/count', self.map_student_search_params(params))
39
+ students_count_response_hash = request(:get, "ws/v1/district/student/count", map_student_search_params(params))
40
40
  # {"resource"=>{"count"=>293}}
41
41
  total_results = students_count_response_hash["resource"]["count"].to_i if students_count_response_hash["resource"]
42
42
  end
43
43
 
44
- students_response_hash = self.request(:get, 'ws/v1/district/student', self.map_student_search_params(params))
44
+ students_response_hash = request(:get, "ws/v1/district/student", map_student_search_params(params))
45
45
  if students_response_hash and students_response_hash["students"] && students_response_hash["students"]["student"]
46
46
  students_hash = [students_response_hash["students"]["student"]].flatten
47
47
 
48
- students = students_hash.compact.collect {|st_hsh|
48
+ students = students_hash.compact.collect { |st_hsh|
49
49
  Student.new(convert_to_student_data(st_hsh))
50
50
  }
51
51
 
@@ -54,15 +54,15 @@ module Bright
54
54
  load_more_call = proc { |page|
55
55
  # pages start at one, so add a page here
56
56
  params[:page] = (page + 1)
57
- api.get_students(params, {:wrap_in_collection => false})
57
+ api.get_students(params, {wrap_in_collection: false})
58
58
  }
59
59
 
60
60
  ResponseCollection.new({
61
- :seed_page => students,
62
- :total => total_results,
63
- :per_page => params[:pagesize],
64
- :load_more_call => load_more_call,
65
- :no_threads => options[:no_threads]
61
+ seed_page: students,
62
+ total: total_results,
63
+ per_page: params[:pagesize],
64
+ load_more_call: load_more_call,
65
+ no_threads: options[:no_threads]
66
66
  })
67
67
  else
68
68
  students
@@ -73,13 +73,13 @@ module Bright
73
73
  end
74
74
 
75
75
  def create_student(student, additional_params = {})
76
- response = self.request(:post, 'ws/v1/student', self.convert_from_student_data(student, "INSERT", additional_params))
76
+ response = request(:post, "ws/v1/student", convert_from_student_data(student, "INSERT", additional_params))
77
77
  if response["results"] and response["results"]["insert_count"] == 1
78
78
  student.api_id = response["results"]["result"]["success_message"]["id"]
79
79
 
80
80
  # update our local student object with any data the server might have updated
81
- nstudent = self.get_student_by_api_id(student.api_id)
82
- student.assign_attributes(Hash[Bright::Student.attribute_names.collect{|n| [n, nstudent.send(n)]}].reject{|k,v| v.nil?})
81
+ nstudent = get_student_by_api_id(student.api_id)
82
+ student.assign_attributes(Bright::Student.attribute_names.collect { |n| [n, nstudent.send(n)] }.to_h.reject { |k, v| v.nil? })
83
83
 
84
84
  # enrollment is no longer needed as creation is over
85
85
  student.enrollment = nil
@@ -91,10 +91,10 @@ module Bright
91
91
  end
92
92
 
93
93
  def update_student(student, additional_params = {})
94
- response = self.request(:post, 'ws/v1/student', self.convert_from_student_data(student, "UPDATE", additional_params))
94
+ response = request(:post, "ws/v1/student", convert_from_student_data(student, "UPDATE", additional_params))
95
95
  if response["results"] and response["results"]["update_count"] == 1
96
96
  student.api_id = response["results"]["result"]["success_message"]["id"]
97
- self.get_student_by_api_id(student.api_id)
97
+ get_student_by_api_id(student.api_id)
98
98
  else
99
99
  puts response.inspect
100
100
  student
@@ -106,18 +106,18 @@ module Bright
106
106
  end
107
107
 
108
108
  def get_schools(params = {}, options = {})
109
- params = self.apply_options(params, options)
109
+ params = apply_options(params, options)
110
110
 
111
111
  if options[:wrap_in_collection] != false
112
- schools_count_response_hash = self.request(:get, 'ws/v1/district/school/count', params)
112
+ schools_count_response_hash = request(:get, "ws/v1/district/school/count", params)
113
113
  # {"resource"=>{"count"=>293}}
114
114
  total_results = schools_count_response_hash["resource"]["count"].to_i if schools_count_response_hash["resource"]
115
115
  end
116
116
 
117
- schools_response_hash = self.request(:get, 'ws/v1/district/school', params)
117
+ schools_response_hash = request(:get, "ws/v1/district/school", params)
118
118
  schools_hsh = [schools_response_hash["schools"]["school"]].flatten
119
119
 
120
- schools = schools_hsh.compact.collect {|st_hsh|
120
+ schools = schools_hsh.compact.collect { |st_hsh|
121
121
  School.new(convert_to_school_data(st_hsh))
122
122
  }
123
123
 
@@ -126,15 +126,15 @@ module Bright
126
126
  load_more_call = proc { |page|
127
127
  # pages start at one, so add a page here
128
128
  params[:page] = (page + 1)
129
- api.get_schools(params, {:wrap_in_collection => false})
129
+ api.get_schools(params, {wrap_in_collection: false})
130
130
  }
131
131
 
132
132
  ResponseCollection.new({
133
- :seed_page => schools,
134
- :total => total_results,
135
- :per_page => params[:pagesize],
136
- :load_more_call => load_more_call,
137
- :no_threads => options[:no_threads]
133
+ seed_page: schools,
134
+ total: total_results,
135
+ per_page: params[:pagesize],
136
+ load_more_call: load_more_call,
137
+ no_threads: options[:no_threads]
138
138
  })
139
139
  else
140
140
  schools
@@ -142,19 +142,19 @@ module Bright
142
142
  end
143
143
 
144
144
  def retrieve_access_token
145
- connection = Bright::Connection.new("#{self.connection_options[:uri]}/oauth/access_token/")
146
- response = connection.request(:post, "grant_type=client_credentials", self.headers_for_access_token)
145
+ connection = Bright::Connection.new("#{connection_options[:uri]}/oauth/access_token/")
146
+ response = connection.request(:post, "grant_type=client_credentials", headers_for_access_token)
147
147
  if !response.error?
148
148
  response_hash = JSON.parse(response.body)
149
149
  end
150
150
  if response_hash["access_token"]
151
- self.connection_options[:access_token] = response_hash["access_token"]
151
+ connection_options[:access_token] = response_hash["access_token"]
152
152
  end
153
153
  response_hash
154
154
  end
155
155
 
156
156
  def request(method, path, params = {})
157
- uri = "#{self.connection_options[:uri]}/#{path}"
157
+ uri = "#{connection_options[:uri]}/#{path}"
158
158
  body = nil
159
159
  if method == :get
160
160
  query = URI.encode_www_form(params)
@@ -163,10 +163,9 @@ module Bright
163
163
  body = JSON.dump(params)
164
164
  end
165
165
 
166
-
167
166
  response = connection_retry_wrapper {
168
167
  connection = Bright::Connection.new(uri)
169
- headers = self.headers_for_auth
168
+ headers = headers_for_auth
170
169
  connection.request(method, body, headers)
171
170
  }
172
171
 
@@ -186,7 +185,7 @@ module Bright
186
185
  default_params = {}
187
186
 
188
187
  q = ""
189
- %w(first_name middle_name last_name).each do |f|
188
+ %w[first_name middle_name last_name].each do |f|
190
189
  if fn = params.delete(f.to_sym)
191
190
  fn = fn.gsub(INVALID_SEARCH_CHAR_RE, " ").strip
192
191
  q += %(name.#{f}==#{fn};)
@@ -202,16 +201,16 @@ module Bright
202
201
  end
203
202
  params[:q] = q
204
203
 
205
- default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
204
+ default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
206
205
  end
207
206
 
208
207
  def convert_to_student_data(attrs)
209
208
  cattrs = {}
210
209
 
211
210
  if attrs["name"]
212
- cattrs[:first_name] = attrs["name"]["first_name"]
211
+ cattrs[:first_name] = attrs["name"]["first_name"]
213
212
  cattrs[:middle_name] = attrs["name"]["middle_name"]
214
- cattrs[:last_name] = attrs["name"]["last_name"]
213
+ cattrs[:last_name] = attrs["name"]["last_name"]
215
214
  end
216
215
 
217
216
  cattrs[:api_id] = attrs["id"].to_s
@@ -234,17 +233,17 @@ module Bright
234
233
  cattrs[:projected_graduation_year] = pg if pg > 0
235
234
  end
236
235
 
237
- #Student Address
236
+ # Student Address
238
237
  begin
239
- cattrs[:addresses] = attrs["addresses"].to_a.collect{|a| self.convert_to_address_data(a)}.select{|a| !a[:street].blank?}.uniq{|a| a[:street]} if attrs["addresses"]
238
+ cattrs[:addresses] = attrs["addresses"].to_a.collect { |a| convert_to_address_data(a) }.select { |a| !a[:street].blank? }.uniq { |a| a[:street] } if attrs["addresses"]
240
239
  rescue
241
240
  end
242
241
 
243
- #Ethnicity / Race Info
242
+ # Ethnicity / Race Info
244
243
  if attrs["ethnicity_race"].is_a?(Hash)
245
244
  if !(race_hshs = attrs.dig("ethnicity_race", "races")).nil?
246
- #this should be an array, but it doesn't appear PS always sends it as one
247
- cattrs[:race] = [race_hshs].flatten.map{|race_hsh| race_hsh["district_race_code"]}.compact.uniq
245
+ # this should be an array, but it doesn't appear PS always sends it as one
246
+ cattrs[:race] = [race_hshs].flatten.map { |race_hsh| race_hsh["district_race_code"] }.compact.uniq
248
247
  end
249
248
 
250
249
  if !attrs.dig("ethnicity_race", "federal_ethnicity").nil?
@@ -255,16 +254,16 @@ module Bright
255
254
  end
256
255
  end
257
256
 
258
- #Contacts Info
259
- [1,2].each do |contact_id|
257
+ # Contacts Info
258
+ [1, 2].each do |contact_id|
260
259
  if !attrs.dig("contact", "emergency_contact_name#{contact_id}").blank? and !attrs.dig("contact", "emergency_phone#{contact_id}").blank?
261
260
  cattrs[:contacts] ||= []
262
261
  contact_attrs = {
263
- :first_name => attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").last.strip,
264
- :last_name => attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").first.strip,
265
- :phone_numbers => [
262
+ first_name: attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").last.strip,
263
+ last_name: attrs.dig("contact", "emergency_contact_name#{contact_id}").to_s.split(",").first.strip,
264
+ phone_numbers: [
266
265
  {
267
- :phone_number => attrs.dig("contact", "emergency_phone#{contact_id}")
266
+ phone_number: attrs.dig("contact", "emergency_phone#{contact_id}")
268
267
  }
269
268
  ]
270
269
  }
@@ -272,68 +271,67 @@ module Bright
272
271
  end
273
272
  end
274
273
 
275
- cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
274
+ cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
276
275
  end
277
276
 
278
277
  def convert_from_student_data(student, action = nil, additional_params = {})
279
278
  return {} if student.nil?
280
279
 
281
280
  student_data = {
282
- :client_uid => student.client_id,
283
- :action => action,
284
- :id => student.api_id,
285
- :local_id => student.sis_student_id,
286
- :state_province_id => student.state_student_id,
287
- :name => {
288
- :first_name => student.first_name,
289
- :middle_name => student.middle_name,
290
- :last_name => student.last_name
291
- }.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?},
292
- :demographics => {
281
+ client_uid: student.client_id,
282
+ action: action,
283
+ id: student.api_id,
284
+ local_id: student.sis_student_id,
285
+ state_province_id: student.state_student_id,
286
+ name: {
287
+ first_name: student.first_name,
288
+ middle_name: student.middle_name,
289
+ last_name: student.last_name
290
+ }.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? },
291
+ demographics: {
293
292
  # To avoid a mismatch of attributes, we'll ignore for now
294
293
  # :gender => student.gender.to_s[0].to_s.upcase,
295
- :birth_date => (student.birth_date ? student.birth_date.strftime(DATE_FORMAT) : nil),
296
- :projected_graduation_year => student.projected_graduation_year
297
- }.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
298
- }.merge(additional_params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
294
+ birth_date: (student.birth_date ? student.birth_date.strftime(DATE_FORMAT) : nil),
295
+ projected_graduation_year: student.projected_graduation_year
296
+ }.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
297
+ }.merge(additional_params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
299
298
 
300
299
  # apply enrollment info
301
300
  if student.enrollment
302
- student_data.merge!(self.convert_from_enrollment_data(student.enrollment))
301
+ student_data.merge!(convert_from_enrollment_data(student.enrollment))
303
302
  end
304
303
 
305
304
  # apply addresses
306
305
  address_data = {}
307
- if ph = student.addresses.detect{|a| a.type == "physical"}
308
- address_data.merge!(self.convert_from_address_data(ph))
306
+ if ph = student.addresses.detect { |a| a.type == "physical" }
307
+ address_data.merge!(convert_from_address_data(ph))
309
308
  end
310
- if mail = student.addresses.detect{|a| a.type == "mailing"}
311
- address_data.merge!(self.convert_from_address_data(mail))
309
+ if mail = student.addresses.detect { |a| a.type == "mailing" }
310
+ address_data.merge!(convert_from_address_data(mail))
312
311
  end
313
312
  if ph.nil? and mail.nil? and any = student.addresses.first
314
313
  cany = any.clone
315
314
  cany.type = "physical"
316
- address_data.merge!(self.convert_from_address_data(cany))
315
+ address_data.merge!(convert_from_address_data(cany))
317
316
  end
318
317
  if address_data.size > 0
319
- student_data.merge!({:addresses => address_data})
318
+ student_data.merge!({addresses: address_data})
320
319
  end
321
320
 
322
- {:students => {:student => student_data}}
321
+ {students: {student: student_data}}
323
322
  end
324
323
 
325
324
  def convert_from_enrollment_data(enrollment)
326
325
  return {} if enrollment.nil?
327
- {:school_enrollment => {
328
- :enroll_status => "A",
329
- :entry_date => (enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
330
- :entry_comment => enrollment.entry_comment,
331
- :exit_date => (enrollment.exit_date || enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
332
- :exit_comment => enrollment.exit_comment,
333
- :grade_level => enrollment.grade,
334
- :school_number => enrollment.school ? enrollment.school.number : nil
335
- }.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
336
- }
326
+ {school_enrollment: {
327
+ enroll_status: "A",
328
+ entry_date: (enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
329
+ entry_comment: enrollment.entry_comment,
330
+ exit_date: (enrollment.exit_date || enrollment.entry_date || Date.today).strftime(DATE_FORMAT),
331
+ exit_comment: enrollment.exit_comment,
332
+ grade_level: enrollment.grade,
333
+ school_number: enrollment.school ? enrollment.school.number : nil
334
+ }.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }}
337
335
  end
338
336
 
339
337
  def convert_to_school_data(attrs)
@@ -347,21 +345,21 @@ module Bright
347
345
  cattrs[:address] = convert_to_address_data(address_attributes)
348
346
  end
349
347
  if (phone_number_attributes = attrs.dig("phones", "main", "number"))
350
- cattrs[:phone_number] = {:phone_number => phone_number_attributes}
348
+ cattrs[:phone_number] = {phone_number: phone_number_attributes}
351
349
  end
352
350
 
353
- cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
351
+ cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
354
352
  end
355
353
 
356
354
  def convert_from_address_data(address)
357
355
  {
358
- (address.type || "physcial") => {
359
- :street => "#{address.street} #{address.apt}", # powerschool doesn't appear to support passing the apt in the api
360
- :city => address.city,
361
- :state_province => address.state,
362
- :postal_code => address.postal_code,
363
- :grid_location => address.geographical_coordinates.to_s.gsub(",", ", ") # make sure there is a comma + space
364
- }.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
356
+ address.type || "physcial" => {
357
+ street: "#{address.street} #{address.apt}", # powerschool doesn't appear to support passing the apt in the api
358
+ city: address.city,
359
+ state_province: address.state,
360
+ postal_code: address.postal_code,
361
+ grid_location: address.geographical_coordinates.to_s.gsub(",", ", ") # make sure there is a comma + space
362
+ }.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
365
363
  }
366
364
  end
367
365
 
@@ -388,24 +386,24 @@ module Bright
388
386
  cattrs[:latitude], cattrs[:longitude] = lat_lng
389
387
  end
390
388
 
391
- cattrs.reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
389
+ cattrs.reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
392
390
  end
393
391
 
394
392
  def apply_expansions(params)
395
- if self.expansion_options.empty?
396
- hsh = self.request(:get, 'ws/v1/district/student', {:pagesize => 1, :q => "local_id==0"})
393
+ if expansion_options.empty?
394
+ hsh = request(:get, "ws/v1/district/student", {pagesize: 1, q: "local_id==0"})
397
395
  if hsh and hsh["students"]
398
396
  self.expansion_options = {
399
- :expansions => hsh["students"]["@expansions"].to_s.split(/\,\s?/),
400
- :extensions => hsh["students"]["@extensions"].to_s.split(/\,\s?/),
397
+ expansions: hsh["students"]["@expansions"].to_s.split(/,\s?/),
398
+ extensions: hsh["students"]["@extensions"].to_s.split(/,\s?/)
401
399
  }
402
400
  end
403
401
  end
404
402
 
405
403
  params.merge({
406
- :expansions => (%w(demographics addresses ethnicity_race phones contact contact_info) & (self.expansion_options[:expansions] || [])).join(","),
407
- :extensions => (%w(studentcorefields) & (self.expansion_options[:extensions] || [])).join(",")
408
- }.reject{|k,v| v.empty?})
404
+ expansions: (%w[demographics addresses ethnicity_race phones contact contact_info] & (expansion_options[:expansions] || [])).join(","),
405
+ extensions: (%w[studentcorefields] & (expansion_options[:extensions] || [])).join(",")
406
+ }.reject { |k, v| v.empty? })
409
407
  end
410
408
 
411
409
  def apply_options(params, options)
@@ -416,17 +414,17 @@ module Bright
416
414
 
417
415
  def headers_for_access_token
418
416
  {
419
- "Authorization" => "Basic #{Base64.strict_encode64("#{self.connection_options[:client_id]}:#{self.connection_options[:client_secret]}")}",
417
+ "Authorization" => "Basic #{Base64.strict_encode64("#{connection_options[:client_id]}:#{connection_options[:client_secret]}")}",
420
418
  "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
421
419
  }
422
420
  end
423
421
 
424
422
  def headers_for_auth
425
- self.retrieve_access_token if self.connection_options[:access_token].nil?
423
+ retrieve_access_token if connection_options[:access_token].nil?
426
424
  {
427
- "Authorization" => "Bearer #{self.connection_options[:access_token]}",
425
+ "Authorization" => "Bearer #{connection_options[:access_token]}",
428
426
  "Accept" => "application/json;charset=UTF-8",
429
- "Content-Type" =>"application/json;charset=UTF-8"
427
+ "Content-Type" => "application/json;charset=UTF-8"
430
428
  }
431
429
  end
432
430
  end
@@ -1,31 +1,29 @@
1
1
  module Bright
2
2
  module SisApi
3
3
  class Synergy < Base
4
-
5
4
  def get_student_by_api_id(api_id)
6
5
  raise NotImplementedError
7
6
  end
8
-
7
+
9
8
  def get_student(params)
10
9
  raise NotImplementedError
11
10
  end
12
-
11
+
13
12
  def get_students(params)
14
13
  raise NotImplementedError
15
14
  end
16
-
15
+
17
16
  def create_student(student)
18
17
  raise NotImplementedError
19
18
  end
20
-
19
+
21
20
  def update_student(student)
22
21
  raise NotImplementedError
23
22
  end
24
-
23
+
25
24
  def get_schools(params)
26
25
  raise NotImplementedError
27
26
  end
28
-
29
27
  end
30
28
  end
31
- end
29
+ end