ps_utilities 0.2.1 → 0.3.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 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