openapply 0.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 +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +506 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/demo/.rbenv-vars +5 -0
- data/examples/demo/Gemfile +6 -0
- data/examples/demo/Gemfile.lock +17 -0
- data/examples/demo/README.md +56 -0
- data/examples/demo/demo_site.rb +94 -0
- data/lib/openapply/get_student.rb +277 -0
- data/lib/openapply/get_students.rb +399 -0
- data/lib/openapply/put.rb +3 -0
- data/lib/openapply/version.rb +3 -0
- data/lib/openapply.rb +125 -0
- data/openapply.gemspec +48 -0
- metadata +163 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
## Usage
|
2
|
+
Start irb
|
3
|
+
```bash
|
4
|
+
bundle install
|
5
|
+
|
6
|
+
# irb
|
7
|
+
# or
|
8
|
+
pry
|
9
|
+
```
|
10
|
+
|
11
|
+
and run this code (or play )
|
12
|
+
```ruby
|
13
|
+
require 'pp'
|
14
|
+
require 'openapply'
|
15
|
+
require_relative './demo_site'
|
16
|
+
|
17
|
+
|
18
|
+
# BASIC USAGE (see readme)
|
19
|
+
# use the .rbenv-vars for a simple setup
|
20
|
+
@oa = Openapply::Client.new()
|
21
|
+
@oa.one_student_record_by_id(95)
|
22
|
+
|
23
|
+
# see settings
|
24
|
+
@oa.api_url
|
25
|
+
@oa.api_key
|
26
|
+
@oa.base_path
|
27
|
+
@oa.api_timeout
|
28
|
+
@oa.api_reply_count
|
29
|
+
# replace record_count with reply count
|
30
|
+
# @oa.reply_count
|
31
|
+
```
|
32
|
+
|
33
|
+
* or More advanced - multiple OA sites
|
34
|
+
```ruby
|
35
|
+
|
36
|
+
require 'pp'
|
37
|
+
require 'openapply'
|
38
|
+
require_relative './demo_site'
|
39
|
+
|
40
|
+
# use a class override in order to interact with multiple oa sites
|
41
|
+
@demo = DemoSite.new()
|
42
|
+
|
43
|
+
# get 5 summary records
|
44
|
+
hash = @demo.custom_student_summaries('applied', nil, nil, 5)
|
45
|
+
|
46
|
+
# get all students
|
47
|
+
hash = students_by_status('applied')
|
48
|
+
array = @demo.students_hash_to_students_array(hash)
|
49
|
+
csv_1 = @demo.students_array_into_csv_string(array)
|
50
|
+
# @demo.send_csv_to_server(csv_1, 'host.example.io', 'user', '/home/user/file1.csv')
|
51
|
+
|
52
|
+
# SLOW takes minutes
|
53
|
+
csv_2 = @demo.student_ids_names_by_status_to_csv('applied')
|
54
|
+
# @demo.send_csv_to_server(csv_2, 'host.example.io', 'user', '/home/user/file2.csv')
|
55
|
+
|
56
|
+
```
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
require 'net/scp'
|
5
|
+
require 'stringio'
|
6
|
+
require 'httparty'
|
7
|
+
|
8
|
+
class DemoSite < Openapply::Client
|
9
|
+
include HTTParty
|
10
|
+
|
11
|
+
# these next two are needed in a subclass to interact with multiple OA sites
|
12
|
+
localized_url = ENV['OA_BASE_URI']
|
13
|
+
base_uri localized_url
|
14
|
+
|
15
|
+
def api_key
|
16
|
+
ENV['OA_AUTH_TOKEN']
|
17
|
+
end
|
18
|
+
|
19
|
+
# Business logic: create a csv file of a given status & transfer it
|
20
|
+
|
21
|
+
def student_ids_names_by_status_to_csv(status)
|
22
|
+
# best is to check if status is in the list of valid statuses
|
23
|
+
return { error: "no status"} if status.to_s.eql? ""
|
24
|
+
|
25
|
+
# # this next step is slow (for 100 kids) - investigate
|
26
|
+
# student_hash = all_students_all_data_by_status(status)
|
27
|
+
student_hash = students_by_status(status)
|
28
|
+
|
29
|
+
|
30
|
+
student_array = students_hash_to_students_array(student_hash)
|
31
|
+
student_csv = students_array_into_csv_string(student_array)
|
32
|
+
end
|
33
|
+
|
34
|
+
def students_hash_to_students_array(hash)
|
35
|
+
array = []
|
36
|
+
csv_keys = [:id, :first_name, :last_name]
|
37
|
+
|
38
|
+
headers = csv_keys.map{|k| k.to_s}
|
39
|
+
# headers = ['id','first_name','last_name']
|
40
|
+
puts headers
|
41
|
+
|
42
|
+
array << headers
|
43
|
+
|
44
|
+
# don't loop if hash is empty
|
45
|
+
return headers if hash.empty?
|
46
|
+
|
47
|
+
hash[:students].each do |record|
|
48
|
+
row = []
|
49
|
+
# skip record if empty
|
50
|
+
# puts "#{record[:record]}\n"
|
51
|
+
next if record.nil?
|
52
|
+
next if record.nil?
|
53
|
+
next if record.empty?
|
54
|
+
|
55
|
+
# find the desired fields and add them to the csv
|
56
|
+
csv_keys.each{ |key| row << record[key] }
|
57
|
+
|
58
|
+
# add row to the master arrary
|
59
|
+
array << row
|
60
|
+
end
|
61
|
+
return array
|
62
|
+
end
|
63
|
+
|
64
|
+
def students_array_into_csv_string(array)
|
65
|
+
return "" if array.nil?
|
66
|
+
return "" if array.empty?
|
67
|
+
# https://stackoverflow.com/questions/4822422/output-array-to-csv-in-ruby
|
68
|
+
csv_string = CSV.generate do |csv|
|
69
|
+
array.each do |row|
|
70
|
+
csv << row
|
71
|
+
end
|
72
|
+
end
|
73
|
+
return csv_string
|
74
|
+
end
|
75
|
+
|
76
|
+
def send_csv_to_server(csv_string, host_name, user_name, remote_path_n_file)
|
77
|
+
# https://www.safaribooksonline.com/library/view/ruby-cookbook/0596523696/ch06s15.html
|
78
|
+
xfer_csv = StringIO.new( csv_string )
|
79
|
+
|
80
|
+
# setup using an SSH KEY instead of password
|
81
|
+
# http://www.rubydoc.info/github/delano/net-scp/Net/SCP
|
82
|
+
Net::SCP.start(host_name, user_name) do |scp|
|
83
|
+
# asynchronous upload; call returns immediately
|
84
|
+
channel = scp.upload( xfer_csv, remote_path_n_file )
|
85
|
+
channel.wait
|
86
|
+
end
|
87
|
+
# ensure file has proper permissions
|
88
|
+
Net::SSH.start(host_name, user_name) do |ssh|
|
89
|
+
# Capture all stderr and stdout output from a remote process
|
90
|
+
output = ssh.exec!("chmod 0775 #{remote_path_n_file}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
module Get
|
2
|
+
|
3
|
+
# Record details for ONE student - this API return has the parent info 2x!
|
4
|
+
#
|
5
|
+
# @param
|
6
|
+
# ==== Attributes
|
7
|
+
# * +student_id+ - openapply student_id
|
8
|
+
# * +options+ - see httparty options
|
9
|
+
#
|
10
|
+
# ==== Example code
|
11
|
+
# @demo = Openapply.new
|
12
|
+
# @demo.student_by_id(96)
|
13
|
+
#
|
14
|
+
# ==== Result
|
15
|
+
# {:student=>
|
16
|
+
# {:id=>96,
|
17
|
+
# :serial_number=>86,
|
18
|
+
# :custom_id=>"86",
|
19
|
+
# :applicant_id=>"00000086",
|
20
|
+
# :email=>"Jerry.Patel@eduvo.com",
|
21
|
+
# :first_name=>"Jerry",
|
22
|
+
# :last_name=>"Patel",
|
23
|
+
# ...,
|
24
|
+
# :profile_photo=>
|
25
|
+
# "https://openapply-sandbox-devel-01.s3.amazonaws.com/uploads/student/avatar/000/000/096/m_9.jpg?v=1499755604",
|
26
|
+
# :profile_photo_updated_at=>"2017-07-11T14:46:44.000+08:00",
|
27
|
+
# :custom_fields=>
|
28
|
+
# {:language=>"Hindi",
|
29
|
+
# :nationality=>"Indian (India)",
|
30
|
+
# :referral_source=>"Friends",
|
31
|
+
# :middle_name_s=>"Danesh",
|
32
|
+
# :mobile_phone=>"852 4545 1195",
|
33
|
+
# ...,
|
34
|
+
# :school_file=>
|
35
|
+
# {:id=>73,
|
36
|
+
# :filename=>"Robert_Patel_Report.pdf",
|
37
|
+
# :url=>"https://demo.openapply.com/api/v1/secure_download/files/73"},
|
38
|
+
# :has_your_child_attended_school_regularly=>"Yes",
|
39
|
+
# ...,
|
40
|
+
# :parent_guardian=>
|
41
|
+
# [{:id=>268,
|
42
|
+
# :serial_number=>257,
|
43
|
+
# :custom_id=>"257",
|
44
|
+
# :name=>"James Patel",
|
45
|
+
# :first_name=>"James",
|
46
|
+
# :last_name=>"Patel",
|
47
|
+
# ...,
|
48
|
+
# :custom_fields=>
|
49
|
+
# {:title=>"CFO",
|
50
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
51
|
+
# :home_telephone=>"",
|
52
|
+
# ...,
|
53
|
+
# :parent_residency=>"Citizen"}},
|
54
|
+
# {:id=>267,
|
55
|
+
# :serial_number=>256,
|
56
|
+
# :custom_id=>"256",
|
57
|
+
# ...,
|
58
|
+
# :profile_photo=>
|
59
|
+
# "https://openapply-sandbox-devel-01.s3.amazonaws.com/uploads/parent/avatar/000/000/267/patel_mom.jpg?v=1499755607",
|
60
|
+
# :profile_photo_updated_at=>"2017-07-11T14:46:47.000+08:00",
|
61
|
+
# :parent_id=>"256",
|
62
|
+
# :custom_fields=>
|
63
|
+
# {:title=>"",
|
64
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
65
|
+
# ...,
|
66
|
+
# :parent_prior_countries_list=>nil,
|
67
|
+
# :parent_residency=>"Citizen"}}],
|
68
|
+
# :siblings_information=>
|
69
|
+
# [{:first_name=>"Deidre",
|
70
|
+
# :last_name=>"Patel",
|
71
|
+
# :gender=>"Female",
|
72
|
+
# :birth_date=>"2008-06-06"}],
|
73
|
+
# :emergency_contact=>[],
|
74
|
+
# :prior_school_list=>
|
75
|
+
# [{:school_name=>"Michael Varner Elementary",
|
76
|
+
# :school_country=>"United States",
|
77
|
+
# :school_contact_name=>"Ann Farris",
|
78
|
+
# :school_contact_phone=>"(415) 777-0876"},
|
79
|
+
# {:school_name=>"ISS International School",
|
80
|
+
# :school_contact_name=>"Taylor Michaels",
|
81
|
+
# :school_contact_phone=>"65 6235 5844",
|
82
|
+
# :school_country=>"Singapore"}],
|
83
|
+
# :immunization_record=>[],
|
84
|
+
# :health_information=>[]},
|
85
|
+
# :parent_ids=>[268, 267]},
|
86
|
+
# :linked=>
|
87
|
+
# {:parents=>
|
88
|
+
# [{:id=>268,
|
89
|
+
# :serial_number=>257,
|
90
|
+
# :custom_id=>"257",
|
91
|
+
# :name=>"James Patel",
|
92
|
+
# :first_name=>"James",
|
93
|
+
# :last_name=>"Patel",
|
94
|
+
# ...,
|
95
|
+
# :address=>"1641 26th Avenue",
|
96
|
+
# :address_ii=>"",
|
97
|
+
# :city=>"San Francisco",
|
98
|
+
# :state=>"California",
|
99
|
+
# :postal_code=>"94122",
|
100
|
+
# :country=>"United States",
|
101
|
+
# ...,
|
102
|
+
# :custom_fields=>
|
103
|
+
# {:title=>"CFO",
|
104
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
105
|
+
# :home_telephone=>"",
|
106
|
+
# ...,
|
107
|
+
# :parent_residency=>"Citizen"}},
|
108
|
+
# {:id=>267,
|
109
|
+
# :serial_number=>256,
|
110
|
+
# :custom_id=>"256",
|
111
|
+
# :name=>"Jane Patel",
|
112
|
+
# :first_name=>"Jane",
|
113
|
+
# ...,
|
114
|
+
# :profile_photo=>
|
115
|
+
# "https://openapply-sandbox-devel-01.s3.amazonaws.com/uploads/parent/avatar/000/000/267/patel_mom.jpg?v=1499755607",
|
116
|
+
# :profile_photo_updated_at=>"2017-07-11T14:46:47.000+08:00",
|
117
|
+
# :parent_id=>"256",
|
118
|
+
# :custom_fields=>
|
119
|
+
# {:title=>"",
|
120
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
121
|
+
# ...,
|
122
|
+
# :parent_residency=>"Citizen"}}]}}
|
123
|
+
def student_by_id(student_id, options ={})
|
124
|
+
url = "#{api_path}#{student_id}?auth_token=#{api_key}"
|
125
|
+
return oa_answer( url, options )
|
126
|
+
end
|
127
|
+
alias_method :student, :student_by_id
|
128
|
+
|
129
|
+
|
130
|
+
# Payment details for ONE student
|
131
|
+
#
|
132
|
+
# ==== Attributes
|
133
|
+
# * +student_id+ - openapply student_id
|
134
|
+
# * +options+ - see httparty options
|
135
|
+
#
|
136
|
+
# ==== Example code
|
137
|
+
# @demo = Openapply.new
|
138
|
+
# @demo.payments_by_id(96)
|
139
|
+
#
|
140
|
+
# ==== Result
|
141
|
+
# {:payments=>
|
142
|
+
# [{:invoice_status=>"Paid",
|
143
|
+
# :type=>"Application",
|
144
|
+
# :invoice_number=>1047,
|
145
|
+
# :amount=>"90.0",
|
146
|
+
# :issue_date=>"2016-03-11",
|
147
|
+
# :due_date=>"2016-03-31",
|
148
|
+
# :payment_method=>"check",
|
149
|
+
# :payment_date=>"2013-03-07"}]}
|
150
|
+
def payments_by_id(student_id, options={})
|
151
|
+
url = "#{api_path}#{student_id}/payments?auth_token=#{api_key}"
|
152
|
+
return oa_answer( url, options )
|
153
|
+
end
|
154
|
+
alias_method :payments, :payments_by_id
|
155
|
+
|
156
|
+
|
157
|
+
# Combines the student_by_id & payments_by_id into one call with all the data
|
158
|
+
#
|
159
|
+
# ==== Attributes
|
160
|
+
# * +student_id+ - openapply student_id
|
161
|
+
#
|
162
|
+
# ==== Example code
|
163
|
+
# @demo = Openapply.new
|
164
|
+
# @demo.student_details_by_id(96)
|
165
|
+
#
|
166
|
+
# ==== Results
|
167
|
+
# NOTE: gaurdian info is moved to the top level - along with ID
|
168
|
+
# {student: {
|
169
|
+
# id=95,
|
170
|
+
# record: {},
|
171
|
+
# guardians: [],
|
172
|
+
# payments: []
|
173
|
+
# }
|
174
|
+
# }
|
175
|
+
#
|
176
|
+
# for example:
|
177
|
+
#
|
178
|
+
# {:student=>
|
179
|
+
# {:id=>96,
|
180
|
+
# :record=>
|
181
|
+
# {:id=>96,
|
182
|
+
# :serial_number=>86,
|
183
|
+
# :custom_id=>"86",
|
184
|
+
# :applicant_id=>"00000086",
|
185
|
+
# :email=>"Jerry.Patel@eduvo.com",
|
186
|
+
# :first_name=>"Jerry",
|
187
|
+
# :last_name=>"Patel",
|
188
|
+
# ...,
|
189
|
+
# :profile_photo=>
|
190
|
+
# "https://openapply-sandbox-devel-01.s3.amazonaws.com/uploads/student/avatar/000/000/096/m_9.jpg?v=1499755604",
|
191
|
+
# :profile_photo_updated_at=>"2017-07-11T14:46:44.000+08:00",
|
192
|
+
# :custom_fields=>
|
193
|
+
# {:language=>"Hindi",
|
194
|
+
# :nationality=>"Indian (India)",
|
195
|
+
# :referral_source=>"Friends",
|
196
|
+
# ...,
|
197
|
+
# :siblings_information=>
|
198
|
+
# [{:first_name=>"Deidre",
|
199
|
+
# :last_name=>"Patel",
|
200
|
+
# :gender=>"Female",
|
201
|
+
# :birth_date=>"2008-06-06"}],
|
202
|
+
# :emergency_contact=>[],
|
203
|
+
# :immunization_record=>[],
|
204
|
+
# :health_information=>[]},
|
205
|
+
# :parent_ids=>[268, 267]},
|
206
|
+
# :payments=>
|
207
|
+
# [{:invoice_status=>"Paid",
|
208
|
+
# :type=>"Application",
|
209
|
+
# :invoice_number=>1047,
|
210
|
+
# :amount=>"90.0",
|
211
|
+
# :issue_date=>"2016-03-11",
|
212
|
+
# :due_date=>"2016-03-31",
|
213
|
+
# :payment_method=>"check",
|
214
|
+
# :payment_date=>"2013-03-07"}],
|
215
|
+
# :guardians=>
|
216
|
+
# [{:id=>268,
|
217
|
+
# :serial_number=>257,
|
218
|
+
# :custom_id=>"257",
|
219
|
+
# :name=>"James Patel",
|
220
|
+
# :first_name=>"James",
|
221
|
+
# :last_name=>"Patel",
|
222
|
+
# ...,
|
223
|
+
# :custom_fields=>
|
224
|
+
# {:title=>"CFO",
|
225
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
226
|
+
# :home_telephone=>"",
|
227
|
+
# ...,
|
228
|
+
# :parent_residency=>"Citizen"}},
|
229
|
+
# {:id=>267,
|
230
|
+
# :serial_number=>256,
|
231
|
+
# :custom_id=>"256",
|
232
|
+
# :name=>"Jane Patel",
|
233
|
+
# :first_name=>"Jane",
|
234
|
+
# :last_name=>"Patel",
|
235
|
+
# ...,
|
236
|
+
# :profile_photo=>
|
237
|
+
# "https://openapply-sandbox-devel-01.s3.amazonaws.com/uploads/parent/avatar/000/000/267/patel_mom.jpg?v=1499755607",
|
238
|
+
# :profile_photo_updated_at=>"2017-07-11T14:46:47.000+08:00",
|
239
|
+
# :parent_id=>"256",
|
240
|
+
# :custom_fields=>
|
241
|
+
# {:title=>"",
|
242
|
+
# :treat_parent_as_emergency_contact=>"Yes",
|
243
|
+
# :home_telephone=>"",
|
244
|
+
# ...,
|
245
|
+
# :parent_residency=>"Citizen"}}]}}
|
246
|
+
def student_details_by_id(id, flatten = false)
|
247
|
+
student_info = student_by_id( "#{id}" )
|
248
|
+
payment_info = payments_by_id( "#{id}" )
|
249
|
+
|
250
|
+
# be sure there is data to process
|
251
|
+
return {student: {id: id, empty: []}} if student_info.nil? or
|
252
|
+
student_info[:student].nil?
|
253
|
+
student_info[:student].empty?
|
254
|
+
guardians = []
|
255
|
+
guardians = student_info[:linked][:parents].dup unless
|
256
|
+
student_info[:linked].nil? or
|
257
|
+
student_info[:linked].empty? or
|
258
|
+
student_info[:linked][:parents].nil?
|
259
|
+
payments = []
|
260
|
+
payments = payment_info[:payments].dup unless payment_info.nil? or
|
261
|
+
payment_info[:payments].nil?
|
262
|
+
# process meaningful data
|
263
|
+
record = student_info[:student].dup
|
264
|
+
# remove duplicated parental data fields
|
265
|
+
record[:custom_fields][:parent_guardian] = nil
|
266
|
+
|
267
|
+
return { student:
|
268
|
+
{ id: id,
|
269
|
+
record: record,
|
270
|
+
payments: payments,
|
271
|
+
guardians: guardians,
|
272
|
+
}
|
273
|
+
}
|
274
|
+
end
|
275
|
+
alias_method :student_details, :student_details_by_id
|
276
|
+
|
277
|
+
end
|