Skip to content

Commit 582b292

Browse files
authored
Add support for all meals (#87)
* Add support for more meals, refactor the examples * Rename occurences of `lunch` to `meal` to improve naming consistency * Add a `MealType` enum
1 parent e8a0431 commit 582b292

File tree

6 files changed

+134
-74
lines changed

6 files changed

+134
-74
lines changed

edupage_api/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from edupage_api.custom_request import CustomRequest
1313
from edupage_api.grades import EduGrade, Grades, Term
1414
from edupage_api.login import Login, TwoFactorLogin
15-
from edupage_api.lunches import Lunch, Lunches
15+
from edupage_api.lunches import Lunches, Meals
1616
from edupage_api.messages import Messages
1717
from edupage_api.module import EdupageModule
1818
from edupage_api.parent import Parent
@@ -163,7 +163,7 @@ def get_my_timetable(self, date: date) -> Optional[Timetable]:
163163

164164
return Timetables(self).get_my_timetable(date)
165165

166-
def get_lunches(self, date: date) -> Optional[Lunch]:
166+
def get_meals(self, date: date) -> Optional[Meals]:
167167
"""Get lunches.
168168
169169
Args:
@@ -173,7 +173,7 @@ def get_lunches(self, date: date) -> Optional[Lunch]:
173173
Optional[Lunch]: Lunch object for entered date.
174174
"""
175175

176-
return Lunches(self).get_lunch(date)
176+
return Lunches(self).get_meals(date)
177177

178178
def get_notifications(self) -> list[TimelineEvent]:
179179
"""Get list of all available notifications.

edupage_api/exceptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class FailedToRateException(Exception):
1818
pass
1919

2020

21-
class FailedToChangeLunchError(Exception):
21+
class FailedToChangeMealError(Exception):
2222
pass
2323

2424

@@ -42,7 +42,7 @@ class RequestError(Exception):
4242
pass
4343

4444

45-
class InvalidLunchData(Exception):
45+
class InvalidMealsData(Exception):
4646
pass
4747

4848

edupage_api/lunches.py

Lines changed: 76 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
from dataclasses import dataclass
33
from datetime import date, datetime
44
from typing import List, Optional
5+
from enum import Enum
56

67
from edupage_api.exceptions import (
7-
FailedToChangeLunchError,
8+
FailedToChangeMealError,
89
FailedToRateException,
9-
InvalidLunchData,
10+
InvalidMealsData,
1011
NotLoggedInException,
1112
)
1213
from edupage_api.module import EdupageModule, Module, ModuleHelper
@@ -54,9 +55,13 @@ class Menu:
5455
number: str
5556
rating: Optional[Rating]
5657

58+
class MealType(Enum):
59+
SNACK = 1
60+
LUNCH = 2
61+
AFTERNOON_SNACK = 3
5762

5863
@dataclass
59-
class Lunch:
64+
class Meal:
6065
served_from: Optional[datetime]
6166
served_to: Optional[datetime]
6267
amount_of_foods: int
@@ -65,8 +70,10 @@ class Lunch:
6570
title: str
6671
menus: List[Menu]
6772
date: datetime
68-
ordered_lunch: Optional[str]
73+
ordered_meal: Optional[str]
74+
meal_type: MealType
6975
__boarder_id: str
76+
__meal_index: str
7077

7178
def __iter__(self):
7279
return iter(self.menus)
@@ -77,7 +84,7 @@ def __make_choice(self, edupage: EdupageModule, choice_str: str):
7784
boarder_menu = {
7885
"stravnikid": self.__boarder_id,
7986
"mysqlDate": self.date.strftime("%Y-%m-%d"),
80-
"jids": {"2": choice_str},
87+
"jids": {self.__meal_index: choice_str},
8188
"view": "pc_listok",
8289
"pravo": "Student",
8390
}
@@ -92,55 +99,46 @@ def __make_choice(self, edupage: EdupageModule, choice_str: str):
9299
).content.decode()
93100

94101
if json.loads(response).get("error") != "":
95-
raise FailedToChangeLunchError()
102+
raise FailedToChangeMealError()
96103

97104
def choose(self, edupage: EdupageModule, number: int):
98105
letters = "ABCDEFGH"
99106
letter = letters[number - 1]
100107

101108
self.__make_choice(edupage, letter)
102-
self.ordered_lunch = letter
109+
self.ordered_meal = letter
103110

104111
def sign_off(self, edupage: EdupageModule):
105112
self.__make_choice(edupage, "AX")
106-
self.ordered_lunch = None
113+
self.ordered_meal = None
107114

115+
@dataclass
116+
class Meals:
117+
snack: Optional[Meal]
118+
lunch: Optional[Meal]
119+
afternoon_snack: Optional[Meal]
120+
108121

109-
class Lunches(Module):
110-
@ModuleHelper.logged_in
111-
def get_lunch(self, date: date):
112-
date_strftime = date.strftime("%Y%m%d")
113-
request_url = f"https://{self.edupage.subdomain}.edupage.org/menu/?date={date_strftime}"
114-
response = self.edupage.session.get(request_url).content.decode()
115-
116-
lunch_data = json.loads(
117-
response.split("edupageData: ")[1].split(",\r\n")[0]
118-
)
119-
lunches_data = lunch_data.get(self.edupage.subdomain)
120-
try:
121-
boarder_id = (
122-
lunches_data.get("novyListok").get("addInfo").get("stravnikid")
123-
)
124-
except AttributeError as e:
125-
raise InvalidLunchData(f"Missing boarder id: {e}")
126-
127-
lunch = lunches_data.get("novyListok").get(date.strftime("%Y-%m-%d"))
128-
lunch = lunch.get("2")
129122

130-
if lunch.get("isCooking") == False:
131-
return "Not cooking"
123+
class Lunches(Module):
124+
def parse_meal(self, meal_index: str, meal: dict, boarder_id: str, date: date) -> Optional[Meal]:
125+
if meal is None:
126+
return None
127+
128+
if meal.get("isCooking") == False:
129+
return None
132130

133-
ordered_lunch = None
134-
lunch_record = lunch.get("evidencia")
131+
ordered_meal = None
132+
meal_record = meal.get("evidencia")
135133

136-
if lunch_record is not None:
137-
ordered_lunch = lunch_record.get("stav")
134+
if meal_record is not None:
135+
ordered_meal = meal_record.get("stav")
138136

139-
if ordered_lunch == "V":
140-
ordered_lunch = lunch_record.get("obj")
137+
if ordered_meal == "V":
138+
ordered_meal = meal_record.get("obj")
141139

142-
served_from_str = lunch.get("vydaj_od")
143-
served_to_str = lunch.get("vydaj_do")
140+
served_from_str = meal.get("vydaj_od")
141+
served_to_str = meal.get("vydaj_do")
144142

145143
if served_from_str:
146144
served_from = datetime.strptime(served_from_str, "%H:%M")
@@ -152,16 +150,16 @@ def get_lunch(self, date: date):
152150
else:
153151
served_to = None
154152

155-
title = lunch.get("nazov")
153+
title = meal.get("nazov")
156154

157-
amount_of_foods = lunch.get("druhov_jedal")
158-
chooseable_menus = list(lunch.get("choosableMenus").keys())
155+
amount_of_foods = meal.get("druhov_jedal")
156+
chooseable_menus = list(meal.get("choosableMenus").keys())
159157

160-
can_be_changed_until = lunch.get("zmen_do")
158+
can_be_changed_until = meal.get("zmen_do")
161159

162160
menus = []
163161

164-
for food in lunch.get("rows"):
162+
for food in meal.get("rows"):
165163
if not food:
166164
continue
167165

@@ -173,7 +171,7 @@ def get_lunch(self, date: date):
173171

174172
if number is not None:
175173
number = number.replace(": ", "")
176-
rating = lunch.get("hodnotenia")
174+
rating = meal.get("hodnotenia")
177175
if rating is not None and rating:
178176
rating = rating.get(number)
179177

@@ -196,7 +194,8 @@ def get_lunch(self, date: date):
196194
else:
197195
rating = None
198196
menus.append(Menu(name, allergens, weight, number, rating))
199-
return Lunch(
197+
198+
return Meal(
200199
served_from,
201200
served_to,
202201
amount_of_foods,
@@ -205,6 +204,37 @@ def get_lunch(self, date: date):
205204
title,
206205
menus,
207206
date,
208-
ordered_lunch,
207+
ordered_meal,
208+
MealType(int(meal_index)),
209209
boarder_id,
210+
meal_index
211+
)
212+
213+
@ModuleHelper.logged_in
214+
def get_meals(self, date: date) -> Optional[Meals]:
215+
date_strftime = date.strftime("%Y%m%d")
216+
request_url = f"https://{self.edupage.subdomain}.edupage.org/menu/?date={date_strftime}"
217+
response = self.edupage.session.get(request_url).content.decode()
218+
219+
lunch_data = json.loads(
220+
response.split("edupageData: ")[1].split(",\r\n")[0]
210221
)
222+
lunches_data = lunch_data.get(self.edupage.subdomain)
223+
try:
224+
boarder_id = (
225+
lunches_data.get("novyListok").get("addInfo").get("stravnikid")
226+
)
227+
except AttributeError as e:
228+
raise InvalidMealsData(f"Missing boarder id: {e}")
229+
230+
meals = lunches_data.get("novyListok").get(date.strftime("%Y-%m-%d"))
231+
if meals is None:
232+
return None
233+
234+
snack = self.parse_meal("1", meals.get("1"), boarder_id, date)
235+
lunch = self.parse_meal("2", meals.get("2"), boarder_id, date)
236+
afternoon_snack = self.parse_meal("3", meals.get("3"), boarder_id, date)
237+
238+
return Meals(snack, lunch, afternoon_snack)
239+
240+

examples/lunch.py

Lines changed: 0 additions & 23 deletions
This file was deleted.

examples/lunch_choose.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import sys
2+
3+
from datetime import datetime
4+
from edupage_api import Edupage
5+
6+
edupage = Edupage()
7+
edupage.login_auto("Username (or e-mail)", "Password")
8+
9+
today = datetime.now()
10+
meals = edupage.get_meals(today)
11+
12+
if meals is None:
13+
print(f"No meal choices for today ({today.date()}) yet!")
14+
sys.exit(0)
15+
16+
for meal_name, meal in [("snack", meals.snack), ("lunch", meals.lunch), ("afternoon snack", meals.afternoon_snack)]:
17+
if meal is None:
18+
print(f"No {meal_name + ('es' if meal_name == 'lunch' else 's')} available!")
19+
continue
20+
21+
chosen_meal_index = (
22+
"ABCDEFGH".index(meal.ordered_meal) if meal.ordered_meal is not None else None
23+
)
24+
25+
for menu_index_str in meal.chooseable_menus:
26+
menu_index = int(menu_index_str)
27+
is_chosen = chosen_meal_index + 1 == menu_index
28+
print(f"[{menu_index_str}] {meal.menus[menu_index].name} {'(chosen)' if is_chosen else ''}")
29+
30+
lunch_n = input(f"Which {meal_name} do you want? ")
31+
while lunch_n not in meal.chooseable_menus and lunch_n != "-1":
32+
lunch_n = input(f"Which {meal_name} do you want? ")
33+
34+
if lunch_n != "-1":
35+
meal.choose(edupage, int(lunch_n))
36+
37+
print("Ok!")

examples/lunch_simple.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from edupage_api import Edupage
2+
from datetime import datetime
3+
4+
edupage = Edupage()
5+
edupage.login_auto("Username (or e-mail)", "Password")
6+
7+
meals = edupage.get_meals(datetime.today().date())
8+
9+
lunch = meals.lunch
10+
print(lunch.menus)
11+
12+
snack = meals.snack
13+
print(snack.menus)
14+
15+
# i don't want a snack for today!
16+
snack.sign_off(edupage)

0 commit comments

Comments
 (0)