initial commit
This commit is contained in:
0
custom_components/afvalwijzer/collector/__init__.py
Normal file
0
custom_components/afvalwijzer/collector/__init__.py
Normal file
57
custom_components/afvalwijzer/collector/deafvalapp.py
Normal file
57
custom_components/afvalwijzer/collector/deafvalapp.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from datetime import datetime
|
||||
import re
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import _LOGGER, SENSOR_COLLECTORS_DEAFVALAPP
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
):
|
||||
if provider not in SENSOR_COLLECTORS_DEAFVALAPP.keys():
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
corrected_postal_code_parts = re.search(r"(\d\d\d\d) ?([A-z][A-z])", postal_code)
|
||||
corrected_postal_code = (
|
||||
corrected_postal_code_parts[1] + corrected_postal_code_parts[2].upper()
|
||||
)
|
||||
|
||||
try:
|
||||
url = SENSOR_COLLECTORS_DEAFVALAPP[provider].format(
|
||||
corrected_postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
)
|
||||
raw_response = requests.get(url)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
try:
|
||||
response = raw_response.text
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from e
|
||||
|
||||
if not response:
|
||||
_LOGGER.error("No waste data found!")
|
||||
return
|
||||
|
||||
waste_data_raw = []
|
||||
|
||||
for rows in response.strip().split("\n"):
|
||||
for ophaaldatum in rows.split(";")[1:-1]:
|
||||
temp = {"type": _waste_type_rename(rows.split(";")[0].strip().lower())}
|
||||
temp["date"] = datetime.strptime(ophaaldatum, "%d-%m-%Y").strftime(
|
||||
"%Y-%m-%d"
|
||||
)
|
||||
waste_data_raw.append(temp)
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
72
custom_components/afvalwijzer/collector/icalendar.py
Normal file
72
custom_components/afvalwijzer/collector/icalendar.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from datetime import datetime
|
||||
import re
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import _LOGGER, SENSOR_COLLECTORS_ICALENDAR
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
): # sourcery skip: avoid-builtin-shadow
|
||||
|
||||
if provider not in SENSOR_COLLECTORS_ICALENDAR.keys():
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
DATE_PATTERN = re.compile(r"^\d{8}")
|
||||
|
||||
try:
|
||||
url = SENSOR_COLLECTORS_ICALENDAR[provider].format(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
datetime.now().strftime("%Y-%m-%d"),
|
||||
)
|
||||
raw_response = requests.get(url)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
try:
|
||||
response = raw_response.text
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from exc
|
||||
|
||||
if not response:
|
||||
_LOGGER.error("No waste data found!")
|
||||
return
|
||||
|
||||
waste_data_raw = []
|
||||
date = None
|
||||
type = None
|
||||
|
||||
for line in response.splitlines():
|
||||
key, value = line.split(":", 2)
|
||||
field = key.split(";")[0]
|
||||
if field == "BEGIN" and value == "VEVENT":
|
||||
date = None
|
||||
type = None
|
||||
elif field == "SUMMARY":
|
||||
type = value.strip().lower()
|
||||
elif field == "DTSTART":
|
||||
if DATE_PATTERN.match(value):
|
||||
date = f"{value[:4]}-{value[4:6]}-{value[6:8]}"
|
||||
else:
|
||||
_LOGGER.debug(f"Unsupported date format: {value}")
|
||||
elif field == "END" and value == "VEVENT":
|
||||
if date and type:
|
||||
waste_data_raw.append({"type": type, "date": date})
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
f"No date or type extracted from event: date={date}, type={type}"
|
||||
)
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
122
custom_components/afvalwijzer/collector/main_collector.py
Normal file
122
custom_components/afvalwijzer/collector/main_collector.py
Normal file
@@ -0,0 +1,122 @@
|
||||
from ..common.waste_data_transformer import WasteDataTransformer
|
||||
from ..const.const import (
|
||||
_LOGGER,
|
||||
SENSOR_COLLECTORS_AFVALWIJZER,
|
||||
SENSOR_COLLECTORS_DEAFVALAPP,
|
||||
SENSOR_COLLECTORS_ICALENDAR,
|
||||
SENSOR_COLLECTORS_OPZET,
|
||||
SENSOR_COLLECTORS_RD4,
|
||||
SENSOR_COLLECTORS_XIMMIO,
|
||||
)
|
||||
|
||||
try:
|
||||
from . import deafvalapp, icalendar, mijnafvalwijzer, opzet, rd4, ximmio
|
||||
except ImportError as err:
|
||||
_LOGGER.error(f"Import error {err.args}")
|
||||
|
||||
|
||||
class MainCollector(object):
|
||||
def __init__(
|
||||
self,
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
exclude_pickup_today,
|
||||
exclude_list,
|
||||
default_label,
|
||||
):
|
||||
self.provider = provider.strip().lower()
|
||||
self.postal_code = postal_code.strip().upper()
|
||||
self.street_number = street_number.strip()
|
||||
self.suffix = suffix.strip().lower()
|
||||
self.exclude_pickup_today = exclude_pickup_today.strip()
|
||||
self.exclude_list = exclude_list.strip().lower()
|
||||
self.default_label = default_label.strip()
|
||||
|
||||
try:
|
||||
if provider in SENSOR_COLLECTORS_AFVALWIJZER:
|
||||
waste_data_raw = mijnafvalwijzer.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
elif provider in SENSOR_COLLECTORS_DEAFVALAPP.keys():
|
||||
waste_data_raw = deafvalapp.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
elif provider in SENSOR_COLLECTORS_ICALENDAR.keys():
|
||||
waste_data_raw = icalendar.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
elif provider in SENSOR_COLLECTORS_OPZET.keys():
|
||||
waste_data_raw = opzet.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
elif provider in SENSOR_COLLECTORS_RD4.keys():
|
||||
waste_data_raw = rd4.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
elif provider in SENSOR_COLLECTORS_XIMMIO.keys():
|
||||
waste_data_raw = ximmio.get_waste_data_raw(
|
||||
self.provider,
|
||||
self.postal_code,
|
||||
self.street_number,
|
||||
self.suffix,
|
||||
)
|
||||
else:
|
||||
_LOGGER.error(f"Unknown provider: {provider}")
|
||||
return False
|
||||
|
||||
except ValueError as err:
|
||||
_LOGGER.error(f"Check afvalwijzer platform settings {err.args}")
|
||||
|
||||
##########################################################################
|
||||
# COMMON CODE
|
||||
##########################################################################
|
||||
self._waste_data = WasteDataTransformer(
|
||||
waste_data_raw,
|
||||
self.exclude_pickup_today,
|
||||
self.exclude_list,
|
||||
self.default_label,
|
||||
)
|
||||
|
||||
##########################################################################
|
||||
# PROPERTIES FOR EXECUTION
|
||||
##########################################################################
|
||||
@property
|
||||
def waste_data_with_today(self):
|
||||
return self._waste_data.waste_data_with_today
|
||||
|
||||
@property
|
||||
def waste_data_without_today(self):
|
||||
return self._waste_data.waste_data_without_today
|
||||
|
||||
@property
|
||||
def waste_data_provider(self):
|
||||
return self._waste_data.waste_data_provider
|
||||
|
||||
@property
|
||||
def waste_types_provider(self):
|
||||
return self._waste_data.waste_types_provider
|
||||
|
||||
@property
|
||||
def waste_data_custom(self):
|
||||
return self._waste_data.waste_data_custom
|
||||
|
||||
@property
|
||||
def waste_types_custom(self):
|
||||
return self._waste_data.waste_types_custom
|
||||
58
custom_components/afvalwijzer/collector/mijnafvalwijzer.py
Normal file
58
custom_components/afvalwijzer/collector/mijnafvalwijzer.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import (
|
||||
_LOGGER,
|
||||
SENSOR_COLLECTOR_TO_URL,
|
||||
SENSOR_COLLECTORS_AFVALWIJZER,
|
||||
)
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
):
|
||||
if provider not in SENSOR_COLLECTORS_AFVALWIJZER:
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
if provider == "rova":
|
||||
provider = "inzamelkalender.rova"
|
||||
|
||||
try:
|
||||
url = SENSOR_COLLECTOR_TO_URL["afvalwijzer_data_default"][0].format(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
datetime.now().strftime("%Y-%m-%d"),
|
||||
)
|
||||
|
||||
raw_response = requests.get(url)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
try:
|
||||
response = raw_response.json()
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from e
|
||||
|
||||
if not response:
|
||||
_LOGGER.error("Address not found!")
|
||||
return
|
||||
|
||||
try:
|
||||
waste_data_raw = (
|
||||
response["ophaaldagen"]["data"] + response["ophaaldagenNext"]["data"]
|
||||
)
|
||||
except KeyError as exc:
|
||||
raise KeyError(f"Invalid and/or no data received from {url}") from exc
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
69
custom_components/afvalwijzer/collector/opzet.py
Normal file
69
custom_components/afvalwijzer/collector/opzet.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import _LOGGER, SENSOR_COLLECTORS_OPZET
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
):
|
||||
if provider not in SENSOR_COLLECTORS_OPZET.keys():
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
try:
|
||||
bag_id = None
|
||||
_verify = provider != "suez"
|
||||
url = f"{SENSOR_COLLECTORS_OPZET[provider]}/rest/adressen/{postal_code}-{street_number}"
|
||||
raw_response = requests.get(url, verify=_verify)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
try:
|
||||
response = raw_response.json()
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from e
|
||||
|
||||
if not response:
|
||||
_LOGGER.error("No waste data found!")
|
||||
return
|
||||
|
||||
try:
|
||||
if len(response) > 1 and suffix:
|
||||
for item in response:
|
||||
if (
|
||||
item["huisletter"] == suffix
|
||||
or item["huisnummerToevoeging"] == suffix
|
||||
):
|
||||
bag_id = item["bagId"]
|
||||
break
|
||||
else:
|
||||
bag_id = response[0]["bagId"]
|
||||
|
||||
url = f"{SENSOR_COLLECTORS_OPZET[provider]}/rest/adressen/{bag_id}/afvalstromen"
|
||||
waste_data_raw_temp = requests.get(url, verify=_verify).json()
|
||||
waste_data_raw = []
|
||||
|
||||
for item in waste_data_raw_temp:
|
||||
if not item["ophaaldatum"]:
|
||||
continue
|
||||
waste_type = item["menu_title"]
|
||||
if not waste_type:
|
||||
continue
|
||||
temp = {"type": _waste_type_rename(item["menu_title"].strip().lower())}
|
||||
temp["date"] = datetime.strptime(item["ophaaldatum"], "%Y-%m-%d").strftime(
|
||||
"%Y-%m-%d"
|
||||
)
|
||||
waste_data_raw.append(temp)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from exc
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
74
custom_components/afvalwijzer/collector/rd4.py
Normal file
74
custom_components/afvalwijzer/collector/rd4.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from datetime import datetime
|
||||
import re
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import _LOGGER, SENSOR_COLLECTORS_RD4
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
):
|
||||
if provider not in SENSOR_COLLECTORS_RD4.keys():
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
TODAY = datetime.now()
|
||||
YEAR_CURRENT = TODAY.year
|
||||
|
||||
corrected_postal_code_parts = re.search(r"(\d\d\d\d) ?([A-z][A-z])", postal_code)
|
||||
corrected_postal_code = (
|
||||
f"{corrected_postal_code_parts[1]}+{corrected_postal_code_parts[2].upper()}"
|
||||
)
|
||||
|
||||
try:
|
||||
url = SENSOR_COLLECTORS_RD4[provider].format(
|
||||
corrected_postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
YEAR_CURRENT,
|
||||
)
|
||||
raw_response = requests.get(url)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
try:
|
||||
response = raw_response.json()
|
||||
except ValueError as e:
|
||||
raise ValueError(f"Invalid and/or no data received from {url}") from e
|
||||
|
||||
if not response:
|
||||
_LOGGER.error("No waste data found!")
|
||||
return
|
||||
|
||||
if not response["success"]:
|
||||
_LOGGER.error("Address not found!")
|
||||
return
|
||||
|
||||
try:
|
||||
waste_data_raw_temp = response["data"]["items"][0]
|
||||
except KeyError as exc:
|
||||
raise KeyError(f"Invalid and/or no data received from {url}") from exc
|
||||
|
||||
waste_data_raw = []
|
||||
|
||||
for item in waste_data_raw_temp:
|
||||
if not item["date"]:
|
||||
continue
|
||||
|
||||
waste_type = item["type"]
|
||||
if not waste_type:
|
||||
continue
|
||||
|
||||
temp = {"type": _waste_type_rename(item["type"].strip().lower())}
|
||||
temp["date"] = datetime.strptime(item["date"], "%Y-%m-%d").strftime("%Y-%m-%d")
|
||||
waste_data_raw.append(temp)
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
83
custom_components/afvalwijzer/collector/ximmio.py
Normal file
83
custom_components/afvalwijzer/collector/ximmio.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import requests
|
||||
|
||||
from ..common.main_functions import _waste_type_rename
|
||||
from ..const.const import _LOGGER, SENSOR_COLLECTOR_TO_URL, SENSOR_COLLECTORS_XIMMIO
|
||||
|
||||
|
||||
def get_waste_data_raw(
|
||||
provider,
|
||||
postal_code,
|
||||
street_number,
|
||||
suffix,
|
||||
):
|
||||
if provider not in SENSOR_COLLECTORS_XIMMIO.keys():
|
||||
raise ValueError(f"Invalid provider: {provider}, please verify")
|
||||
|
||||
collectors = ("avalex", "meerlanden", "rad", "westland")
|
||||
provider_url = "ximmio02" if provider in collectors else "ximmio01"
|
||||
|
||||
TODAY = datetime.now().strftime("%d-%m-%Y")
|
||||
DATE_TODAY = datetime.strptime(TODAY, "%d-%m-%Y")
|
||||
DATE_TOMORROW = datetime.strptime(TODAY, "%d-%m-%Y") + timedelta(days=1)
|
||||
DATE_TODAY_NEXT_YEAR = (DATE_TODAY.date() + timedelta(days=365)).strftime(
|
||||
"%Y-%m-%d"
|
||||
)
|
||||
|
||||
##########################################################################
|
||||
# First request: get uniqueId and community
|
||||
##########################################################################
|
||||
try:
|
||||
url = SENSOR_COLLECTOR_TO_URL[provider_url][0]
|
||||
companyCode = SENSOR_COLLECTORS_XIMMIO[provider]
|
||||
data = {
|
||||
"postCode": postal_code,
|
||||
"houseNumber": street_number,
|
||||
"companyCode": companyCode,
|
||||
}
|
||||
raw_response = requests.post(url=url, data=data)
|
||||
uniqueId = raw_response.json()["dataList"][0]["UniqueId"]
|
||||
community = raw_response.json()["dataList"][0]["Community"]
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
##########################################################################
|
||||
# Second request: get the dates
|
||||
##########################################################################
|
||||
try:
|
||||
url = SENSOR_COLLECTOR_TO_URL[provider_url][1]
|
||||
data = {
|
||||
"companyCode": companyCode,
|
||||
"startDate": DATE_TODAY.date(),
|
||||
"endDate": DATE_TODAY_NEXT_YEAR,
|
||||
"community": community,
|
||||
"uniqueAddressID": uniqueId,
|
||||
}
|
||||
raw_response = requests.post(url=url, data=data).json()
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise ValueError(err) from err
|
||||
|
||||
if not raw_response:
|
||||
_LOGGER.error("Address not found!")
|
||||
return
|
||||
|
||||
try:
|
||||
response = raw_response["dataList"]
|
||||
except KeyError as e:
|
||||
raise KeyError(f"Invalid and/or no data received from {url}") from e
|
||||
|
||||
waste_data_raw = []
|
||||
|
||||
for item in response:
|
||||
temp = {"type": _waste_type_rename(item["_pickupTypeText"].strip().lower())}
|
||||
temp["date"] = datetime.strptime(
|
||||
sorted(item["pickupDates"])[0], "%Y-%m-%dT%H:%M:%S"
|
||||
).strftime("%Y-%m-%d")
|
||||
waste_data_raw.append(temp)
|
||||
|
||||
return waste_data_raw
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Yell something at a mountain!")
|
||||
Reference in New Issue
Block a user