epita-ease 0.2.0__tar.gz

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.
@@ -0,0 +1,502 @@
1
+ Metadata-Version: 2.3
2
+ Name: epita-ease
3
+ Version: 0.2.0
4
+ Summary: EASE (Epita Auriga Schedule Exporter) is a tool to export your schedule from the Auriga platform.
5
+ Requires-Dist: icalendar>=7.3.0
6
+ Requires-Dist: inquirerpy>=0.3.4
7
+ Requires-Dist: playwright>=1.64.0
8
+ Requires-Dist: pydantic>=2.14.1
9
+ Requires-Dist: requests>=2.34.2
10
+ Requires-Dist: toml>=0.10.2
11
+ Requires-Python: >=3.14
12
+ Description-Content-Type: text/markdown
13
+
14
+ # EASE: **E**PITA **A**uriga **S**chedule **E**xporter
15
+
16
+ ## How to
17
+
18
+ ### Using pipx (recommended)
19
+
20
+ Install EASE with pipx:
21
+
22
+ ```
23
+ pipx install https://github.com/lacaulac/ease/releases/latest/download/ease-0.2.0-py3-none-any.whl
24
+ ```
25
+
26
+ You can then set-up EASE by running `ease-setup`, and use EASE by running `ease`. Updates can then be run using `pipx update ease`.
27
+
28
+ *Note: If `pipx` is not installed, you should be able to install it with `pip install pipx`.*
29
+
30
+ ### Using `uv` and virtual environments
31
+
32
+ This was meant to be run with [`uv`](https://docs.astral.sh/uv/getting-started/installation/); it allows seamless use of virtual environments and handles Python versions and dependency installation on its own. You can install it on GNU/Linux systems with the following:
33
+
34
+ ```sh
35
+ curl -LsSf https://astral.sh/uv/install.sh | sh
36
+ ```
37
+
38
+ You can then set up EASE:
39
+
40
+ ```sh
41
+ uv run setup
42
+ ```
43
+
44
+ **Warning : your password will be stored in plaintext**
45
+
46
+ Finally, you can just run EASE anytime you want an export of your calendar :)
47
+
48
+ ```sh
49
+ uv run ease
50
+ ```
51
+
52
+ ## General algorithm
53
+
54
+ 1. Connects to auriga.epita.fr
55
+ 2. Gets redirected into oblivion for a bit
56
+ 3. Inputs credentials (you can do that manually too)
57
+ 4. Logs in
58
+ 5. Hijacks the auth token
59
+ 6. Exports the calendar's JSON for the current year
60
+ 7. Converts it into a .ics file
61
+ 8. ???
62
+ 9. Profit
63
+
64
+
65
+ ## Miscellaneous
66
+
67
+ ### JSON Schema
68
+
69
+ Yeah, those exports are *big*
70
+
71
+ ```
72
+ {
73
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
74
+ "title": "Interventions Export",
75
+ "type": "object",
76
+ "required": ["interventions", "unavailabilities"],
77
+ "properties": {
78
+ "interventions": {
79
+ "type": "array",
80
+ "items": {
81
+ "$ref": "#/$defs/intervention"
82
+ }
83
+ },
84
+ "unavailabilities": {
85
+ "type": "array"
86
+ }
87
+ },
88
+ "$defs": {
89
+ "localizedText": {
90
+ "type": "object",
91
+ "additionalProperties": {
92
+ "type": ["string", "null"]
93
+ }
94
+ },
95
+
96
+ "person": {
97
+ "type": "object",
98
+ "required": ["id", "currentFirstName", "currentLastName"],
99
+ "properties": {
100
+ "id": {
101
+ "type": "integer"
102
+ },
103
+ "currentFirstName": {
104
+ "type": "string"
105
+ },
106
+ "currentLastName": {
107
+ "type": "string"
108
+ }
109
+ }
110
+ },
111
+
112
+ "activityType": {
113
+ "type": "object",
114
+ "required": ["id", "code", "caption"],
115
+ "properties": {
116
+ "id": {
117
+ "type": "integer"
118
+ },
119
+ "code": {
120
+ "type": "string"
121
+ },
122
+ "caption": {
123
+ "$ref": "#/$defs/localizedText"
124
+ }
125
+ }
126
+ },
127
+
128
+ "interventionReference": {
129
+ "type": "object",
130
+ "properties": {
131
+ "id": {
132
+ "type": "integer"
133
+ },
134
+ "accountedDuration": {
135
+ "type": "integer"
136
+ },
137
+ "actualDuration": {
138
+ "type": "integer"
139
+ },
140
+ "startDateTime": {
141
+ "type": "string",
142
+ "format": "date-time"
143
+ },
144
+ "endDateTime": {
145
+ "type": "string",
146
+ "format": "date-time"
147
+ },
148
+ "additionalRemarks": {
149
+ "$ref": "#/$defs/localizedText"
150
+ },
151
+ "customAttributes": {
152
+ "type": "object"
153
+ }
154
+ },
155
+ "required": ["id"]
156
+ },
157
+
158
+ "interventionInstructor": {
159
+ "type": "object",
160
+ "required": ["id", "person"],
161
+ "properties": {
162
+ "id": {
163
+ "type": "integer"
164
+ },
165
+ "person": {
166
+ "$ref": "#/$defs/person"
167
+ }
168
+ }
169
+ },
170
+
171
+ "pedagogicalUnit": {
172
+ "type": "object",
173
+ "required": ["id", "code"],
174
+ "properties": {
175
+ "id": {
176
+ "type": "integer"
177
+ },
178
+ "code": {
179
+ "type": "string"
180
+ },
181
+ "caption": {
182
+ "$ref": "#/$defs/localizedText"
183
+ },
184
+ "externalCode": {
185
+ "type": "object",
186
+ "properties": {
187
+ "key": {
188
+ "type": "string"
189
+ }
190
+ }
191
+ },
192
+ "customAttributes": {
193
+ "type": "object"
194
+ }
195
+ }
196
+ },
197
+
198
+ "population": {
199
+ "type": "object",
200
+ "required": ["id", "code"],
201
+ "properties": {
202
+ "id": {
203
+ "type": "integer"
204
+ },
205
+ "code": {
206
+ "type": "string"
207
+ },
208
+ "caption": {
209
+ "$ref": "#/$defs/localizedText"
210
+ },
211
+ "externalCode": {
212
+ "type": "object",
213
+ "properties": {
214
+ "key": {
215
+ "type": "string"
216
+ }
217
+ }
218
+ },
219
+ "populationType": {
220
+ "type": "object"
221
+ }
222
+ }
223
+ },
224
+
225
+ "program": {
226
+ "type": "object",
227
+ "required": ["id", "code"],
228
+ "properties": {
229
+ "id": {
230
+ "type": "integer"
231
+ },
232
+ "code": {
233
+ "type": "string"
234
+ },
235
+ "caption": {
236
+ "$ref": "#/$defs/localizedText"
237
+ }
238
+ }
239
+ },
240
+
241
+ "resourceType": {
242
+ "type": "object",
243
+ "required": ["id", "code"],
244
+ "properties": {
245
+ "id": {
246
+ "type": "integer"
247
+ },
248
+ "code": {
249
+ "type": "string"
250
+ },
251
+ "caption": {
252
+ "$ref": "#/$defs/localizedText"
253
+ },
254
+ "isManagingConflictsEnabled": {
255
+ "type": "boolean"
256
+ }
257
+ }
258
+ },
259
+
260
+ "resource": {
261
+ "type": "object",
262
+ "required": ["id", "code"],
263
+ "properties": {
264
+ "id": {
265
+ "type": "integer"
266
+ },
267
+ "code": {
268
+ "type": "string"
269
+ },
270
+ "caption": {
271
+ "$ref": "#/$defs/localizedText"
272
+ },
273
+ "description": {
274
+ "$ref": "#/$defs/localizedText"
275
+ },
276
+ "floor": {
277
+ "type": "integer"
278
+ },
279
+ "examCapacity": {
280
+ "type": "integer"
281
+ },
282
+ "totalCapacity": {
283
+ "type": "integer"
284
+ },
285
+ "isAccessibleForDisablePeople": {
286
+ "type": "boolean"
287
+ },
288
+ "isRoom": {
289
+ "type": "boolean"
290
+ },
291
+ "resourceType": {
292
+ "$ref": "#/$defs/resourceType"
293
+ }
294
+ }
295
+ },
296
+
297
+ "attendanceStatus": {
298
+ "type": "object",
299
+ "required": ["id", "code"],
300
+ "properties": {
301
+ "id": {
302
+ "type": "integer"
303
+ },
304
+ "code": {
305
+ "type": "string"
306
+ },
307
+ "caption": {
308
+ "$ref": "#/$defs/localizedText"
309
+ }
310
+ }
311
+ },
312
+
313
+ "participation": {
314
+ "type": "object",
315
+ "required": [
316
+ "id",
317
+ "absenceExcused",
318
+ "isRemote",
319
+ "person"
320
+ ],
321
+ "properties": {
322
+ "id": {
323
+ "type": "integer"
324
+ },
325
+ "absenceExcused": {
326
+ "type": "boolean"
327
+ },
328
+ "absenceReason": {
329
+ "type": "object"
330
+ },
331
+ "attendanceStatus": {
332
+ "$ref": "#/$defs/attendanceStatus"
333
+ },
334
+ "automaticRegistrationStatus": {
335
+ "$ref": "#/$defs/attendanceStatus"
336
+ },
337
+ "participationStatus": {
338
+ "type": "object"
339
+ },
340
+ "isRemote": {
341
+ "type": "boolean"
342
+ },
343
+ "person": {
344
+ "$ref": "#/$defs/person"
345
+ }
346
+ }
347
+ },
348
+
349
+ "timezone": {
350
+ "type": "object",
351
+ "required": [
352
+ "id",
353
+ "code",
354
+ "name"
355
+ ],
356
+ "properties": {
357
+ "id": {
358
+ "type": "integer"
359
+ },
360
+ "abbreviation": {
361
+ "type": "string"
362
+ },
363
+ "code": {
364
+ "type": "string"
365
+ },
366
+ "description": {
367
+ "type": "string"
368
+ },
369
+ "dst": {
370
+ "type": "boolean"
371
+ },
372
+ "name": {
373
+ "type": "string"
374
+ },
375
+ "utcOffset": {
376
+ "type": "number"
377
+ },
378
+ "utcOffsetWithDst": {
379
+ "type": "number"
380
+ }
381
+ }
382
+ },
383
+
384
+ "interventionStatus": {
385
+ "type": "object",
386
+ "required": ["id", "code"],
387
+ "properties": {
388
+ "id": {
389
+ "type": "integer"
390
+ },
391
+ "code": {
392
+ "type": "string"
393
+ },
394
+ "caption": {
395
+ "$ref": "#/$defs/localizedText"
396
+ },
397
+ "isAccessAttendanceListsDisabled": {
398
+ "type": "boolean"
399
+ },
400
+ "isBillable": {
401
+ "type": "boolean"
402
+ },
403
+ "isDisplayedInSchedules": {
404
+ "type": "boolean"
405
+ },
406
+ "isHoursTaughtCountedInPrc": {
407
+ "type": "boolean"
408
+ },
409
+ "isHoursTaughtCountedInWorkloadPlan": {
410
+ "type": "boolean"
411
+ },
412
+ "isHoursTaughtExportedToPayroll": {
413
+ "type": "boolean"
414
+ },
415
+ "isInstructorConflictsEnabled": {
416
+ "type": "boolean"
417
+ },
418
+ "isLearnerConflictsEnabled": {
419
+ "type": "boolean"
420
+ },
421
+ "isPartOfAttendanceLists": {
422
+ "type": "boolean"
423
+ },
424
+ "isResourceConflictsEnabled": {
425
+ "type": "boolean"
426
+ },
427
+ "toSchedule": {
428
+ "type": "boolean"
429
+ }
430
+ }
431
+ },
432
+
433
+ "intervention": {
434
+ "type": "object",
435
+ "required": [
436
+ "id",
437
+ "activityType",
438
+ "actualDuration",
439
+ "startDateTime",
440
+ "endDateTime",
441
+ "isExam"
442
+ ],
443
+ "properties": {
444
+ "id": {
445
+ "type": "integer"
446
+ },
447
+ "activityType": {
448
+ "$ref": "#/$defs/activityType"
449
+ },
450
+ "actualDuration": {
451
+ "type": "integer"
452
+ },
453
+ "startDateTime": {
454
+ "type": "string",
455
+ "format": "date-time"
456
+ },
457
+ "endDateTime": {
458
+ "type": "string",
459
+ "format": "date-time"
460
+ },
461
+ "field": {
462
+ "type": "object"
463
+ },
464
+ "isExam": {
465
+ "type": "boolean"
466
+ },
467
+ "interventionInstructors": {
468
+ "type": "array",
469
+ "items": {
470
+ "$ref": "#/$defs/interventionInstructor"
471
+ }
472
+ },
473
+ "interventionPedagogicalUnits": {
474
+ "type": "array"
475
+ },
476
+ "interventionPopulations": {
477
+ "type": "array"
478
+ },
479
+ "interventionPrograms": {
480
+ "type": "array"
481
+ },
482
+ "interventionResources": {
483
+ "type": "array"
484
+ },
485
+ "interventionStatus": {
486
+ "$ref": "#/$defs/interventionStatus"
487
+ },
488
+ "participations": {
489
+ "type": "array",
490
+ "items": {
491
+ "$ref": "#/$defs/participation"
492
+ }
493
+ },
494
+ "timezone": {
495
+ "$ref": "#/$defs/timezone"
496
+ }
497
+ }
498
+ }
499
+ }
500
+ }
501
+
502
+ ```