add awg_de

This commit is contained in:
5ila5
2024-08-20 23:01:38 +02:00
committed by 5ila5
parent 746e3d7901
commit 54f98b8bc4
5 changed files with 203 additions and 1 deletions

View File

@@ -1150,6 +1150,7 @@ If your service provider is not listed, feel free to open a [source request issu
- [Würzburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: wuerzburg
- [ZAH Hildesheim](/doc/ics/zah_hildesheim_de.md) / zah-hildesheim.de
- [ZAK Kempten](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappzak
- [ZAW Donau-Wald](/doc/source/awg_de.md) / awg.de
- [ZAW-SR](/doc/source/app_abfallplus_de.md) / Abfall+ App: zawsr
- [ZEW Zweckverband Entsorgungsregion West](/doc/source/abfallnavi_de.md) / zew-entsorgung.de
- [ZfA Iserlohn](/doc/ics/zfa_iserlohn_de.md) / zfa-iserlohn.de

View File

@@ -6420,6 +6420,11 @@
"app_id": "de.k4systems.abfallappzak"
}
},
{
"title": "ZAW Donau-Wald",
"module": "awg_de",
"default_params": {}
},
{
"title": "ZAW-SR",
"module": "app_abfallplus_de",

View File

@@ -0,0 +1,138 @@
# This is a nearly 1:1 copy of the original file waste_collection_schedule/waste_collection_schedule/source/meinawb_de.py
import html
import logging
import random
import re
import string
import requests
from waste_collection_schedule import Collection
from waste_collection_schedule.service.ICS import ICS
_LOGGER = logging.getLogger(__name__)
TITLE = "ZAW Donau-Wald"
DESCRIPTION = "Source for ZAW Donau-Wald."
URL = "https://www.awg.de/"
TEST_CASES = {
"Achslach Aign 1 ": {"city": "Achslach", "street": "Aign", "hnr": "1"},
"Böbrach Bärnerauweg 10A": {
"city": "Böbrach",
"street": "Bärnerauweg",
"hnr": 10,
"addition": "A",
},
"Am Bäckergütl 1, 94094 Malching": {
"city": "Malching",
"street": "Am Bäckergütl",
"hnr": 1,
"addition": "",
},
}
ICON_MAP = {
"Biotonne": "mdi:leaf",
"Papiertonne": "mdi:package-variant",
"Restmuelltonne": "mdi:trash-can",
"Restmüllcontainer": "mdi:trash-can",
"Papiercontainer": "mdi:package-variant",
}
API_URL = (
"https://wastemanagement.awg.de/WasteManagementDonauwald/WasteManagementServlet"
)
class Source:
def __init__(self, city, street, hnr, addition=""):
self._city = city
self._street = street
self._house_number = hnr
self._address_suffix = addition
self._boundary = "WebKitFormBoundary" + "".join(
random.sample(string.ascii_letters + string.digits, 16)
)
self._ics = ICS()
def __str__(self):
return (
f"{self._city} {self._street} {self._house_number} {self._address_suffix}"
)
@staticmethod
def _parse_data(data, boundary):
result = ""
for key, value in data.items():
result += f'------{boundary}\r\nContent-Disposition: form-data; name="{key}"\r\n\r\n{value}\r\n'
result += f"------{boundary}--\r\n"
return result.encode()
@staticmethod
def _parse_response_input(text):
parsed = re.findall(
'<INPUT\\sNAME="([^"]+?)"\\sID="[^"]+?"(?:\\sVALUE="([^"]*?)")?', text
)
return {k: v for k, v in parsed}
def _address(self):
return {
"Ort": self._city,
"Strasse": self._street,
"Hausnummer": self._house_number,
"Hausnummerzusatz": self._address_suffix,
}
def _headers(self):
return {"Content-Type": f"multipart/form-data; boundary=----{self._boundary}"}
def _payload(self, last_request, action="", period="", **kwargs):
payload = self._parse_response_input(last_request)
payload.update({"SubmitAction": action, **kwargs})
if period:
payload.update({"Zeitraum": html.unescape(period)})
return self._parse_data(payload, self._boundary)
def _get_dates(self, session, init_request, calendar=""):
kwargs = {"Ort": self._city, "Strasse": ""}
payload = self._payload(
init_request, action="CITYCHANGED", period=calendar, **kwargs
)
city_response = session.post(API_URL, headers=self._headers(), data=payload)
payload = self._payload(
city_response.text, action="forward", period=calendar, **self._address()
)
final_response = session.post(API_URL, headers=self._headers(), data=payload)
payload = self._payload(
final_response.text,
action="filedownload_ICAL",
period=calendar,
**self._address(),
)
ics_response = session.post(API_URL, headers=self._headers(), data=payload)
return self._ics.convert(ics_response.text)
def fetch(self):
session = requests.Session()
init_request = session.get(
f"{API_URL}?SubmitAction=wasteDisposalServices&InFrameMode=true"
).text
if calendars := re.findall('NAME="Zeitraum" VALUE="([^"]+?)"', init_request):
dates = [
date
for calendar in calendars
for date in self._get_dates(session, init_request, calendar)
]
else:
dates = self._get_dates(session, init_request)
entries = []
for date, bin_type in dates:
entries.append(
Collection(date, bin_type.strip(), ICON_MAP.get(bin_type.strip()))
)
return entries

58
doc/source/awg_de.md Normal file
View File

@@ -0,0 +1,58 @@
# ZAW Donau-Wald
Support for schedules provided by [ZAW Donau-Wald](https://www.awg.de/), serving Regen, Deggendorf, Freyung-Grafenau, Passau, Germany.
## Configuration via configuration.yaml
```yaml
waste_collection_schedule:
sources:
- name: awg_de
args:
city: CITY (Ort)
street: STREET (Straße)
hnr: "HOUSE NUMBER (Hausnummer)"
addition: ADDITION (Hausnummerzusatz)
```
### Configuration Variables
**city**
*(String) (required)*
**street**
*(String) (required)*
**hnr**
*(String) (required)*
**addition**
*(String) (optional)*
## Example
```yaml
waste_collection_schedule:
sources:
- name: awg_de
args:
city: Achslach
street: Aign
hnr: "1"
```
```yaml
waste_collection_schedule:
sources:
- name: awg_de
args:
city: Böbrach
street: Bärnerauweg
hnr: 10
addition: "A"
```
## How to get the source argument
Find the parameter of your address using [https://www.awg.de/abfallentsorgung/abfuhrkalender](https://www.awg.de/abfallentsorgung/abfuhrkalender) and write them exactly like on the web page.

File diff suppressed because one or more lines are too long