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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/untis.rb +347 -0
  3. metadata +43 -0
@@ -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
@@ -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: []