linting
This commit is contained in:
+102
-6
@@ -3,15 +3,21 @@ from datetime import date
|
||||
|
||||
|
||||
class Builder:
|
||||
"""A class method for creating a new class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the object for the OpenMensa Feed Doc XML."""
|
||||
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(
|
||||
"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",
|
||||
"http://openmensa.org/open-mensa-v2 "
|
||||
+ "http://openmensa.org/open-mensa-v2.xsd",
|
||||
)
|
||||
self._version = None
|
||||
self._name = None
|
||||
@@ -28,6 +34,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
"""The version of the device .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._version
|
||||
|
||||
@version.setter
|
||||
@@ -40,6 +51,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name of the canteen .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
@@ -52,12 +68,17 @@ class Builder:
|
||||
|
||||
@property
|
||||
def address(self):
|
||||
"""The address of the canteen .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
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}"
|
||||
street_nr, zip_code, city = value
|
||||
self._address = f"{street_nr}, {zip_code} {city}"
|
||||
|
||||
@address.deleter
|
||||
def address(self):
|
||||
@@ -65,6 +86,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def city(self):
|
||||
"""Get the city of the canteen .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._city
|
||||
|
||||
@city.setter
|
||||
@@ -77,6 +103,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def phone(self):
|
||||
"""The phone number .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._phone
|
||||
|
||||
@phone.setter
|
||||
@@ -89,6 +120,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def email(self):
|
||||
"""The email address of the canteen .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._email
|
||||
|
||||
@email.setter
|
||||
@@ -101,6 +137,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""Get a tuple containing the location as latitude and longitude .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return (self._longitude, self._latitude)
|
||||
|
||||
@location.setter
|
||||
@@ -115,6 +156,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def availability(self):
|
||||
"""Whether the canteen is public or restriced.
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._availability
|
||||
|
||||
@availability.setter
|
||||
@@ -130,11 +176,22 @@ class Builder:
|
||||
|
||||
@property
|
||||
def times(self):
|
||||
"""Get the opening times the canteen.
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._times
|
||||
|
||||
@times.setter
|
||||
def times(self, value: dict[str, str]):
|
||||
def attach_weekday(tag: str, value: str):
|
||||
"""Attach a week tag to the week .
|
||||
|
||||
Args:
|
||||
tag (str): [description]
|
||||
value (str): [description]
|
||||
"""
|
||||
if value == "":
|
||||
return
|
||||
d = self._doc.createElement(tag)
|
||||
@@ -167,17 +224,31 @@ class Builder:
|
||||
|
||||
@property
|
||||
def feed(self):
|
||||
"""Get a feed object .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._feed
|
||||
|
||||
@feed.setter
|
||||
def feed(self, value: dict):
|
||||
"""Set the feed element .
|
||||
|
||||
Args:
|
||||
value (dict): [description]
|
||||
"""
|
||||
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 "*"
|
||||
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")
|
||||
@@ -211,6 +282,11 @@ class Builder:
|
||||
|
||||
@property
|
||||
def day(self):
|
||||
"""Returns the number of day of the week .
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._day
|
||||
|
||||
@day.setter
|
||||
@@ -229,6 +305,15 @@ class Builder:
|
||||
prices: dict[str, float],
|
||||
note: str = None,
|
||||
):
|
||||
"""Add a meal element to the document .
|
||||
|
||||
Args:
|
||||
date (date): [description]
|
||||
category (str): [description]
|
||||
name (str): [description]
|
||||
prices (dict[str, float]): [description]
|
||||
note (str, optional): [description]. Defaults to None.
|
||||
"""
|
||||
meal = self._doc.createElement("meal")
|
||||
node = self._doc.createElement("name")
|
||||
meal.appendChild(node)
|
||||
@@ -270,12 +355,23 @@ class Builder:
|
||||
meal_list.append(meal)
|
||||
|
||||
def __append_node(self, tag: str, value: str):
|
||||
"""Create a node with a tag and text .
|
||||
|
||||
Args:
|
||||
tag (str): [description]
|
||||
value (str): [description]
|
||||
"""
|
||||
elem = self._doc.createElement(tag)
|
||||
self._canteen.appendChild(elem)
|
||||
node = self._doc.createTextNode(value)
|
||||
elem.appendChild(node)
|
||||
|
||||
def toXML(self):
|
||||
"""Return a XML string representing the canteen.
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
self._doc.appendChild(self._om)
|
||||
if self.version:
|
||||
self.__append_node("version", self.version)
|
||||
|
||||
@@ -6,9 +6,16 @@ import json
|
||||
|
||||
|
||||
class SWP_Webspeiseplan_API:
|
||||
"""This class is used download content from SWP_Webspeiseplan.
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
|
||||
URL_BASE = "https://swp.webspeiseplan.de"
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the configuration for the web service ."""
|
||||
logging.basicConfig()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.__parse_token()
|
||||
@@ -20,7 +27,9 @@ class SWP_Webspeiseplan_API:
|
||||
"_": int(time.time() * 1000),
|
||||
}
|
||||
|
||||
self.outlets = {outlet["name"]: outlet for outlet in self.__parse_model(params)}
|
||||
self.outlets = {
|
||||
outlet["name"]: outlet for outlet in self.__parse_model(params)
|
||||
}
|
||||
self.menus = {}
|
||||
self.meal_categories = {}
|
||||
for outlet in self.outlets.values():
|
||||
@@ -38,6 +47,7 @@ class SWP_Webspeiseplan_API:
|
||||
self.meal_categories[outlet["name"]] = id2cat
|
||||
|
||||
def __parse_token(self):
|
||||
"""Get the token from the proxy server."""
|
||||
req = urllib.request.Request(self.URL_BASE)
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
txt = resp.read().decode("utf-8")
|
||||
@@ -50,14 +60,23 @@ class SWP_Webspeiseplan_API:
|
||||
self.logger.debug(f"__parse_token: PROXY_TOKEN {self.proxy_token}")
|
||||
|
||||
def __spoof_req_headers(req: urllib.request.Request):
|
||||
req.add_header("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||
"""Add headers to a request .
|
||||
|
||||
Args:
|
||||
req (urllib.request.Request): [description]
|
||||
"""
|
||||
req.add_header(
|
||||
"Accept", "application/json, text/javascript, */*; q=0.01"
|
||||
)
|
||||
req.add_header("Accept-Language", "en-US,en;q=0.9")
|
||||
req.add_header("Connection", "keep-alive")
|
||||
req.add_header("Host", "swp.webspeiseplan.de")
|
||||
req.add_header("Referer", "https://swp.webspeiseplan.de/InitialConfig")
|
||||
req.add_header(
|
||||
"Sec-Ch-Ua",
|
||||
'"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"',
|
||||
'"Not/A)Brand";v="99", '
|
||||
+ '"Google Chrome";v="115", '
|
||||
+ '"Chromium";v="115"',
|
||||
)
|
||||
req.add_header("Sec-Ch-Ua-Mobile", "?0")
|
||||
req.add_header("Sec-Ch-Ua-Platform", "Linux")
|
||||
@@ -66,11 +85,21 @@ class SWP_Webspeiseplan_API:
|
||||
req.add_header("Sec-Fetch-Site", "same-origin")
|
||||
req.add_header(
|
||||
"User-Agent",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) "
|
||||
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
+ "Chrome/115.0.0.0 Safari/537.36",
|
||||
)
|
||||
req.add_header("X-Requested-With", "XMLHttpRequest")
|
||||
|
||||
def __parse_model(self, params: dict):
|
||||
"""Retrieve data from host.
|
||||
|
||||
Args:
|
||||
params (dict): [description]
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
url = f"{self.URL_BASE}/index.php?" + "&".join(
|
||||
[f"{k}={v}" for k, v in params.items()]
|
||||
)
|
||||
@@ -80,4 +109,3 @@ class SWP_Webspeiseplan_API:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
data = resp.read()
|
||||
return json.loads(data)["content"]
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ from stw_potsdam.swp_webspeiseplan_api import SWP_Webspeiseplan_API
|
||||
|
||||
|
||||
class SWP_Webspeiseplan_Parser:
|
||||
"""Class method to parse SWP_Webspeiseplan."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
menu_data: list[dict],
|
||||
@@ -12,6 +14,14 @@ class SWP_Webspeiseplan_Parser:
|
||||
outlet_data: dict,
|
||||
url: str,
|
||||
):
|
||||
"""Initialize the parser .
|
||||
|
||||
Args:
|
||||
menu_data (list[dict]): [description]
|
||||
meal_categories (list[dict]): [description]
|
||||
outlet_data (dict): [description]
|
||||
url (str): [description]
|
||||
"""
|
||||
logging.basicConfig()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.menu_data = menu_data
|
||||
@@ -24,6 +34,11 @@ class SWP_Webspeiseplan_Parser:
|
||||
self.__parse_meals()
|
||||
|
||||
def __parse_canteen(self, outlet: dict):
|
||||
"""Parse the outlet data from outlet.
|
||||
|
||||
Args:
|
||||
outlet (dict): [description]
|
||||
"""
|
||||
canteen = self._builder
|
||||
canteen.name = outlet["name"]
|
||||
canteen.address = (
|
||||
@@ -53,13 +68,16 @@ class SWP_Webspeiseplan_Parser:
|
||||
}
|
||||
|
||||
times = {
|
||||
k: v.replace("None, None", "").replace("None,", "").replace(", None", "")
|
||||
k: v.replace("None, None", "")
|
||||
.replace("None,", "")
|
||||
.replace(", None", "")
|
||||
for k, v in times.items()
|
||||
}
|
||||
|
||||
canteen.times = times
|
||||
|
||||
def __parse_feed(self):
|
||||
"""Parse feed and set feed."""
|
||||
feed = {
|
||||
"name": "full",
|
||||
"priority": 0,
|
||||
@@ -71,6 +89,7 @@ class SWP_Webspeiseplan_Parser:
|
||||
self._builder.feed = feed
|
||||
|
||||
def __parse_meals(self):
|
||||
"""Parse the menu and adds it to the builder."""
|
||||
for menu in self.menu_data:
|
||||
for meal in menu["speiseplanGerichtData"]:
|
||||
info = meal["speiseplanAdvancedGericht"]
|
||||
@@ -78,7 +97,9 @@ class SWP_Webspeiseplan_Parser:
|
||||
additional_info = meal["zusatzinformationen"]
|
||||
self._builder.add_meal(
|
||||
date=date,
|
||||
category=self.meal_categories[info["gerichtkategorieID"]]["name"],
|
||||
category=self.meal_categories[info["gerichtkategorieID"]][
|
||||
"name"
|
||||
],
|
||||
name=info["gerichtname"],
|
||||
prices={
|
||||
"student": additional_info["mitarbeiterpreisDecimal2"],
|
||||
@@ -89,4 +110,9 @@ class SWP_Webspeiseplan_Parser:
|
||||
|
||||
@property
|
||||
def xml_feed(self):
|
||||
"""Return the XML string of the builder.
|
||||
|
||||
Returns:
|
||||
[type]: [description]
|
||||
"""
|
||||
return self._builder.toXML()
|
||||
|
||||
@@ -45,6 +45,7 @@ def get_menu():
|
||||
log.debug("Downloading menu for SWP")
|
||||
return SWP_Webspeiseplan_API()
|
||||
|
||||
|
||||
@app.route("/canteens/<canteen_name>")
|
||||
@app.route("/canteens/<canteen_name>/xml")
|
||||
def canteen_xml_feed(canteen_name):
|
||||
@@ -63,9 +64,10 @@ def canteen_xml_feed(canteen_name):
|
||||
)
|
||||
xml = swp_parser.xml_feed.decode()
|
||||
response = make_response(xml)
|
||||
response.mimetype = 'text/xml'
|
||||
response.mimetype = "text/xml"
|
||||
return response
|
||||
|
||||
|
||||
@app.route("/")
|
||||
@app.route("/canteens")
|
||||
def canteen_index():
|
||||
|
||||
@@ -25,6 +25,7 @@ def _read_feed(resource_name):
|
||||
with io.open(_resource_path(resource_name), encoding='utf-8') as xml:
|
||||
return xml.read()
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_meta_consistency():
|
||||
raise NotImplementedError()
|
||||
@@ -34,6 +35,7 @@ def test_meta_consistency():
|
||||
expected = _read_feed('meta_output.xml')
|
||||
assert expected == actual
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_menu_consistency():
|
||||
raise NotImplementedError()
|
||||
@@ -42,6 +44,7 @@ def test_menu_consistency():
|
||||
expected = _read_feed('menu_output.xml')
|
||||
assert expected == actual
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_empty_menu():
|
||||
raise NotImplementedError()
|
||||
@@ -50,6 +53,7 @@ def test_empty_menu():
|
||||
expected = _read_feed('empty_menu_output.xml')
|
||||
assert expected == actual
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_offers_dictionary():
|
||||
raise NotImplementedError()
|
||||
@@ -58,6 +62,7 @@ def test_offers_dictionary():
|
||||
expected = _read_feed('offers-dict-output.xml')
|
||||
assert expected == actual
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_missing_category():
|
||||
raise NotImplementedError()
|
||||
|
||||
+3
-1
@@ -48,11 +48,13 @@ def test_canteen_not_found(client, url):
|
||||
def test_canteen_menu_api_unavailable(client, api_offline):
|
||||
_request_check_meals(client)
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_canteen_menu_request(client, api_online_one_shot):
|
||||
raise NotImplementedError()
|
||||
_request_check_meals(client)
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def test_canteen_menu_cached(client, api_online_one_shot):
|
||||
raise NotImplementedError()
|
||||
@@ -66,8 +68,8 @@ def test_canteen_menu_second_request_indeed_fails(client, api_online_one_shot):
|
||||
views.cache.clear()
|
||||
_request_check_meals(client)
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
def _request_check_meals(client):
|
||||
raise NotImplementedError()
|
||||
response = client.get("/canteens/griebnitzsee/xml")
|
||||
|
||||
Reference in New Issue
Block a user