ps_utilities 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d12612f8c4d8b6ce0ee6a52c4d30748c5ca12b1f8414478d0f2164f8aa79295e
4
- data.tar.gz: 5e0cbd4742dd42f98679cdea0356f1714e0ae23b878adba319cc1e33c7c901f4
3
+ metadata.gz: daddd46f3c769ec3b61c29558b7cc82d70ea60372eadf8b5b01bba22f1a37068
4
+ data.tar.gz: 31cdcb88c3c8e66a5fd1c5005cf00e62eb1a1d8cb8000db52ef63c1ef0437e51
5
5
  SHA512:
6
- metadata.gz: eb7bca650ace01f55b015bd52db6385c0b5d9fc1bdd99eac873bc6f9f4aebde2b05d51eb65226f9eab43f379d280daf8e423d03d461660810d7ecead03ed1322
7
- data.tar.gz: 44d0548cea631ab20b45d21667c96611321eac42f7f5ef11c21239abde10984ec1f25d013ada635a2c66fede989c11e20927b0be3ed3516dc59bc8a2344ae8e7
6
+ metadata.gz: 1aea5bd941ef10d5373fb9409aa04fece491cf148c1acce8d9a5000309e4c079818e41b954a7f91bfb11ac582c0fb1ac5f97bb16b9d631f149c4a83ec7d12839
7
+ data.tar.gz: 577b9af25d14b005a8e57126c00ace8e98021062dc4ef03e752067dea68ea206523d91564cc299c74643b5bf79408399c2b8e799daf7f6411089b3dcb86fa563
@@ -24,18 +24,19 @@ module PsUtilities
24
24
  # @note You should use environment variables to initialize your server.
25
25
  class Connection
26
26
 
27
- attr_reader :credentials, :headers, :base_uri, :auth_path, :version
27
+ attr_reader :credentials, :headers, :base_uri, :auth_path, :auth_token
28
+ attr_reader :version
28
29
 
29
30
  include PsUtilities::PreBuiltGet
30
31
  include PsUtilities::PreBuiltPut
31
32
  include PsUtilities::PreBuiltPost
32
33
 
33
34
  def initialize(attributes: {}, headers: {})
35
+ @version = "v#{PsUtilities::Version::VERSION}"
34
36
  @credentials = attr_defaults.merge(attributes)
35
- @headers = header_defaults.merge(headers)
36
37
  @base_uri = credentials[:base_uri]
37
38
  @auth_path = credentials[:auth_endpoint]
38
- @version = "v#{PsUtilities::Version::VERSION}"
39
+ @headers = header_defaults.merge(headers)
39
40
 
40
41
  raise ArgumentError, "missing client_secret" if credentials[:client_secret].nil? or
41
42
  credentials[:client_secret].empty?
@@ -45,24 +46,14 @@ module PsUtilities
45
46
  credentials[:base_uri].empty?
46
47
  end
47
48
 
48
- # with no command it just authenticates
49
- def run(command: nil, params: {}, api_path: "", options: {})
49
+ # with no command it just checks authenticates if needed
50
+ def run(command: nil, api_path: "", options: {}, params: {})
50
51
  authenticate unless token_valid?
52
+ @headers[:headers].merge!('Authorization' => 'Bearer ' + authorized_token)
51
53
  case command
52
54
  when nil, :authenticate
53
- # authenticate unless token_valid?
54
- # when :get
55
- # api(:get, api_path, options) unless api_path.empty?
56
- # when :put
57
- # send(:api, :put, api_path, options) unless api_path.empty?
58
- # when :post
59
- # api(, api_path, options) unless api_path.empty?
60
- when :get, :put, :post
55
+ when :delete, :get, :patch, :post, :put
61
56
  api(command, api_path, options) unless api_path.empty?
62
- # when :get, :put, :post
63
- # send(command, api_path, options) unless api_path.empty?
64
- # when :get, :put, :post
65
- # send(:api, command, api_path, options) unless api_path.empty?
66
57
  else
67
58
  send(command, params)
68
59
  end
@@ -70,71 +61,22 @@ module PsUtilities
70
61
 
71
62
  private
72
63
 
73
- # options = {query: {}}
74
- def api(verb, api_path, options={})
75
- count = 0
76
- retries = 3
77
- ps_url = base_uri + api_path
78
- options = options.merge(headers)
79
- begin
80
- HTTParty.send(verb, ps_url, options)
81
- rescue Net::ReadTimeout, Net::OpenTimeout
82
- if count < retries
83
- count += 1
84
- retry
85
- else
86
- { error: "no response (timeout) from URL: #{url}" }
87
- end
88
- end
64
+ def authorized_token
65
+ "#{credentials[:access_token]}"
89
66
  end
90
67
 
91
- # options = {query: {}}
92
- def get(api_path, options={})
93
- count = 0
94
- retries = 3
95
- ps_url = base_uri + api_path
96
- options = options.merge(headers)
97
- begin
98
- HTTParty.get(ps_url, options)
99
- # self.class.get(url, query: options[:query], headers: options[:headers])
100
- rescue Net::ReadTimeout, Net::OpenTimeout
101
- if count < retries
102
- count += 1
103
- retry
104
- else
105
- { error: "no response (timeout) from URL: #{url}" }
106
- end
107
- end
108
- end
109
-
110
- # options = {body: {}}
111
- def put(api_path, options={})
112
- count = 0
113
- retries = 3
114
- ps_url = base_uri + api_path
115
- options = options.merge(headers)
116
- begin
117
- HTTParty.get(ps_url, options)
118
- # self.class.get(url, query: options[:query], headers: options[:headers])
119
- rescue Net::ReadTimeout, Net::OpenTimeout
120
- if count < retries
121
- count += 1
122
- retry
123
- else
124
- { error: "no response (timeout) from URL: #{url}" }
125
- end
126
- end
127
- end
128
-
129
- # options = {body: {}}
130
- def post(api_path, options={})
68
+ # verb = :delete, :get, :patch, :post, :put
69
+ # options = {query: {}, body: {}}
70
+ # get usually needs a query info
71
+ # put usually needs a body with data
72
+ def api(verb, api_path, options={})
131
73
  count = 0
132
74
  retries = 3
133
75
  ps_url = base_uri + api_path
134
76
  options = options.merge(headers)
77
+ pp options
135
78
  begin
136
- HTTParty.get(ps_url, options)
137
- # self.class.get(url, query: options[:query], headers: options[:headers])
79
+ HTTParty.send(verb, ps_url, options)
138
80
  rescue Net::ReadTimeout, Net::OpenTimeout
139
81
  if count < retries
140
82
  count += 1
@@ -147,15 +89,13 @@ module PsUtilities
147
89
 
148
90
  # In PowerSchool go to System>System Settings>Plugin Management Configuration>your plugin>Data Provider Configuration to manually check plugin expiration date
149
91
  def authenticate
150
- @headers[:headers] ||= {}
151
92
  ps_url = base_uri + auth_path
152
- # ps_url = credentials[:base_uri] + credentials[:auth_endpoint]
153
93
  response = HTTParty.post(ps_url, {headers: auth_headers,
154
94
  body: 'grant_type=client_credentials'})
155
95
 
156
96
  @credentials[:token_expires] = Time.now + response.parsed_response['expires_in'].to_i
157
97
  @credentials[:access_token] = response.parsed_response['access_token'].to_s
158
- @headers[:headers].merge!('Authorization' => 'Bearer ' + credentials[:access_token])
98
+ # @headers[:headers].merge!('Authorization' => 'Bearer ' + credentials[:access_token])
159
99
 
160
100
  # throw error if no token returned -- nothing else will work
161
101
  raise AuthError.new("No Auth Token Returned",
@@ -190,8 +130,6 @@ module PsUtilities
190
130
  auth_endpoint: ENV['PS_AUTH_ENDPOINT'] || '/oauth/access_token',
191
131
  client_id: ENV['PS_CLIENT_ID'],
192
132
  client_secret: ENV['PS_CLIENT_SECRET'],
193
- # not recommended here - it changes (ok as a parameter though)
194
- # access_token: ENV['PS_ACCESS_TOKEN'] || nil,
195
133
  }
196
134
  end
197
135
 
@@ -2,31 +2,151 @@ module PsUtilities
2
2
 
3
3
  module PreBuiltGet
4
4
 
5
- def get_active_students_count(params={})
6
- # api_path = "/ws/v1/district/student/count?q=school_enrollment.enroll_status_code==0"
7
- api_path = "/ws/v1/district/student/count"
8
- options = { query: {"q" => "school_enrollment.enroll_status_code==0"} }
9
- get(api_path, options)
5
+ def get_all_active_students(params={})
6
+ params[:status_code] = 0
7
+ get_all_matching_students(params)
10
8
  end
11
9
 
12
- def get_active_students_info(params={})
13
- # api_path = "/ws/v1/district/student?q=school_enrollment.enroll_status==a&pagesize=500"
14
- api_path = "/ws/v1/district/student"
15
- options = { query:
16
- {"q" => "school_enrollment.enroll_status_code==0",
17
- "pagesize" => "500"} }
18
- get(api_path, options)
10
+ # params = {username: "xxxxxxx"} or {local_id: "12345"}
11
+ # or {enroll_status: "x"} or {status_code: "0"}
12
+ # or {first_name: "John"} or {last_name: "Brown"}
13
+ # api_path = "/ws/v1/district/student?expansions=school_enrollment,contact&q=enroll_status==A;name.last_name==J*"
14
+ def get_all_matching_students(params)
15
+ params[:page_size] ||= 100
16
+ count = get_matching_students_count(params)
17
+ pages = calc_pages(count, params[:page_size])
18
+ answer = {}
19
+ students = []
20
+ (1..pages).each do |page|
21
+ params[:page_number] = page
22
+ answer = get_matching_students_page(params)
23
+ students << (answer.dig("students","student") || [])
24
+ end
25
+ # answer["students"]["student"] = students.flatten
26
+ # return answer
27
+ { students: students.flatten }
19
28
  end
29
+ # {students: [
30
+ # {"id"=>4916, "local_id"=>112406, "student_username"=>"cccc406", "name"=>{"first_name"=>"Ssssss", "last_name"=>"CCCCC"}},
31
+ # {"id"=>4932, "local_id"=>112520, "student_username"=>"jjjj520", "name"=>{"first_name"=>"Ppppppp", "last_name"=>"JJJJJJJJ"}},
32
+ # {"id"=>4969, "local_id"=>112766, "student_username"=>"aaaa766", "name"=>{"first_name"=>"Sssss", "middle_name"=>"Aaaaaaaa", "last_name"=>"Aaaaaaaaaa"}}
33
+ # ]
34
+ # }
20
35
 
21
- # params = {username: "xxxxxxx"}
22
- def get_one_student_record(params)
36
+ # params = {username: "xxxxxxx"} or {local_id: "12345"}
37
+ def get_one_student(params)
23
38
  # api_path = "/ws/v1/district/student?expansions=school_enrollment,contact&q=student_username==xxxxxx237"
39
+ api_path = "/ws/v1/district/student"
40
+ options = {query:
41
+ {"expansions" => "school_enrollment,contact,contact_info"}}
42
+ query = []
43
+ query << "student_username==#{params[:username]}" if params.has_key?(:username)
44
+ query << "local_id==#{params[:local_id]}" if params.has_key?(:local_id)
45
+
46
+ options[:query]["q"] = query.join(";")
47
+ return {"errorMessage"=>{"message"=>"A valid parameter must be entered."}} if query.empty?
48
+
49
+ answer = api(:get, api_path, options)
50
+ { student: (answer.dig("students","student") || []) }
51
+ end
52
+ # {student:
53
+ # {"id"=>5023,
54
+ # "local_id"=>112193,
55
+ # "student_username"=>"xxxxxxx193",
56
+ # "name"=>{"first_name"=>"Aaaaaaaaa", "last_name"=>"EEEEEEEEE"},
57
+ # "school_enrollment"=>
58
+ # {"enroll_status"=>"A",
59
+ # "enroll_status_description"=>"Active",
60
+ # "enroll_status_code"=>0,
61
+ # "grade_level"=>12,
62
+ # "entry_date"=>"2017-08-25",
63
+ # "exit_date"=>"2018-06-09",
64
+ # "school_number"=>33,
65
+ # "school_id"=>6,
66
+ # "entry_comment"=>"Promote Same School",
67
+ # "full_time_equivalency"=>{"fteid"=>1070, "name"=>"FTE Value: 1"}
68
+ # },
69
+ # "contact"=>
70
+ # {"guardian_email"=>"parent1@example.fr,parent2@example.ch", "mother"=>"EEEEEEE, Vvvvv", "father"=>"EEEEEEEE, Sssssss"},
71
+ # "contact_info"=>{"email"=>"xxxxxxx193@xxxx.de"}
72
+ # }
73
+ # }
74
+
75
+ private
76
+ # given page_size = 100
77
+ # 430 kids = 5 pages
78
+ # 400 kids = 4 pages
79
+ def calc_pages(count, page_size)
80
+ max_page = ( (count.to_i-1) / page_size.to_i ).to_i + 1
81
+ end
82
+ # 5
83
+
84
+ # api_path = "/ws/v1/district/student/count?q=school_enrollment.enroll_status_code==0"
85
+ # returns: {"resource"=>{"count"=>423}}
86
+ def get_matching_students_count(params={})
87
+ api_path = "/ws/v1/district/student/count"
88
+
89
+ query = []
90
+ query << "student_username==#{params[:username]}" if params.has_key?(:username)
91
+ query << "local_id==#{params[:local_id]}" if params.has_key?(:local_id)
92
+ query << "name.last_name==#{params[:last_name]}" if params.has_key?(:last_name)
93
+ query << "name.first_name==#{params[:first_name]}" if params.has_key?(:first_name)
94
+ query << "school_enrollment.enroll_status==#{params[:enroll_status]}" if params.has_key?(:enroll_status)
95
+ query << "school_enrollment.enroll_status_code==#{params[:status_code]}" if params.has_key?(:status_code)
96
+
97
+ options = {query: {"q" => query.join(";")} }
98
+ pp options
99
+ return {"errorMessage"=>{"message"=>"A valid parameter must be entered."}} if query.empty?
100
+
101
+ answer = api(:get, api_path, options) # {"resource"=>{"count"=>423}}
102
+ answer.dig("resource", "count").to_i
103
+ end
104
+ # 423
105
+
106
+ # params = {username: "xxxxxxx"} or {local_id: "12345"}
107
+ # or {enroll_status: "x"} or {status_code: "0"}
108
+ # or {first_name: "John"} or {last_name: "Brown"}
109
+ # api_path = "/ws/v1/district/student?expansions=school_enrollment,contact&q=student_username==xxxxxx237"
110
+ def get_matching_students_page(params)
24
111
  api_path = "/ws/v1/district/student"
25
- options = { query:
26
- { "q" => "student_username==#{params[:username]}",
27
- "expansions" => "school_enrollment,contact,contact_info"} }
28
- get(api_path, options)
112
+ params[:page_size] ||= 100
113
+ params[:page_number] ||= 1
114
+ pp params
115
+ options = { query:
116
+ { "pagesize" => "#{params[:page_size]}",
117
+ "page" => "#{params[:page_number]}"} }
118
+ query = []
119
+ query << "student_username==#{params[:username]}" if params.has_key?(:username)
120
+ query << "local_id==#{params[:local_id]}" if params.has_key?(:local_id)
121
+ query << "name.last_name==#{params[:last_name]}" if params.has_key?(:last_name)
122
+ query << "name.first_name==#{params[:first_name]}" if params.has_key?(:first_name)
123
+ query << "school_enrollment.enroll_status==#{params[:enroll_status]}" if params.has_key?(:enroll_status)
124
+ query << "school_enrollment.enroll_status_code==#{params[:status_code]}" if params.has_key?(:status_code)
125
+
126
+ options[:query]["q"] = query.join(";")
127
+ return {"errorMessage"=>{"message"=>"A valid parameter must be entered."}} if query.empty?
128
+ pp options
129
+ api(:get, api_path, options)
29
130
  end
131
+ # {"students"=>
132
+ # {"@expansions"=>
133
+ # "demographics, addresses, alerts, phones, school_enrollment, ethnicity_race, contact, contact_info, initial_enrollment, schedule_setup, fees, lunch",
134
+ # "@extensions"=>
135
+ # "s_stu_crdc_x,activities,c_studentlocator,u_students_extension,u_studentsuserfields,s_stu_ncea_x,s_stu_edfi_x,studentcorefields",
136
+ # "student"=>
137
+ # [{"id"=>4916, "local_id"=>112406, "student_username"=>"cccc406", "name"=>{"first_name"=>"Ssssss", "last_name"=>"CCCCC"}},
138
+ # {"id"=>4932,
139
+ # "local_id"=>112520,
140
+ # "student_username"=>"jjjjjjjj520",
141
+ # "name"=>{"first_name"=>"Ppppppp", "last_name"=>"JJJJJJJJ"}},
142
+ # {"id"=>4969,
143
+ # "local_id"=>112766,
144
+ # "student_username"=>"aaaaaaaa766",
145
+ # "name"=>{"first_name"=>"Sssss", "middle_name"=>"Aaaaaaaa", "last_name"=>"Aaaaaaaaaa"}}
146
+ # ]
147
+ # }
148
+ # }
149
+
30
150
 
31
151
  end
32
152
 
@@ -1,5 +1,5 @@
1
1
  module PsUtilities
2
2
  module Version
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ps_utilities
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Weisbecker
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-06-21 00:00:00.000000000 Z
12
+ date: 2018-06-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty