untis 1.0.1
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/lib/untis.rb +347 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8a74e98496d1dba08aae22dab8e48a803b61be6cc2c633ab2e9b57aec423a95e
|
4
|
+
data.tar.gz: 27ef6140d9ca1c9716372c84770549e7e4f352a0962c004d31e1ae7c89e6b332
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9d96ccd0094f044bb70424c1163e75a0d80d1e047451d7c5a45b4108f54c147c82a217685fb9a042e24291390c136342603390feb1e7ee3d76b30495b7aa08ce
|
7
|
+
data.tar.gz: eb0c1b0cd868fe9daa2ae7d48396c545fbf935dbbe36d54c8873a0a08fc06f75023a49b4cfc93c5560448bc8c86df16469b2ffbe8473a7616bcb1582d43223f4
|
data/lib/untis.rb
ADDED
@@ -0,0 +1,347 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'json'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
class UntisWorker
|
7
|
+
attr_accessor :login, :password, :client_id,
|
8
|
+
:session_id, :person_id, :person_type,
|
9
|
+
:api_base_url, :school_name, :school_name_url,
|
10
|
+
:api_url, :api_url_base, :api_version,
|
11
|
+
:api_version_sv
|
12
|
+
|
13
|
+
def initialize(**args)
|
14
|
+
@login = args[:login]
|
15
|
+
@password = args[:password]
|
16
|
+
@client_id = args[:client_id] || self.generate_client_id
|
17
|
+
@session_id = args[:session_id]
|
18
|
+
@person_id = args[:person_id]
|
19
|
+
@person_type = args[:person_type]
|
20
|
+
@api_base_url = args[:api_base_url] || "https://kephiso.webuntis.com/WebUntis"
|
21
|
+
@school_name = args[:school_name] || "Example School"
|
22
|
+
@school_name_url = URI::escape @school_name.gsub(/\s/, '+')
|
23
|
+
@api_url_base = URI "#{@api_base_url}/jsonrpc.do"
|
24
|
+
@api_url = URI "#{@api_base_url}/jsonrpc.do?school=#{@school_name_url}"
|
25
|
+
@api_version = '2.0'
|
26
|
+
@api_version_sv = @api_version
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate_client_id
|
30
|
+
"UW-#{SecureRandom.hex}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_id
|
34
|
+
SecureRandom.hex
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def build_fields(**args)
|
40
|
+
{ 'id' => generate_id, 'jsonrpc' => @api_version, 'method' => args[:method], 'params' => args[:params].delete_if do |k, v| v.nil? end }
|
41
|
+
end
|
42
|
+
|
43
|
+
def post(url, data)
|
44
|
+
response = nil
|
45
|
+
|
46
|
+
data.delete_if do |k, v|
|
47
|
+
v.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
if @session_id.nil?
|
52
|
+
response = Net::HTTP.post url, data.to_json, 'Content-Type' => 'application/json'
|
53
|
+
else
|
54
|
+
response = Net::HTTP.post url, data.to_json, 'Content-Type' => 'application/json', 'Cookie' => "JSESSIONID=#{@session_id}"
|
55
|
+
end
|
56
|
+
rescue
|
57
|
+
puts 'Request failed!'
|
58
|
+
sleep 1
|
59
|
+
puts 'Retrying...'
|
60
|
+
return post url, data
|
61
|
+
end
|
62
|
+
|
63
|
+
response_data = JSON.parse response.body
|
64
|
+
|
65
|
+
# Catch non-auth
|
66
|
+
if response_data['error'] && (response_data['error']['code'] == -8520 || response_data['error']['message'] == 'not authenticated')
|
67
|
+
puts 'Request failed, authentication expired! Re-Authing...'
|
68
|
+
sleep 0.25
|
69
|
+
authenticate!
|
70
|
+
sleep 1
|
71
|
+
puts 'Retrying...'
|
72
|
+
return post url, data
|
73
|
+
end
|
74
|
+
|
75
|
+
response_data
|
76
|
+
end
|
77
|
+
|
78
|
+
public
|
79
|
+
|
80
|
+
def date_from_str(date_str)
|
81
|
+
Date::strptime date_str, '%Y%m%d'
|
82
|
+
end
|
83
|
+
|
84
|
+
def date_to_str(date)
|
85
|
+
date.strftime '%Y%m%d'
|
86
|
+
end
|
87
|
+
|
88
|
+
def time_from_str(time_str)
|
89
|
+
Time::strptime time_str, '%H%M'
|
90
|
+
end
|
91
|
+
|
92
|
+
def time_to_str(time)
|
93
|
+
time.strftime '%H%M'
|
94
|
+
end
|
95
|
+
|
96
|
+
def authenticate!
|
97
|
+
result = post @api_url, build_fields(
|
98
|
+
method: 'authenticate',
|
99
|
+
params: {
|
100
|
+
'user' => @login,
|
101
|
+
'password' => @password,
|
102
|
+
'client' => @client_id
|
103
|
+
}
|
104
|
+
)
|
105
|
+
|
106
|
+
if result['result']
|
107
|
+
puts 'Auth OK!'
|
108
|
+
|
109
|
+
@session_id = result['result']['sessionId']
|
110
|
+
@person_type = result['result']['personType']
|
111
|
+
@person_id = result['result']['personId']
|
112
|
+
@api_version_sv = result['jsonrpc']
|
113
|
+
else
|
114
|
+
puts 'Auth error!'
|
115
|
+
puts result['error']['message']
|
116
|
+
end
|
117
|
+
|
118
|
+
result
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_teachers
|
122
|
+
post @api_url, build_fields(
|
123
|
+
method: 'getTeachers',
|
124
|
+
params: []
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_students
|
129
|
+
post @api_url, build_fields(
|
130
|
+
method: 'getStudents',
|
131
|
+
params: []
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_classes(**args)
|
136
|
+
post @api_url, build_fields(
|
137
|
+
method: 'getKlassen',
|
138
|
+
params: {
|
139
|
+
schoolyearId: args[:school_year] || args[:year] || args[:schoolyearId] || args[:school_year_id]
|
140
|
+
}
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_subjects
|
145
|
+
post @api_url, build_fields(
|
146
|
+
method: 'getSubjects',
|
147
|
+
params: []
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_rooms
|
152
|
+
post @api_url, build_fields(
|
153
|
+
method: 'getRooms',
|
154
|
+
params: []
|
155
|
+
)
|
156
|
+
end
|
157
|
+
|
158
|
+
def get_departments
|
159
|
+
post @api_url, build_fields(
|
160
|
+
method: 'getDepartments',
|
161
|
+
params: []
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
def get_holidays
|
166
|
+
post @api_url, build_fields(
|
167
|
+
method: 'getHolidays',
|
168
|
+
params: []
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_timegrid
|
173
|
+
post @api_url, build_fields(
|
174
|
+
method: 'getTimegridUnits',
|
175
|
+
params: []
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_status_data
|
180
|
+
post @api_url, build_fields(
|
181
|
+
method: 'getStatusData',
|
182
|
+
params: []
|
183
|
+
)
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_current_school_year
|
187
|
+
post @api_url, build_fields(
|
188
|
+
method: 'getCurrentSchoolyear',
|
189
|
+
params: []
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
def get_school_years
|
194
|
+
post @api_url, build_fields(
|
195
|
+
method: 'getSchoolyears',
|
196
|
+
params: []
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_timetable(**args)
|
201
|
+
if args[:options].nil?
|
202
|
+
post @api_url, build_fields(
|
203
|
+
method: 'getTimetable',
|
204
|
+
params: {
|
205
|
+
id: args[:id],
|
206
|
+
type: args[:type],
|
207
|
+
startDate: date_to_str(args[:start_date] || args[:startDate]),
|
208
|
+
endDate: date_to_str(args[:end_date] || args[:endDate])
|
209
|
+
}
|
210
|
+
)
|
211
|
+
else
|
212
|
+
opts = args[:options]
|
213
|
+
|
214
|
+
post @api_url, build_fields(
|
215
|
+
method: 'getTimetable',
|
216
|
+
params: {
|
217
|
+
options: {
|
218
|
+
element: {
|
219
|
+
id: opts[:element][:id],
|
220
|
+
type: opts[:element][:type],
|
221
|
+
keyType: opts[:element][:key_type] || opts[:element][:keyType] || 'id'
|
222
|
+
},
|
223
|
+
startDate: date_to_str(opts[:start_date] || opts[:startDate] || Date.today),
|
224
|
+
endDate: date_to_str(opts[:end_date] || opts[:endDate] || Date.today),
|
225
|
+
onlyBaseTimetable: opts[:only_base_timetable] || opts[:onlyBaseTimetable] || false,
|
226
|
+
showBooking: opts[:show_booking] || opts[:showBooking] || false,
|
227
|
+
showInfo: opts[:show_info] || opts[:showInfo] || false,
|
228
|
+
showSubstText: opts[:show_subst_text] || opts[:showSubstText] || false,
|
229
|
+
showLsText: opts[:show_ls_text] || opts[:showLsText] || false,
|
230
|
+
showStudentgroup: opts[:show_student_group] || opts[:showStudentgroup] || false,
|
231
|
+
klasseFields: opts[:class_fields] || opts[:klasseFields],
|
232
|
+
roomFields: opts[:room_fields] || opts[:roomFields],
|
233
|
+
subjectFields: opts[:subject_fields] || opts[:subjectFields],
|
234
|
+
teacherFields: opts[:teacher_fields] || opts[:teacherFields]
|
235
|
+
}
|
236
|
+
}
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def get_latest_import_time
|
242
|
+
post @api_url, build_fields(
|
243
|
+
method: 'getLatestImportTime',
|
244
|
+
params: []
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
def get_person_id(**args)
|
249
|
+
post @api_url, build_fields(
|
250
|
+
method: 'getPersonId',
|
251
|
+
params: {
|
252
|
+
type: args[:type] || 5,
|
253
|
+
sn: args[:sn] || args[:surname] || args[:last_name],
|
254
|
+
fn: args[:fn] || args[:forename] || args[:name] || args[:first_name],
|
255
|
+
dob: args[:dob] || args[:birthday] || args[:birth_date] || 0,
|
256
|
+
}
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
def get_substitutions(**args)
|
261
|
+
post @api_url, build_fields(
|
262
|
+
method: 'getSubstitutions',
|
263
|
+
params: {
|
264
|
+
endDate: date_to_str(args[:end_date] || args[:endDate]),
|
265
|
+
startDate: date_to_str(args[:start_date] || args[:startDate]),
|
266
|
+
departmentId: args[:department_id] || args[:departmentId] || 0,
|
267
|
+
}
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
def get_class_reg_events(**args)
|
272
|
+
post @api_url, build_fields(
|
273
|
+
method: 'getClassregEvents',
|
274
|
+
params: {
|
275
|
+
endDate: args[:end_date] || args[:endDate],
|
276
|
+
startDate: args[:start_date] || args[:startDate],
|
277
|
+
}
|
278
|
+
)
|
279
|
+
end
|
280
|
+
|
281
|
+
def get_exams(**args)
|
282
|
+
post @api_url, build_fields(
|
283
|
+
method: 'getExams',
|
284
|
+
params: {
|
285
|
+
endDate: args[:end_date] || args[:endDate],
|
286
|
+
startDate: args[:start_date] || args[:startDate],
|
287
|
+
examTypeId: args[:exam_type_id] || args[:exam_type] || args[:examTypeId] || args[:exam_id]
|
288
|
+
}
|
289
|
+
)
|
290
|
+
end
|
291
|
+
|
292
|
+
def get_exam_types
|
293
|
+
post @api_url, build_fields(
|
294
|
+
method: 'getExamTypes',
|
295
|
+
params: []
|
296
|
+
)
|
297
|
+
end
|
298
|
+
|
299
|
+
def get_timetable_with_absences(**args)
|
300
|
+
opts = args[:options] || args
|
301
|
+
|
302
|
+
post @api_url, build_fields(
|
303
|
+
method: 'getTimetableWithAbsences',
|
304
|
+
params: {
|
305
|
+
options: {
|
306
|
+
endDate: opts[:end_date] || opts[:endDate],
|
307
|
+
startDate: opts[:start_date] || opts[:startDate]
|
308
|
+
}
|
309
|
+
}
|
310
|
+
)
|
311
|
+
end
|
312
|
+
|
313
|
+
def get_class_reg_categories
|
314
|
+
post @api_url, build_fields(
|
315
|
+
method: 'getClassregCategories',
|
316
|
+
params: []
|
317
|
+
)
|
318
|
+
end
|
319
|
+
|
320
|
+
def get_class_reg_category_groups
|
321
|
+
post @api_url, build_fields(
|
322
|
+
method: 'getClassregCategoryGroups',
|
323
|
+
params: []
|
324
|
+
)
|
325
|
+
end
|
326
|
+
|
327
|
+
def get_class_reg_events_for_element(**args)
|
328
|
+
opts = args[:options] || args
|
329
|
+
|
330
|
+
opts[:element] = {} if opts[:element].nil?
|
331
|
+
|
332
|
+
post @api_url, build_fields(
|
333
|
+
method: 'getClassregEvents',
|
334
|
+
params: {
|
335
|
+
options: {
|
336
|
+
endDate: opts[:end_date] || opts[:endDate],
|
337
|
+
startDate: opts[:start_date] || opts[:startDate],
|
338
|
+
element: {
|
339
|
+
id: opts[:element][:id],
|
340
|
+
type: opts[:element][:type],
|
341
|
+
keyType: opts[:element][:keyType] || opts[:element][:key_type] || 'id',
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
)
|
346
|
+
end
|
347
|
+
end
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: untis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Meow the Cat
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-05-07 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: WebUntis Timetable Management system wrapper for Ruby.
|
14
|
+
email: meowdakat@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/untis.rb
|
20
|
+
homepage: https://github.com/Meow/untis
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubygems_version: 3.0.3
|
40
|
+
signing_key:
|
41
|
+
specification_version: 4
|
42
|
+
summary: Untis Timetable system wrapper.
|
43
|
+
test_files: []
|