zermelo-api-vogk 0.2.16__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Klaas Vogel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.1
2
+ Name: zermelo_api_vogk
3
+ Version: 0.2.16
4
+ Summary: A small module to create a Zermelo accesstoken and put some data from Zermelo in dataclasses
5
+ Home-page: https://github.com/KlaasVogel/zermelo_api_vogk
6
+ Author: Klaas Vogel
7
+ Author-email: zermelo_api@klaasvogel.nl
8
+ License: MIT
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+ Provides-Extra: dev
15
+ License-File: LICENSE
16
+
17
+ ## zermelo_api_vogk
18
+ A small module to create a Zermelo accesstoken and put some data from Zermelo in dataclasses
19
+
20
+ # V0.2.16
21
+ - found bug when running as daemon, probably: logger.
22
+ - try without output to file
23
+
24
+ # V0.2.15
25
+ - disabled debug mode
26
+
27
+ # V0.2.14
28
+ - debug on for bugfixing
29
+ - added extra debug log for filter in lesgroepen
30
+ - edit filter to find second part of groupname in les.groups
31
+
32
+ # V0.2.13
33
+ - New bug: loading of stamgroepen as lesgroep is broken!
34
+ - need to update/edit filter in lesgroepen
35
+
36
+ # V0.2.12
37
+ - removed debug for wisa and lesgroepen
38
+
39
+ # V0.2.11
40
+ - added groep.extendentName to filter in lesgroep
41
+
42
+ # V0.2.10
43
+ - trying to optimize lesgroepen
44
+ - added (temp) debug to lesgroepen
45
+ - log group
46
+
47
+ # V0.2.9
48
+ - removed dependency of Groepen in Vakken (ot used)
49
+ - added getName to Vak (Vakken)
50
+ - start cleanup code
51
+
52
+ # V0.2.8
53
+ - changed definition of Vakken and Groepen in Branch
54
+ - added Vakken & Vak to __init__.py
55
+
56
+ # V0.2.7
57
+ - added response as data in getData on wrong output
58
+ - refactoring of Appointments
59
+ * added function: get_department_updates [doesn't work atm :( ]
60
+
61
+ # V0.2.6
62
+ - removed linebreaks from logger.write()
63
+
64
+ # V0.2.5
65
+ - trying getting extra data for each appointment from user
66
+ - changed "with_id" in get_data to "from_id" and reversed functionality for better readability
67
+ - added classmethod to Appointment to get Appointment direct from id
68
+
69
+ # V0.2.4
70
+ - added getting appointments
71
+
72
+ # V0.2.3
73
+ - changed getting lesgroepen only as return so not part of branch anymore
74
+ - removed lastcheck from lesgroepen
75
+
76
+ # V0.2.2
77
+ - bugfix lesgroepen
78
+ - added write to logger (debug)
79
+ - changed repr of Users
80
+
81
+ # V0.2.1
82
+ - added datetime to each branch
83
+ - init of branches is now only datestring, year will be determined internally
84
+
85
+ # V0.2.0
86
+ - changed decorator from_zermelo_dict to function
87
+
88
+ # V0.1.3
89
+ - added lesgroepen
90
+
91
+ # V0.1.2
92
+ - added Vakken
93
+
94
+ # V0.1.1
95
+ - added groepen / groups
96
+ - First setup of vakken
97
+ - cleanup of code
98
+
99
+ # V0.1.0: First Refactoring already:
100
+ - deleted fields.py and moved usefull functions to zermelo_api
101
+ - loading of data for (zermelo)list generalized in zermelo_api
102
+
103
+ # V0.0.8:
104
+ - Added loading of Users (Leerlingen & Medewerkers)
105
+ - Added backtracker to MyLogger
106
+
107
+ # V0.0.7:
108
+ - Added Loading of Branches
109
+
110
+ # V0.0.1 -> V0.0.5:
111
+ - Experimenting with creating of own package and major structure of project
@@ -0,0 +1,95 @@
1
+ ## zermelo_api_vogk
2
+ A small module to create a Zermelo accesstoken and put some data from Zermelo in dataclasses
3
+
4
+ # V0.2.16
5
+ - found bug when running as daemon, probably: logger.
6
+ - try without output to file
7
+
8
+ # V0.2.15
9
+ - disabled debug mode
10
+
11
+ # V0.2.14
12
+ - debug on for bugfixing
13
+ - added extra debug log for filter in lesgroepen
14
+ - edit filter to find second part of groupname in les.groups
15
+
16
+ # V0.2.13
17
+ - New bug: loading of stamgroepen as lesgroep is broken!
18
+ - need to update/edit filter in lesgroepen
19
+
20
+ # V0.2.12
21
+ - removed debug for wisa and lesgroepen
22
+
23
+ # V0.2.11
24
+ - added groep.extendentName to filter in lesgroep
25
+
26
+ # V0.2.10
27
+ - trying to optimize lesgroepen
28
+ - added (temp) debug to lesgroepen
29
+ - log group
30
+
31
+ # V0.2.9
32
+ - removed dependency of Groepen in Vakken (ot used)
33
+ - added getName to Vak (Vakken)
34
+ - start cleanup code
35
+
36
+ # V0.2.8
37
+ - changed definition of Vakken and Groepen in Branch
38
+ - added Vakken & Vak to __init__.py
39
+
40
+ # V0.2.7
41
+ - added response as data in getData on wrong output
42
+ - refactoring of Appointments
43
+ * added function: get_department_updates [doesn't work atm :( ]
44
+
45
+ # V0.2.6
46
+ - removed linebreaks from logger.write()
47
+
48
+ # V0.2.5
49
+ - trying getting extra data for each appointment from user
50
+ - changed "with_id" in get_data to "from_id" and reversed functionality for better readability
51
+ - added classmethod to Appointment to get Appointment direct from id
52
+
53
+ # V0.2.4
54
+ - added getting appointments
55
+
56
+ # V0.2.3
57
+ - changed getting lesgroepen only as return so not part of branch anymore
58
+ - removed lastcheck from lesgroepen
59
+
60
+ # V0.2.2
61
+ - bugfix lesgroepen
62
+ - added write to logger (debug)
63
+ - changed repr of Users
64
+
65
+ # V0.2.1
66
+ - added datetime to each branch
67
+ - init of branches is now only datestring, year will be determined internally
68
+
69
+ # V0.2.0
70
+ - changed decorator from_zermelo_dict to function
71
+
72
+ # V0.1.3
73
+ - added lesgroepen
74
+
75
+ # V0.1.2
76
+ - added Vakken
77
+
78
+ # V0.1.1
79
+ - added groepen / groups
80
+ - First setup of vakken
81
+ - cleanup of code
82
+
83
+ # V0.1.0: First Refactoring already:
84
+ - deleted fields.py and moved usefull functions to zermelo_api
85
+ - loading of data for (zermelo)list generalized in zermelo_api
86
+
87
+ # V0.0.8:
88
+ - Added loading of Users (Leerlingen & Medewerkers)
89
+ - Added backtracker to MyLogger
90
+
91
+ # V0.0.7:
92
+ - Added Loading of Branches
93
+
94
+ # V0.0.1 -> V0.0.5:
95
+ - Experimenting with creating of own package and major structure of project
@@ -0,0 +1,8 @@
1
+ from .src.zermelo_api import ZermeloAPI
2
+ from .src.branches import Branch, Branches
3
+ from .src.time_utils import *
4
+ from .src.users import Leerling, Medewerker, Leerlingen, Personeel
5
+ from .src.lesgroepen import Lesgroepen, Lesgroep
6
+ from .src.leerjaren import Leerjaar, Leerjaren
7
+ from .src.appointments import get_user_appointments, get_department_updates, Appointment
8
+ from .src.vakken import Vakken, Vak
@@ -0,0 +1,92 @@
1
+ from .zermelo_api import zermelo, from_zermelo_dict
2
+ from dataclasses import dataclass, InitVar, field
3
+ from logger import makeLogger, DEBUG
4
+
5
+ logger = makeLogger("APPS")
6
+
7
+
8
+ @dataclass
9
+ class Appointment:
10
+ id: int
11
+ appointmentInstance: int = 0
12
+ start: int = 0
13
+ end: int = 0
14
+ startTimeSlot: int = 0
15
+ endTimeSlot: int = 0
16
+ branch: int = 0
17
+ type: str = "unknown"
18
+ groupsInDepartments: list[int] = field(default_factory=list)
19
+ locationsOfBranch: list[int] = field(default_factory=list)
20
+ locations: list[str] = field(default_factory=list)
21
+ optional: bool = False
22
+ valid: bool = False
23
+ cancelled: bool = False
24
+ cancelledReason: str = ""
25
+ modified: bool = False
26
+ teacherChanged: bool = False
27
+ groupChanged: bool = False
28
+ locationChanged: bool = False
29
+ timeChanged: bool = False
30
+ moved: bool = False
31
+ created: int = 0
32
+ hidden: bool = False
33
+ commonSchedule: bool = False
34
+ ignoreSubstitutions: bool = False
35
+ changeDescription: str = ""
36
+ schedulerRemark: str = ""
37
+ capacity: int = 0
38
+ content: str = ""
39
+ lastModified: int = 0
40
+ new: bool = True
41
+ choosableInDepartments: list[int] = field(default_factory=list)
42
+ choosableInDepartmentCodes: list[str] = field(default_factory=list)
43
+ courses: list[int] = field(default_factory=list)
44
+ alternativeSubject: str = ""
45
+ onlineStudents: list[str] = field(default_factory=list)
46
+ extraStudentSource: str = ""
47
+ appointmentLastModified: int = 0
48
+ onlineLocationUrl: str = ""
49
+ remark: str = ""
50
+ capacityManually: bool = False
51
+ teachingTimeManually: bool = False
52
+ teachingTime: int = 0
53
+ expectedStudentCount: int = 0
54
+ expectedStudentCountOnline: int = 0
55
+ availableSpace: int = 0
56
+ udmUUID: str = ""
57
+ creator: str = ""
58
+ subjects: list[str] = field(default_factory=list)
59
+ teachers: list[int] = field(default_factory=list)
60
+ onlineTeachers: list[str] = field(default_factory=list)
61
+ students: list[str] = field(default_factory=list)
62
+
63
+ # doesn't work (not enough rights)
64
+ # @classmethod
65
+ # def get_appointment(cls, id: int):
66
+ # query = f"appointments/{id}"
67
+ # status, data = zermelo.getData(query, from_id=True)
68
+ # if status != 200:
69
+ # raise Exception(data)
70
+ # return from_zermelo_dict(cls, data[0])
71
+
72
+
73
+ def get_appointments(query: str) -> list[Appointment]:
74
+ status, data = zermelo.getData(query)
75
+ if status != 200:
76
+ raise Exception(data)
77
+ return [from_zermelo_dict(Appointment, row) for row in data]
78
+
79
+
80
+ def get_user_appointments(user: int | str, **kwargs) -> list[Appointment]:
81
+ query = f"appointments/?user={user}"
82
+ for key, val in kwargs.items():
83
+ query += f"&{key}={val}"
84
+ logger.debug(query)
85
+ return get_appointments(query)
86
+
87
+
88
+ def get_department_updates(id: int, **kwargs) -> list[Appointment]:
89
+ query = f"appointments/?containsStudentsFromGroupInDepartment={id}"
90
+ for key, val in kwargs.items():
91
+ query += f"&{key}={val}"
92
+ return get_appointments(query)
@@ -0,0 +1,93 @@
1
+ from .logger import makeLogger
2
+ from .zermelo_api import ZermeloCollection, zermelo, from_zermelo_dict
3
+ from .time_utils import get_date, get_year, datetime
4
+ from .users import Leerling, Leerlingen, Personeel, Medewerker
5
+ from .leerjaren import Leerjaren, Leerjaar
6
+ from .groepen import Groep, Groepen
7
+ from .lesgroepen import Lesgroepen, Lesgroep
8
+ from .vakken import Vakken, Vak
9
+ from dataclasses import dataclass, InitVar, field
10
+
11
+ # branch is roughly translated to 'afdeling' in Dutch
12
+ # for readability kept as branch, might be changed in the future
13
+
14
+ logger = makeLogger("BRANCH")
15
+
16
+
17
+ @dataclass
18
+ class SchoolInSchoolYear:
19
+ id: int
20
+ # school: int
21
+ # year: int
22
+ # archived: bool
23
+ # name: str
24
+ # projectName: str
25
+ # schoolName: str
26
+ # schoolHrmsCode: str
27
+
28
+
29
+ @dataclass
30
+ class Branch:
31
+ id: int
32
+ schoolInSchoolYear: int
33
+ branch: str
34
+ name: str
35
+ schoolYear: int
36
+ date: datetime = datetime.now()
37
+ leerlingen: list[Leerling] = field(default_factory=list)
38
+ personeel: list[Medewerker] = field(default_factory=list)
39
+ leerjaren: list[Leerjaar] = field(default_factory=list)
40
+ vakken: Vakken = field(default_factory=list)
41
+ groepen: Groepen = field(default_factory=list)
42
+
43
+ def __post_init__(self):
44
+ logger.info(f"*** loading branch: {self.name} ***")
45
+ self.leerlingen = Leerlingen(self.schoolInSchoolYear)
46
+ self.personeel = Personeel(self.schoolInSchoolYear)
47
+ self.leerjaren = Leerjaren(self.schoolInSchoolYear)
48
+ self.groepen = Groepen(self.schoolInSchoolYear)
49
+ self.vakken = Vakken(self.schoolInSchoolYear)
50
+
51
+ def find_lesgroepen(self) -> Lesgroepen | bool:
52
+ if self.leerlingen and self.personeel:
53
+ return Lesgroepen(
54
+ self.leerjaren,
55
+ self.vakken,
56
+ self.groepen,
57
+ self.leerlingen,
58
+ self.personeel,
59
+ )
60
+ return False
61
+
62
+
63
+ @dataclass
64
+ class Branches(ZermeloCollection, list[Branch]):
65
+ datestring: InitVar = ""
66
+
67
+ def __post_init__(self, datestring):
68
+ logger.debug("init branches")
69
+ date = get_date(datestring)
70
+ year = get_year(datestring)
71
+ logger.debug(year)
72
+ query = f"schoolsinschoolyears/?year={year}&archived=False"
73
+ data = zermelo.load_query(query)
74
+ for schoolrow in data:
75
+ school = from_zermelo_dict(SchoolInSchoolYear, schoolrow)
76
+ query = f"branchesofschools/?schoolInSchoolYear={school.id}"
77
+ self.load_collection(query, Branch)
78
+ for branch in self:
79
+ branch.date = date
80
+
81
+ def __str__(self):
82
+ return "Branches(" + ", ".join([br.name for br in self]) + ")"
83
+
84
+ def get(self, name: str) -> Branch:
85
+ logger.info(f"loading branch: {name} ")
86
+ for branch in self:
87
+ if (
88
+ name.lower() in branch.branch.lower()
89
+ or branch.branch.lower() in name.lower()
90
+ ):
91
+ return branch
92
+ else:
93
+ logger.error(f"NO Branch found for {name}")
@@ -0,0 +1,52 @@
1
+ from os import path, mkdir
2
+ from shutil import copyfile
3
+ import json
4
+
5
+
6
+ class getConfig:
7
+ def __init__(self, file):
8
+ HOMEDIR = getConfigDir()
9
+ filename = file + ".json"
10
+ backupname = file + ".bak"
11
+ if not HOMEDIR:
12
+ raise Exception("Kan configuratie directory niet aanmaken")
13
+ self.filepath = path.join(HOMEDIR, filename)
14
+ self.backup = path.join(HOMEDIR, backupname)
15
+
16
+ def __repr__(self):
17
+ return f'ConfigFile(path="{self.filepath}")'
18
+
19
+ def save(self, data):
20
+ try:
21
+ copyfile(self.filepath, self.backup)
22
+ except Exception:
23
+ print("warning - geen datafile")
24
+ try:
25
+ with open(self.filepath, "w") as file:
26
+ json.dump(data, file, indent=2)
27
+ except Exception:
28
+ return False
29
+ return True
30
+
31
+ def load(self):
32
+ data = {}
33
+ for file in [self.filepath, self.backup]:
34
+ try:
35
+ if path.isfile(file):
36
+ with open(file, "r") as json_file:
37
+ data = json.load(json_file)
38
+ except Exception:
39
+ continue
40
+ return data
41
+
42
+ def get(self, key: str = None):
43
+ data = self.load()
44
+ if not key:
45
+ return data
46
+ return data[key] if key in data else {}
47
+
48
+
49
+ def getConfigDir():
50
+ abspath = path.abspath(__file__)
51
+ dname = path.dirname(abspath)
52
+ return dname
@@ -0,0 +1,26 @@
1
+ from .config import getConfig
2
+ from .logger import makeLogger, INFO, DEBUG
3
+
4
+ logger = makeLogger("creds", INFO)
5
+
6
+
7
+ class Credentials:
8
+ def __init__(self):
9
+ self.file = getConfig("creds")
10
+ self.token = ""
11
+ self.load()
12
+
13
+ def load(self):
14
+ self.token = ""
15
+ try:
16
+ data = self.file.load()
17
+ self.token = data["token"]
18
+ except Exception as e:
19
+ logger.trace()
20
+ finally:
21
+ logger.debug(f"token: {self.token}")
22
+ return True if self.token else False
23
+
24
+ def settoken(self, token):
25
+ self.file.save({"token": token})
26
+ self.token = token
@@ -0,0 +1,35 @@
1
+ from .zermelo_api import ZermeloCollection, zermelo
2
+ from .logger import makeLogger
3
+ from dataclasses import dataclass, InitVar
4
+
5
+ logger = makeLogger("GROEPEN")
6
+
7
+
8
+ @dataclass
9
+ class Groep:
10
+ id: int
11
+ isMainGroup: bool
12
+ isMentorGroup: bool
13
+ departmentOfBranch: int
14
+ name: str
15
+ extendedName: str
16
+
17
+
18
+ @dataclass
19
+ class Groepen(ZermeloCollection, list[Groep]):
20
+ schoolinschoolyear: InitVar
21
+
22
+ def __post_init__(self, schoolinschoolyear: int):
23
+ query = f"groupindepartments?schoolInSchoolYear={schoolinschoolyear}"
24
+ self.load_collection(query, Groep)
25
+
26
+ def get_department_groups(
27
+ self, departmentOfBranch: int, maingroup: bool = False
28
+ ) -> list[Groep]:
29
+ # returns all groups (if it is/isnt stamklas (maingroup))
30
+ return [
31
+ groep
32
+ for groep in self
33
+ if groep.departmentOfBranch == departmentOfBranch
34
+ and groep.isMainGroup == maingroup
35
+ ]
@@ -0,0 +1,48 @@
1
+ from .zermelo_api import ZermeloCollection
2
+ from .logger import makeLogger
3
+ from dataclasses import dataclass, InitVar
4
+
5
+ # Leerjaar is a rough dutch translation of department in Zermelo
6
+
7
+ logger = makeLogger("Leerjaren")
8
+
9
+
10
+ def getLeerjaarNaam(string):
11
+ names = {"LG1": "klas 1", "LG2": "klas 2", "LG3": "klas 3"}
12
+ for name, result in names.items():
13
+ if name in string:
14
+ return result
15
+ else:
16
+ return string
17
+
18
+
19
+ @dataclass
20
+ class Leerjaar:
21
+ id: int
22
+ code: str
23
+ yearOfEducation: int
24
+ branchOfSchool: int
25
+ teacherTeams: list[int]
26
+ mainGroupAuthority: str
27
+ educationType: str
28
+ weekTimeTable: int
29
+ teachingLevel: str
30
+ educations: list[int]
31
+ schoolInSchoolYear: int
32
+ branchOfSchoolCode: str
33
+ schoolInSchoolYearName: str
34
+ profiles: list[int]
35
+ schoolInSchoolYearId: int
36
+ name: str = ""
37
+
38
+ def __post_init__(self):
39
+ self.name = getLeerjaarNaam(self.code.upper())
40
+
41
+
42
+ @dataclass
43
+ class Leerjaren(ZermeloCollection, list[Leerjaar]):
44
+ schoolinschoolyear: InitVar
45
+
46
+ def __post_init__(self, schoolinschoolyear: int):
47
+ query = f"departmentsofbranches?schoolInSchoolYear={schoolinschoolyear}"
48
+ self.load_collection(query, Leerjaar)