Name | zermeloapi JSON |
Version |
2024.1.8.10.51.44
JSON |
| download |
home_page | |
Summary | zermelo api |
upload_time | 2024-01-08 09:51:45 |
maintainer | |
docs_url | None |
author | b.vill |
requires_python | >=3.0 |
license | |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# zermelo api v:2024.01.08.10.51.44
![GitHub Logo](https://ozhw.zportal.nl/static/v/21.09j64/img/zermelo2013.svg)
# documentation
## install
```properties
pip install zermeloapi
```
## how to import
```python
import zermeloapi
```
## initializing
```python
zermelo = zermeloapi.zermelo(school, username, password, teacher=False, version=3)
```
## get token
```python
token = zermelo.get_token()
```
if u wand to u can give the school username and password again but u don't need to in that case u can use `get_token(school,username,password)`
## get access token
```python
access_token = zermelo.get_access_token()
```
again if u wand to u can give the school and username again but u don't need to in that case u can use `get_access_token(school,username)`
## get raw schedule
```python
raw_schedule = zermelo.get_schedule()
```
u can give the week number and or year of u wand to else it uses the current year/week u can use `get_schedule(week=02)`,`get_schedule(year=2024)`or`get_schedule(year=2024,week=02)`
## get schedule
```python
raw_schedule = zermelo.get_schedule()
```
u can give the week number and or year of u wand to else it uses the current year/week u can use `get_schedule(week=02)`,`get_schedule(year=2024)`or`get_schedule(year=2024,week=02)`and u you can pass a rawshedule from get_raw_shedule()
## sort schedule
```python
sorted_schedule = zermelo.sort_schedule()
```
like before u can give the week and year but u can also give the schedule from [`get_schedule()`](#get-schedule) instead to sort it defaults to getting it self but if u give it uses that one u can do that by using it like this `sort_schedule(schedule)` for the week and year it is the same syntax
## readable schedule
```python
readable = zermelo.readable_schedule()
```
again u can give it week and year with the same syntax as before also you can give it a sorted schedule (output from [`sort_schedule()`](#sort-schedule)) by using `readable_schedule(sorted_schedule)`
## print schedule
```python
zermelo.print_schedule()
```
yes u can use it like this `zermelo.print_schedule(zermelo.readable_schedule())` but **WHY** if u wand that use it like that just `print(zermelo.readable_schedule())` the only use is that it defaults to `zermelo.readable_schedule()`
# [source code](https://github.com/btpv/zermeloapi)
```python
# from calendar import weekday
import os.path
import requests
import json
import time
import base64
# from datetime import datetime
import datetime
class zermelo:
expires_in = 0
school = ''
username = ''
teacher = False
debug = False
TimeToAddToUtc = 0
def __init__(self, school, username,password=None, teacher=False, version=3,debug=False,linkcode=None):
self.school = school
self.username = username
self.teacher = teacher
self.debug = debug
self.version = 'v'+str(version)
self.TimeToAddToUtc = self.get_date()[2]
if linkcode == None and password != None:
self.token = self.get_tokenfromusrpsw(school=school,username=username,password=password)
else:
self.token = self.gettokenfromfile(linkcode=linkcode)
def updatetoken(self, linkcode):
self.token = self.gettokenfromfile(linkcode=linkcode)
def gettokenfromlinkcode(self, linkcode=None):
if linkcode == None:
linkcode = input("apitoken: ").replace(" ",'')
else:
linkcode = str(linkcode).replace(" ",'')
return json.loads(requests.post(f"https://ozhw.zportal.nl/api/v3/oauth/token?grant_type=authorization_code&code={linkcode}").text)["access_token"]
def get_tokenfromusrpsw(self, school=None, username=None, password=None):
if(school == None):
school = self.school
if (username == None):
username = self.username
if(password == None):
password = self.password
url = 'https://'+school+'.zportal.nl/api/'+self.version+'/oauth'
myobj = {'username': username, 'password': password, 'client_id': 'OAuthPage', 'redirect_uri': '/main/',
'scope': '', 'state': '4E252A', 'response_type': 'code', 'tenant': school}
x = requests.post(url, data=myobj,allow_redirects=False)
respons = x.headers['Location']
# exit(0)
if self.debug:
print(x.text)
# exit(0)
start = respons.find("code=") + len("code=")
end = respons.find("&", start)
token = respons[start:end]
start = respons.find("tenant=") + len("tenant=")
end = respons.find("&", start)
school = respons[start:end]
start = respons.find("expires_in=") + len("expires_in=")
end = respons.find("&", start)
self.expires_in = respons[start:end]
start = respons.find("loginMethod=") + len("loginMethod=")
end = respons.find("&", start)
self.loginMethod = respons[start:end]
start = respons.find("interfaceVersion=") + len("interfaceVersion=")
end = respons.find("&", start)
self.interfaceVersion = respons[start:end]
if(school == None):
school = self.school
if(token == None):
token = self.get_token()
print(token)
url = 'https://' + school+'.zportal.nl/api/'+self.version+'/oauth/token'
myobj = {'code': token, 'client_id': 'ZermeloPortal', 'client_secret': 42,
'grant_type': 'authorization_code', 'rememberMe': False}
print("\n\n")
print(myobj,url)
l = requests.post(url, data=myobj)
if self.debug:
print(l.text)
jl = json.loads(l.text)
token = jl['access_token']
return(token)
def gettokenfromfile(self, file="./token", linkcode=None):
if not os.path.exists(file):
self.settokentofile(linkcode=linkcode)
with open(file) as f:
filevalue = f.read()
return str(base64.b64decode(filevalue))[2:-1]
def settokentofile(self,token=None,file="./token",linkcode=None):
if token == None:
token = self.gettokenfromlinkcode(linkcode=linkcode)
file = str(base64.b64encode(bytes(token, "utf-8")))[2:-1]
with open("./token", "w") as f:
f.write(str(file))
def get_date(self):
now = datetime.datetime.now()
return (now.year,now.isocalendar()[1],int((datetime.datetime.fromtimestamp(now.timestamp()) - datetime.datetime.utcfromtimestamp(now.timestamp())).total_seconds() / 3600))
def get_raw_schedule(self, year:int=None, week:int=None, username:str=None,teacher:bool = False) -> dict:
time = self.get_date()
if year == None:
year = time[0]
if week == None:
week = time[1]
if username == None:
url = f"https://{self.school}.zportal.nl/api/v3/liveschedule?access_token={self.token}&{'teacher' if (self.teacher) else 'student'}={self.username}&week={year}{week:0>2}"
else:
start = str(datetime.datetime.strptime(f"{year}-{week}-0","%Y-%U-%w").timestamp())[0:-2]
end = str(datetime.datetime.strptime(f"{year}-{week}-6","%Y-%U-%w").timestamp())[0:-2]
url = f"https://{self.school}.zportal.nl/api/v3/appointments?access_token={self.token}&start={start}&end={end}&{'teachers' if (teacher) else 'possibleStudents'}={username}"
if self.debug:
print(url)
rawr = requests.get(url)
if self.debug:
print(rawr)
rl = json.loads(rawr.text)
return rl
def get_schedule(self,rawschedule:dict=None,year=None, week=None,username=None,teacher=None):
if rawschedule == None:
rawschedule = self.get_raw_schedule(year=year,week=week,username=username,teacher=teacher)
response = rawschedule["response"]
if username != None:
appointments = response["data"]
else:
data = response["data"][0]
appointments = data["appointments"]
return(appointments)
def sort_schedule(self, schedule=None, year=None, week=None,username=None,teacher=None):
if(schedule == None):
schedule = self.get_schedule(year=year, week=week,username=username,teacher=teacher)
pdate = 0
days = [[[], []]]
thisweek = {}
for les in schedule:
date = datetime.datetime.utcfromtimestamp(les["start"]).strftime('%Y%m%d')
hour = str(int(datetime.datetime.utcfromtimestamp(
les["start"]).strftime('%H')) + self.TimeToAddToUtc)
time = datetime.datetime.utcfromtimestamp(les["start"]).strftime('%Y-%m-%d ') + (hour if int(
hour) > 9 else ('0'+hour)) + datetime.datetime.utcfromtimestamp(les["start"]).strftime(':%M')
ehour = str(int(datetime.datetime.utcfromtimestamp(
les["end"]).strftime('%H')) + self.TimeToAddToUtc)
etime = datetime.datetime.utcfromtimestamp(les["end"]).strftime('%Y-%m-%d ') + (ehour if int(
ehour) > 9 else ('0'+ehour)) + datetime.datetime.utcfromtimestamp(les["end"]).strftime(':%M')
# print(les["status"])
if username != None:
code = 2002
if les["cancelled"] or not les["valid"]:
code = 4007
elif les["moved"]:
code = 3012
elif les["modified"]:
code = 3011
if not date in thisweek:
thisweek[date] = [[],[]]
if (not les["cancelled"] and les["valid"]):
thisweek[date][0].append([les["subjects"][0], time, etime,
str(les["locations"]), [{"code":code}], False])
else:
thisweek[date][1].append([les["subjects"][0], time, etime,
str(les["locations"]), [{"code":code}], False])
else:
if date != pdate:
days.append([[], []])
if self.debug:
print(les)
if not (les == None or len(les["status"]) < 1):
if (les["status"][0]["code"] < 3000 and les["status"][0]["code"] >= 2000):
days[-1][0].append([les["subjects"][0], time, etime,
str(les["locations"]), les["status"], les["online"]])
else:
days[-1][1].append([les["subjects"][0], time, etime,
str(les["locations"]), les["status"], les["online"]])
pdate = date
if username != None:
thisweekdayssorted = [thisweek[i] for i in [str(c) for c in sorted([int(i) for i in thisweek.keys()])]]
days = []
for v in thisweekdayssorted:
part = []
for v2 in v:
part.append(sorted(v2,key = lambda x: int(x[1].replace(":","").replace("-","").replace(" ",""))))
days.append(part)
else:
days.pop(0)
return(days)
def readable_schedule(self, days=None, year=None, week=None,username=None,teacher=None):
result = ''
if(days == None):
days = self.sort_schedule(year=year, week=week,username=username,teacher=teacher)
daysofweek = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
for i,day in enumerate(days):
if len(day[0]) > 0:
result += (daysofweek[i]+"\nstart: "+day[0][0][1]+"\tend: "+day[0][-1][2]+'\n')
else:
result += (f"{daysofweek[i]}\n")
for les in day[0]:
if (les[4][0]["code"] < 4000 and les[4][0]["code"] >= 2000):
# if True:
result += f"les: {les[0].ljust(8, ' ')} lokaal: {('📷'if(les[5])else (les[3][2:-2]if(len(les[3][2:-2]) > 0)else '----')).ljust(8, ' ')} start: {les[1]}\tend: {les[2]}\n"
pass
result += ("\n\n")
return result
def print_schedule(self, readable=None, days=None, year=None, week=None,username=None,teacher=None):
if(readable == None):
readable = self.readable_schedule(days=days, year=year, week=week,username=username,teacher=teacher)
print(readable)
```
Raw data
{
"_id": null,
"home_page": "",
"name": "zermeloapi",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.0",
"maintainer_email": "",
"keywords": "",
"author": "b.vill",
"author_email": "villeriusborro@gmail.com",
"download_url": "",
"platform": null,
"description": "# zermelo api v:2024.01.08.10.51.44\n![GitHub Logo](https://ozhw.zportal.nl/static/v/21.09j64/img/zermelo2013.svg)\n# documentation\n\n\n## install\n\n```properties\npip install zermeloapi\n```\n\n## how to import\n```python\nimport zermeloapi\n```\n## initializing\n```python\nzermelo = zermeloapi.zermelo(school, username, password, teacher=False, version=3)\n```\n## get token\n```python\ntoken = zermelo.get_token()\n```\nif u wand to u can give the school username and password again but u don't need to in that case u can use `get_token(school,username,password)`\n## get access token\n```python\naccess_token = zermelo.get_access_token()\n```\nagain if u wand to u can give the school and username again but u don't need to in that case u can use `get_access_token(school,username)`\n## get raw schedule\n```python\nraw_schedule = zermelo.get_schedule()\n```\nu can give the week number and or year of u wand to else it uses the current year/week u can use `get_schedule(week=02)`,`get_schedule(year=2024)`or`get_schedule(year=2024,week=02)`\n## get schedule\n```python\nraw_schedule = zermelo.get_schedule()\n```\nu can give the week number and or year of u wand to else it uses the current year/week u can use `get_schedule(week=02)`,`get_schedule(year=2024)`or`get_schedule(year=2024,week=02)`and u you can pass a rawshedule from get_raw_shedule()\n## sort schedule\n```python\nsorted_schedule = zermelo.sort_schedule()\n```\nlike before u can give the week and year but u can also give the schedule from [`get_schedule()`](#get-schedule) instead to sort it defaults to getting it self but if u give it uses that one u can do that by using it like this `sort_schedule(schedule)` for the week and year it is the same syntax\n## readable schedule\n```python\nreadable = zermelo.readable_schedule()\n```\nagain u can give it week and year with the same syntax as before also you can give it a sorted schedule (output from [`sort_schedule()`](#sort-schedule)) by using `readable_schedule(sorted_schedule)`\n## print schedule\n```python\nzermelo.print_schedule()\n```\nyes u can use it like this `zermelo.print_schedule(zermelo.readable_schedule())` but **WHY** if u wand that use it like that just `print(zermelo.readable_schedule())` the only use is that it defaults to `zermelo.readable_schedule()`\n# [source code](https://github.com/btpv/zermeloapi)\n```python\n# from calendar import weekday\nimport os.path\nimport requests\nimport json\nimport time\nimport base64\n# from datetime import datetime\nimport datetime\nclass zermelo:\n expires_in = 0\n school = ''\n username = ''\n teacher = False\n debug = False\n TimeToAddToUtc = 0\n\n def __init__(self, school, username,password=None, teacher=False, version=3,debug=False,linkcode=None):\n self.school = school\n self.username = username\n self.teacher = teacher\n self.debug = debug\n self.version = 'v'+str(version)\n self.TimeToAddToUtc = self.get_date()[2]\n if linkcode == None and password != None:\n self.token = self.get_tokenfromusrpsw(school=school,username=username,password=password)\n else:\n self.token = self.gettokenfromfile(linkcode=linkcode)\n\n def updatetoken(self, linkcode):\n self.token = self.gettokenfromfile(linkcode=linkcode)\n def gettokenfromlinkcode(self, linkcode=None):\n if linkcode == None:\n linkcode = input(\"apitoken: \").replace(\" \",'')\n else:\n linkcode = str(linkcode).replace(\" \",'')\n return json.loads(requests.post(f\"https://ozhw.zportal.nl/api/v3/oauth/token?grant_type=authorization_code&code={linkcode}\").text)[\"access_token\"]\n def get_tokenfromusrpsw(self, school=None, username=None, password=None):\n if(school == None):\n school = self.school\n if (username == None):\n username = self.username\n if(password == None):\n password = self.password\n url = 'https://'+school+'.zportal.nl/api/'+self.version+'/oauth'\n myobj = {'username': username, 'password': password, 'client_id': 'OAuthPage', 'redirect_uri': '/main/',\n 'scope': '', 'state': '4E252A', 'response_type': 'code', 'tenant': school}\n x = requests.post(url, data=myobj,allow_redirects=False)\n respons = x.headers['Location']\n # exit(0)\n if self.debug:\n print(x.text)\n # exit(0)\n start = respons.find(\"code=\") + len(\"code=\")\n end = respons.find(\"&\", start)\n token = respons[start:end]\n start = respons.find(\"tenant=\") + len(\"tenant=\")\n end = respons.find(\"&\", start)\n school = respons[start:end]\n start = respons.find(\"expires_in=\") + len(\"expires_in=\")\n end = respons.find(\"&\", start)\n self.expires_in = respons[start:end]\n start = respons.find(\"loginMethod=\") + len(\"loginMethod=\")\n end = respons.find(\"&\", start)\n self.loginMethod = respons[start:end]\n start = respons.find(\"interfaceVersion=\") + len(\"interfaceVersion=\")\n end = respons.find(\"&\", start)\n self.interfaceVersion = respons[start:end]\n if(school == None):\n school = self.school\n if(token == None):\n token = self.get_token()\n print(token)\n url = 'https://' + school+'.zportal.nl/api/'+self.version+'/oauth/token'\n myobj = {'code': token, 'client_id': 'ZermeloPortal', 'client_secret': 42,\n 'grant_type': 'authorization_code', 'rememberMe': False}\n print(\"\\n\\n\")\n print(myobj,url)\n l = requests.post(url, data=myobj)\n if self.debug:\n print(l.text)\n jl = json.loads(l.text)\n token = jl['access_token']\n return(token)\n\n def gettokenfromfile(self, file=\"./token\", linkcode=None):\n if not os.path.exists(file):\n self.settokentofile(linkcode=linkcode)\n with open(file) as f:\n filevalue = f.read()\n return str(base64.b64decode(filevalue))[2:-1]\n def settokentofile(self,token=None,file=\"./token\",linkcode=None):\n if token == None:\n token = self.gettokenfromlinkcode(linkcode=linkcode)\n file = str(base64.b64encode(bytes(token, \"utf-8\")))[2:-1]\n with open(\"./token\", \"w\") as f:\n f.write(str(file))\n def get_date(self):\n now = datetime.datetime.now()\n return (now.year,now.isocalendar()[1],int((datetime.datetime.fromtimestamp(now.timestamp()) - datetime.datetime.utcfromtimestamp(now.timestamp())).total_seconds() / 3600))\n \n\n def get_raw_schedule(self, year:int=None, week:int=None, username:str=None,teacher:bool = False) -> dict:\n time = self.get_date()\n if year == None:\n year = time[0]\n if week == None:\n week = time[1]\n if username == None:\n url = f\"https://{self.school}.zportal.nl/api/v3/liveschedule?access_token={self.token}&{'teacher' if (self.teacher) else 'student'}={self.username}&week={year}{week:0>2}\"\n else:\n start = str(datetime.datetime.strptime(f\"{year}-{week}-0\",\"%Y-%U-%w\").timestamp())[0:-2]\n end = str(datetime.datetime.strptime(f\"{year}-{week}-6\",\"%Y-%U-%w\").timestamp())[0:-2]\n url = f\"https://{self.school}.zportal.nl/api/v3/appointments?access_token={self.token}&start={start}&end={end}&{'teachers' if (teacher) else 'possibleStudents'}={username}\"\n if self.debug:\n print(url)\n rawr = requests.get(url)\n if self.debug:\n print(rawr)\n rl = json.loads(rawr.text)\n return rl\n def get_schedule(self,rawschedule:dict=None,year=None, week=None,username=None,teacher=None):\n if rawschedule == None:\n rawschedule = self.get_raw_schedule(year=year,week=week,username=username,teacher=teacher)\n response = rawschedule[\"response\"]\n if username != None:\n appointments = response[\"data\"]\n else:\n data = response[\"data\"][0]\n appointments = data[\"appointments\"]\n return(appointments)\n\n def sort_schedule(self, schedule=None, year=None, week=None,username=None,teacher=None):\n if(schedule == None):\n schedule = self.get_schedule(year=year, week=week,username=username,teacher=teacher)\n pdate = 0\n days = [[[], []]]\n thisweek = {}\n for les in schedule:\n date = datetime.datetime.utcfromtimestamp(les[\"start\"]).strftime('%Y%m%d')\n hour = str(int(datetime.datetime.utcfromtimestamp(\n les[\"start\"]).strftime('%H')) + self.TimeToAddToUtc)\n time = datetime.datetime.utcfromtimestamp(les[\"start\"]).strftime('%Y-%m-%d ') + (hour if int(\n hour) > 9 else ('0'+hour)) + datetime.datetime.utcfromtimestamp(les[\"start\"]).strftime(':%M')\n ehour = str(int(datetime.datetime.utcfromtimestamp(\n les[\"end\"]).strftime('%H')) + self.TimeToAddToUtc)\n etime = datetime.datetime.utcfromtimestamp(les[\"end\"]).strftime('%Y-%m-%d ') + (ehour if int(\n ehour) > 9 else ('0'+ehour)) + datetime.datetime.utcfromtimestamp(les[\"end\"]).strftime(':%M')\n # print(les[\"status\"])\n if username != None:\n code = 2002\n if les[\"cancelled\"] or not les[\"valid\"]:\n code = 4007\n elif les[\"moved\"]:\n code = 3012\n elif les[\"modified\"]:\n code = 3011\n if not date in thisweek:\n thisweek[date] = [[],[]]\n if (not les[\"cancelled\"] and les[\"valid\"]):\n thisweek[date][0].append([les[\"subjects\"][0], time, etime,\n str(les[\"locations\"]), [{\"code\":code}], False])\n else:\n thisweek[date][1].append([les[\"subjects\"][0], time, etime,\n str(les[\"locations\"]), [{\"code\":code}], False])\n else:\n if date != pdate:\n days.append([[], []])\n if self.debug:\n print(les)\n if not (les == None or len(les[\"status\"]) < 1):\n if (les[\"status\"][0][\"code\"] < 3000 and les[\"status\"][0][\"code\"] >= 2000):\n days[-1][0].append([les[\"subjects\"][0], time, etime,\n str(les[\"locations\"]), les[\"status\"], les[\"online\"]])\n else:\n days[-1][1].append([les[\"subjects\"][0], time, etime,\n str(les[\"locations\"]), les[\"status\"], les[\"online\"]])\n pdate = date\n if username != None:\n thisweekdayssorted = [thisweek[i] for i in [str(c) for c in sorted([int(i) for i in thisweek.keys()])]]\n days = []\n for v in thisweekdayssorted:\n part = []\n for v2 in v:\n part.append(sorted(v2,key = lambda x: int(x[1].replace(\":\",\"\").replace(\"-\",\"\").replace(\" \",\"\"))))\n days.append(part)\n else:\n days.pop(0)\n return(days)\n\n def readable_schedule(self, days=None, year=None, week=None,username=None,teacher=None):\n result = ''\n if(days == None):\n days = self.sort_schedule(year=year, week=week,username=username,teacher=teacher)\n daysofweek = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n for i,day in enumerate(days):\n if len(day[0]) > 0:\n result += (daysofweek[i]+\"\\nstart: \"+day[0][0][1]+\"\\tend: \"+day[0][-1][2]+'\\n')\n else:\n result += (f\"{daysofweek[i]}\\n\")\n for les in day[0]:\n if (les[4][0][\"code\"] < 4000 and les[4][0][\"code\"] >= 2000):\n # if True:\n result += f\"les: {les[0].ljust(8, ' ')} lokaal: {('\ud83d\udcf7'if(les[5])else (les[3][2:-2]if(len(les[3][2:-2]) > 0)else '----')).ljust(8, ' ')} start: {les[1]}\\tend: {les[2]}\\n\"\n pass\n result += (\"\\n\\n\")\n return result\n\n def print_schedule(self, readable=None, days=None, year=None, week=None,username=None,teacher=None):\n if(readable == None):\n readable = self.readable_schedule(days=days, year=year, week=week,username=username,teacher=teacher)\n print(readable)\n\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "zermelo api",
"version": "2024.1.8.10.51.44",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e85b5907e32ec25f89289c8365c9a901df8823341b50d666b44a3db7e3323543",
"md5": "d85703464116b67fb110877759a0567c",
"sha256": "26e2a48122b21002bf0d6548799dfb17126b9db70b777529c7fed17ed8bc0d1b"
},
"downloads": -1,
"filename": "zermeloapi-2024.1.8.10.51.44-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d85703464116b67fb110877759a0567c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.0",
"size": 8178,
"upload_time": "2024-01-08T09:51:45",
"upload_time_iso_8601": "2024-01-08T09:51:45.513399Z",
"url": "https://files.pythonhosted.org/packages/e8/5b/5907e32ec25f89289c8365c9a901df8823341b50d666b44a3db7e3323543/zermeloapi-2024.1.8.10.51.44-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-08 09:51:45",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "zermeloapi"
}