bright 1.2.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,276 +0,0 @@
1
- module Bright
2
- module SisApi
3
- class Skyward < Base
4
-
5
- @@description = "Connects to the Skyward API for accessing student information"
6
- @@doc_url = "https://esdemo1.skyward.com/api/swagger/ui/index"
7
- @@api_version = "v1"
8
-
9
- attr_accessor :connection_options, :schools_cache
10
-
11
- DEMOGRAPHICS_CONVERSION = {
12
- "I"=>"American Indian Or Alaska Native",
13
- "A"=>"Asian",
14
- "B"=>"Black Or African American",
15
- "P"=>"Native Hawaiian Or Other Pacific Islander",
16
- "W"=>"White"
17
- }
18
-
19
- PHONE_TYPE_CONVERSION = {
20
- "Cellular" => "Cell",
21
- "Work" => "Work",
22
- "Home" => "Home",
23
- "Other" => "Other"
24
- }
25
-
26
- def initialize(options = {})
27
- self.connection_options = options[:connection] || {}
28
- # {
29
- # :client_id => "",
30
- # :client_secret => "",
31
- # :uri => "https://skywardinstall.com/API"
32
- # }
33
- end
34
-
35
- def get_student_by_api_id(api_id, params = {})
36
- st_hsh = self.request(:get, "v1/students/#{api_id}", params)[:parsed_body]
37
- Student.new(convert_to_user_data(st_hsh, {:type => "Student"})) unless st_hsh.blank?
38
- end
39
-
40
- def get_students(params = {}, options = {})
41
- params["paging.limit"] = params[:limit] || options[:limit] || 1000
42
- students_response = self.request(:get, 'v1/students', params)
43
- if !students_response[:parsed_body].blank?
44
- students = students_response[:parsed_body].compact.collect {|st_hsh|
45
- Student.new(convert_to_user_data(st_hsh, {:type => "Student"}))
46
- }
47
- end
48
-
49
- next_cursor = nil
50
- if students_response[:headers]["Link"]
51
- students_response[:headers]["Link"].split(",").each do |part, index|
52
- section = part.split(';')
53
- url = section[0][/<(.*)>/,1]
54
- name = section[1][/rel="(.*)"/,1].to_s
55
- if name == "next"
56
- next_cursor = CGI.parse(URI.parse(url).query)["cursor"].first
57
- end
58
- end
59
- end
60
- if options[:wrap_in_collection] != false
61
- api = self
62
- load_more_call = proc {|cursor|
63
- params["paging.cursor"] = cursor
64
- options = {:wrap_in_collection => false, :include_cursor => true}
65
- api.get_students(params, options)
66
- }
67
- CursorResponseCollection.new({
68
- :seed_page => students,
69
- :load_more_call => load_more_call,
70
- :next_cursor => next_cursor
71
- })
72
- elsif options[:include_cursor] == true
73
- return {:objects => students, :next_cursor => next_cursor}
74
- else
75
- return students
76
- end
77
- end
78
-
79
- def get_school_by_api_id(api_id, params = {})
80
- sc_hsh = self.request(:get, "v1/schools/#{api_id}", params)[:parsed_body]
81
- School.new(convert_to_school_data(sc_hsh)) unless sc_hsh.blank?
82
- end
83
-
84
- def get_schools(params = {}, options = {})
85
- params["paging.limit"] = params[:limit] || options[:limit] || 10000
86
- schools_hshs = self.request(:get, "v1/schools", params)[:parsed_body]
87
- if !schools_hshs.blank?
88
- schools = schools_hshs.compact.collect {|sc_hsh|
89
- School.new(convert_to_school_data(sc_hsh))
90
- }
91
- end
92
- return schools
93
- end
94
-
95
- def get_contact_by_api_id(api_id, params = {})
96
- contact_hsh = self.request(:get, "v1/names/#{api_id}", params)[:parsed_body]
97
- Contact.new(convert_to_user_data(contact_hsh, {:type => "Contact"})) unless contact_hsh.blank?
98
- end
99
-
100
- def get_guardians_by_api_id(api_id, params = {})
101
- guardians = []
102
- guardians_array = self.request(:get, "v1/guardians", params.merge({"studentNameId" => api_id}))[:parsed_body]
103
- if !guardians_array.blank?
104
- guardians_array.each do |guardian_hsh|
105
- relationship_type = guardian_hsh.delete("Students").detect{|s_hsh| s_hsh["StudentNameId"].to_s == api_id.to_s}["RelationshipDesc"]
106
- guardian_hsh["RelationshipType"] = relationship_type
107
- guardian_hsh["NameId"] = guardian_hsh.delete("GuardianNameId")
108
- guardians << Contact.new(convert_to_user_data(guardian_hsh, {:type => "Contact"}))
109
- end
110
- end
111
- return guardians
112
- end
113
-
114
- def retrieve_access_token
115
- connection = Bright::Connection.new("#{self.connection_options[:uri]}/token")
116
- response = connection.request(:post,
117
- {"grant_type" => "password",
118
- "username" => self.connection_options[:client_id],
119
- "password" => self.connection_options[:client_secret]
120
- },
121
- self.headers_for_access_token)
122
- if !response.error?
123
- response_hash = JSON.parse(response.body)
124
- end
125
- if response_hash["access_token"]
126
- self.connection_options[:access_token] = response_hash["access_token"]
127
- self.connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
128
- end
129
- response_hash
130
- end
131
-
132
- def request(method, path, params = {})
133
- uri = "#{self.connection_options[:uri]}/#{path}"
134
- body = nil
135
- if method == :get
136
- query = URI.encode_www_form(params)
137
- uri += "?#{query}"
138
- else
139
- body = JSON.dump(params)
140
- end
141
-
142
- response = connection_retry_wrapper {
143
- connection = Bright::Connection.new(uri)
144
- headers = self.headers_for_auth
145
- connection.request(method, body, headers)
146
- }
147
-
148
- if !response.error?
149
- response_hash = JSON.parse(response.body)
150
- else
151
- puts "#{response.inspect}"
152
- puts "#{response.body}"
153
- end
154
- return {:parsed_body => response_hash, :headers => response.headers}
155
- end
156
-
157
- protected
158
-
159
- def convert_to_user_data(user_params, options = {})
160
- # :type => "Contact" || "Student"
161
- return {} if user_params.blank?
162
-
163
- user_data_hsh = {
164
- :api_id => user_params["NameId"],
165
- :first_name => user_params["FirstName"],
166
- :middle_name => user_params["MiddleName"],
167
- :last_name => user_params["LastName"],
168
- :sis_student_id => user_params["DisplayId"],
169
- :state_student_id => user_params["StateId"],
170
- :projected_graduation_year => user_params["GradYr"],
171
- :gender => user_params["Gender"],
172
- :hispanic_ethnicity => user_params["HispanicLatinoEthnicity"],
173
- :relationship_type => user_params["RelationshipType"]
174
- }.reject{|k,v| v.blank?}
175
- unless user_params["DateOfBirth"].blank?
176
- user_data_hsh[:birth_date] = Date.parse(user_params["DateOfBirth"]).to_s
177
- end
178
-
179
- DEMOGRAPHICS_CONVERSION.each do |demographics_key, demographics_value|
180
- if user_params["FederalRace"].to_s.upcase.include?(demographics_key)
181
- user_data_hsh[:race] ||= []
182
- user_data_hsh[:race] << demographics_value
183
- end
184
- end
185
-
186
- unless user_params["SchoolEmail"].blank?
187
- user_data_hsh[:email_address] = {
188
- :email_address => user_params["SchoolEmail"]
189
- }
190
- end
191
-
192
- unless user_params["Email"].blank?
193
- user_data_hsh[:email_address] = {
194
- :email_address => user_params["Email"]
195
- }
196
- end
197
-
198
- unless user_params["DefaultSchoolId"].blank?
199
- self.schools_cache ||= {}
200
- if (attending_school = self.schools_cache[user_params["DefaultSchoolId"]]).nil?
201
- attending_school = self.get_school_by_api_id(user_params["DefaultSchoolId"])
202
- self.schools_cache[attending_school.api_id] = attending_school
203
- end
204
- user_data_hsh[:school] = attending_school
205
- end
206
-
207
- unless user_params["StreetAddress"].blank?
208
- user_data_hsh[:addresses] = [{
209
- :street => user_params["StreetAddress"],
210
- :city => user_params["City"],
211
- :state => user_params["State"],
212
- :postal_code => user_params["ZipCode"]
213
- }]
214
- end
215
-
216
- ["PhoneNumber", "PhoneNumber2", "PhoneNumber3"].each do |phone_param|
217
- if user_params[phone_param].present? && user_params["#{phone_param}Type"].present?
218
- user_data_hsh[:phone_numbers] ||= []
219
- user_data_hsh[:phone_numbers] << {
220
- :phone_number => user_params[phone_param],
221
- :type => PHONE_TYPE_CONVERSION[user_params["#{phone_param}Type"]]
222
- }
223
- end
224
- end
225
-
226
- if options[:type] == "Student"
227
- #generate the contacts for a student
228
- user_data_hsh[:contacts] = self.get_guardians_by_api_id(user_data_hsh[:api_id])
229
- end
230
-
231
- return user_data_hsh
232
- end
233
-
234
- def convert_to_school_data(school_params)
235
- return {} if school_params.nil?
236
-
237
- school_data_hsh = {
238
- :api_id => school_params["SchoolId"],
239
- :name => school_params["SchoolName"],
240
- :low_grade => school_params["GradeLow"],
241
- :high_grade => school_params["GradeHigh"],
242
- }
243
-
244
- unless school_params["StreetAddress"].blank?
245
- school_data_hsh[:address] = {
246
- :street => school_params["StreetAddress"],
247
- :city => school_params["City"],
248
- :state => school_params["State"],
249
- :postal_code => school_params["ZipCode"]
250
- }
251
- end
252
-
253
- return school_data_hsh
254
- end
255
-
256
- def headers_for_access_token
257
- {
258
- "Authorization" => "Basic #{Base64.strict_encode64("#{self.connection_options[:client_id]}:#{self.connection_options[:client_secret]}")}",
259
- "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
260
- }
261
- end
262
-
263
- def headers_for_auth
264
- if self.connection_options[:access_token].nil? or self.connection_options[:access_token_expires] < Time.now
265
- self.retrieve_access_token
266
- end
267
- {
268
- "Authorization" => "Bearer #{self.connection_options[:access_token]}",
269
- "Accept" => "application/json;charset=UTF-8",
270
- "Content-Type" =>"application/json;charset=UTF-8"
271
- }
272
- end
273
-
274
- end
275
- end
276
- end