317 lines
9.2 KiB
Python
317 lines
9.2 KiB
Python
from xml.dom import minidom
|
|
from datetime import date
|
|
|
|
|
|
class Builder:
|
|
def __init__(self):
|
|
self._doc = minidom.Document()
|
|
self._om = self._doc.createElement("openmensa")
|
|
self._om.setAttribute("version", "2.1")
|
|
self._om.setAttribute("xmlns", "http://openmensa.org/open-mensa-v2")
|
|
self._om.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
|
self._om.setAttribute(
|
|
"xsi:schemaLocation",
|
|
"http://openmensa.org/open-mensa-v2 http://openmensa.org/open-mensa-v2.xsd",
|
|
)
|
|
self._version = None
|
|
self._name = None
|
|
self._address = None
|
|
self._city = None
|
|
self._phone = None
|
|
self._email = None
|
|
self._location = None
|
|
self._availability = None
|
|
self._times = None
|
|
self._feed = None
|
|
self._day = None
|
|
self._days: dict[date, dict[str, list]] = {}
|
|
|
|
@property
|
|
def version(self):
|
|
return self._version
|
|
|
|
@version.setter
|
|
def version(self, value: str):
|
|
self._version = value
|
|
|
|
@version.deleter
|
|
def version(self):
|
|
del self._version
|
|
|
|
@property
|
|
def name(self):
|
|
return self._name
|
|
|
|
@name.setter
|
|
def name(self, value: str):
|
|
self._name = value
|
|
|
|
@name.deleter
|
|
def name(self):
|
|
del self._name
|
|
|
|
@property
|
|
def address(self):
|
|
return self._address
|
|
|
|
@address.setter
|
|
def address(self, value: tuple[str, str, str]):
|
|
street_nr, zip, city = value
|
|
self._address = f"{street_nr}, {zip} {city}"
|
|
|
|
@address.deleter
|
|
def address(self):
|
|
del self._address
|
|
|
|
@property
|
|
def city(self):
|
|
return self._city
|
|
|
|
@city.setter
|
|
def city(self, value: str):
|
|
self._city = value
|
|
|
|
@city.deleter
|
|
def city(self):
|
|
del self._city
|
|
|
|
@property
|
|
def phone(self):
|
|
return self._phone
|
|
|
|
@phone.setter
|
|
def phone(self, value: str):
|
|
self._phone = value
|
|
|
|
@phone.deleter
|
|
def phone(self):
|
|
del self._phone
|
|
|
|
@property
|
|
def email(self):
|
|
return self._email
|
|
|
|
@email.setter
|
|
def email(self, value: str):
|
|
self._email = value
|
|
|
|
@email.deleter
|
|
def email(self):
|
|
del self._email
|
|
|
|
@property
|
|
def location(self):
|
|
return (self._longitude, self._latitude)
|
|
|
|
@location.setter
|
|
def location(self, value: tuple[float, float]):
|
|
self._longitude = value[0]
|
|
self._latitude = value[1]
|
|
|
|
@location.deleter
|
|
def location(self):
|
|
del self._longitude
|
|
del self._latitude
|
|
|
|
@property
|
|
def availability(self):
|
|
return self._availability
|
|
|
|
@availability.setter
|
|
def availability(self, value: str):
|
|
if value == "pulbic" or value == "restricted":
|
|
self._availability = value
|
|
else:
|
|
raise ValueError("only 'public' or 'restricted are allowed.")
|
|
|
|
@availability.deleter
|
|
def availability(self):
|
|
del self._availability
|
|
|
|
@property
|
|
def times(self):
|
|
return self._times
|
|
|
|
@times.setter
|
|
def times(self, value: dict[str, str]):
|
|
def attach_weekday(tag: str, value: str):
|
|
if value == "":
|
|
return
|
|
d = self._doc.createElement(tag)
|
|
if value == "geschlossen":
|
|
d.setAttribute("closed", "true")
|
|
else:
|
|
d.setAttribute("open", value)
|
|
self._times.appendChild(d)
|
|
|
|
weekdays = (
|
|
"monday",
|
|
"tuesday",
|
|
"wednesday",
|
|
"thursday",
|
|
"friday",
|
|
"saturday",
|
|
"sunday",
|
|
)
|
|
self._times = self._doc.createElement("times")
|
|
self._times.setAttribute("type", "opening")
|
|
|
|
for weekday in weekdays:
|
|
v = value.get(weekday)
|
|
if v:
|
|
attach_weekday(weekday, v)
|
|
|
|
@times.deleter
|
|
def times(self):
|
|
del self._times
|
|
|
|
@property
|
|
def feed(self):
|
|
return self._feed
|
|
|
|
@feed.setter
|
|
def feed(self, value: dict):
|
|
name: str = value.get("name")
|
|
priority: int = value.get("priority")
|
|
url: str = value.get("url")
|
|
source: str = value.get("source")
|
|
hour: int = value.get("hour")
|
|
dayOfMonth: int | str = value.get("dayOfMonth") if value.get("dayOfMonth") else "*"
|
|
dayOfWeek: int | str = value.get("dayOfWeek") if value.get("dayOfWeek") else "*"
|
|
month: int | str = value.get("month") if value.get("month") else "*"
|
|
minute: int = value.get("minute") if value.get("minute") else 0
|
|
retry: str = value.get("retry")
|
|
|
|
self._feed = self._doc.createElement("feed")
|
|
self._feed.setAttribute("name", name)
|
|
self._feed.setAttribute("priority", str(priority))
|
|
schedule = self._doc.createElement("schedule")
|
|
self._feed.appendChild(schedule)
|
|
schedule.setAttribute("dayOfMonth", str(dayOfMonth))
|
|
schedule.setAttribute("dayOfWeek", str(dayOfWeek))
|
|
schedule.setAttribute("month", str(month))
|
|
schedule.setAttribute("hour", str(hour))
|
|
schedule.setAttribute("minute", str(minute))
|
|
if retry:
|
|
schedule.setAttribute("retry", retry)
|
|
|
|
el = self._doc.createElement("url")
|
|
self._feed.appendChild(el)
|
|
node = self._doc.createTextNode(url)
|
|
el.appendChild(node)
|
|
|
|
el = self._doc.createElement("source")
|
|
self._feed.appendChild(el)
|
|
node = self._doc.createTextNode(source)
|
|
el.appendChild(node)
|
|
|
|
@feed.deleter
|
|
def feed(self):
|
|
del self._feed
|
|
|
|
@property
|
|
def day(self):
|
|
return self._day
|
|
|
|
@day.setter
|
|
def day(self, value):
|
|
self._day = value
|
|
|
|
@day.deleter
|
|
def day(self):
|
|
del self._day
|
|
|
|
def add_meal(
|
|
self,
|
|
date: date,
|
|
category: str,
|
|
name: str,
|
|
prices: dict[str, float],
|
|
note: str = None,
|
|
):
|
|
meal = self._doc.createElement("meal")
|
|
node = self._doc.createElement("name")
|
|
meal.appendChild(node)
|
|
data = self._doc.createTextNode(name)
|
|
node.appendChild(data)
|
|
|
|
if note:
|
|
node = self._doc.createElement("note")
|
|
meal.appendChild(node)
|
|
data = self._doc.createTextNode(note)
|
|
node.appendChild(data)
|
|
|
|
if prices["student"]:
|
|
node = self._doc.createElement("price")
|
|
meal.appendChild(node)
|
|
node.setAttribute("role", "student")
|
|
data = self._doc.createTextNode(f'{prices["student"]:.2f}')
|
|
node.appendChild(data)
|
|
if prices["employee"]:
|
|
node = self._doc.createElement("price")
|
|
meal.appendChild(node)
|
|
node.setAttribute("role", "employee")
|
|
data = self._doc.createTextNode(f'{prices["employee"]:.2f}')
|
|
node.appendChild(data)
|
|
|
|
if prices["other"]:
|
|
node = self._doc.createElement("price")
|
|
meal.appendChild(node)
|
|
node.setAttribute("role", "other")
|
|
data = self._doc.createTextNode(f'{prices["other"]:.2f}')
|
|
node.appendChild(data)
|
|
|
|
category_dict = self._days.get(date, dict())
|
|
if not category_dict:
|
|
self._days[date] = category_dict
|
|
meal_list = category_dict.get(category, list())
|
|
if not meal_list:
|
|
category_dict[category] = meal_list
|
|
meal_list.append(meal)
|
|
|
|
def __append_node(self, tag: str, value: str):
|
|
elem = self._doc.createElement(tag)
|
|
self._canteen.appendChild(elem)
|
|
node = self._doc.createTextNode(value)
|
|
elem.appendChild(node)
|
|
|
|
def toXML(self):
|
|
self._doc.appendChild(self._om)
|
|
if self.version:
|
|
self.__append_node("version", self.version)
|
|
self._canteen = self._doc.createElement("canteen")
|
|
self._om.appendChild(self._canteen)
|
|
if self.name:
|
|
self.__append_node("name", self.name)
|
|
if self.address:
|
|
self.__append_node("address", self.address)
|
|
if self.city:
|
|
self.__append_node("city", self.city)
|
|
if self.phone:
|
|
self.__append_node("phone", self.phone)
|
|
if self.email:
|
|
self.__append_node("email", self.email)
|
|
if self._longitude and self._latitude:
|
|
location = self._doc.createElement("location")
|
|
self._canteen.appendChild(location)
|
|
location.setAttribute("latitude", str(self._latitude))
|
|
location.setAttribute("longitude", str(self._longitude))
|
|
if self.availability:
|
|
self.__append_node("availability", self.availability)
|
|
if self.times:
|
|
self._canteen.appendChild(self.times)
|
|
if self.feed:
|
|
self._canteen.appendChild(self.feed)
|
|
|
|
for date, category_dict in sorted(self._days.items()):
|
|
day = self._doc.createElement("day")
|
|
self._canteen.appendChild(day)
|
|
day.setAttribute("date", str(date))
|
|
for category_name, meals in sorted(category_dict.items()):
|
|
category = self._doc.createElement("category")
|
|
day.appendChild(category)
|
|
category.setAttribute("name", category_name)
|
|
for meal in meals:
|
|
category.appendChild(meal)
|
|
return self._doc.toprettyxml(encoding="UTF-8")
|