Skip to content

Commit

Permalink
Merge pull request #142 from rikroe/wuerzburg
Browse files Browse the repository at this point in the history
Add wuerzburg_de
  • Loading branch information
mampfes authored Jan 16, 2022
2 parents 844f877 + 4059668 commit ef645c7
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Currently the following service providers are supported:

- [Abfall.IO / AbfallPlus.de](./doc/source/abfall_io.md)
- [AbfallNavi.de (RegioIT.de)](./doc/source/abfallnavi_de.md)
- [Abfallkalender Würzburg](./doc/source/wuerzburg_de.md)
- [Abfallwirtschaft Rendsburg](./doc/source/awr_de.md)
- [Abfallwirtschaft Stuttgart](./doc/source/stuttgart_de.md)
- [Abfallwirtschaft Südholstein](./doc/source/awsh_de.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import datetime

import requests
from bs4 import BeautifulSoup
from waste_collection_schedule import Collection # type: ignore[attr-defined]

TITLE = "Abfallkalender Würzburg"
DESCRIPTION = "Source for waste collection in the city of Würzburg, Germany."
URL = "https://www.wuerzburg.de/themen/umwelt-verkehr/vorsorge-entsorgung/abfallkalender/32208.Abfallkalender.html"
TEST_CASES = {
"District only": {"district": "Altstadt"},
"Street only": {"street": "Juliuspromenade"},
"District + Street": {"district": "Altstadt", "street": "Juliuspromenade"},
"District + Street diff": {"district": "Altstadt", "street": "Oberer Burgweg"},
}


class Source:
def __init__(self, district: str = None, street: str = None):
self._district = district
self._street = street
self._district_id = None

@staticmethod
def map_district_id(district: str = None, street: str = None):
"""Map `street` or `district` to `district_id`, giving priority to `street`.
Parameters must exactly be the same as visible in dropdowns on `URL`.
"""
if not district and not street:
raise ValueError("One of ['district', 'street'] is required.")

r = requests.get(URL)
r.raise_for_status()
selects = BeautifulSoup(r.content, "html.parser").body.find_all("select")

if street:
strlist = next(iter([s for s in selects if s["id"] == "strlist"]))
strdict = {option.text: option["value"] for option in strlist}

try:
return strdict[street]
except KeyError:
raise KeyError(
f"Unable to find street '{street}'. Please compare exact typing with {URL}"
)

if district:
reglist = next(iter([s for s in selects if s["id"] == "reglist"]))
regdict = {
option.text: option.attrs["value"] for option in reglist.contents
}

try:
return regdict[district]
except KeyError:
raise KeyError(
f"Unable to find district '{district}'. Please compare exact typing with {URL}"
)

def fetch(self):
# Get & parse full HTML only on first call to fetch() to map district or street to district_id
if not self._district_id:
self._district_id = self.map_district_id(self._district, self._street)

if not self._district_id:
raise ValueError("'_district_id' is not set!")

now = datetime.datetime.now().date()

r = requests.get(
URL,
params={
"_func": "evList",
"_mod": "events",
"ev[start]": str(now),
"ev[end]": str(now + datetime.timedelta(days=365)),
"ev[addr]": self._district_id,
},
)
r.raise_for_status()

entries = []
for event in r.json()["contents"].values():
entries.append(
Collection(
datetime.datetime.fromisoformat(event["start"]).date(),
event["title"],
picture=event.get("thumb", {}).get("url"),
)
)

return entries
49 changes: 49 additions & 0 deletions doc/source/wuerzburg_de.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# WasteNet Southland

Support for schedules provided by [Abfallkalender Würzburg](https://www.wuerzburg.de/themen/umwelt-verkehr/vorsorge-entsorgung/abfallkalender/32208.Abfallkalender.html), serving the City of Würzburg.

## Configuration via configuration.yaml

```yaml
waste_collection_schedule:
sources:
- name: wuerzburg_de
args:
district: ADDRESS
street: STREET
```
### Configuration Variables
**district** and **street** can be used independently, only **one** is required. If set, priority will be given to **street**.
**district**<br>
*(string) (required)* - if *street* is empty
**street**<br>
*(string) (required)* - if *district* is empty
## Example
Both examples will yield the same result.
```yaml
waste_collection_schedule:
sources:
- name: wuerzburg_de
args:
district: "Altstadt"
```
```yaml
waste_collection_schedule:
sources:
- name: wuerzburg_de
args:
street: "Juliuspromenade"
```
## How to get the source argument
The source argument is either district or street as displayed in the web form at [Abfallkalender Würzburg](https://www.wuerzburg.de/themen/umwelt-verkehr/vorsorge-entsorgung/abfallkalender/32208.Abfallkalender.html). Exact match is required.
1 change: 1 addition & 0 deletions info.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Currently the following service providers are supported:

- [Abfall.IO / AbfallPlus.de](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/abfall_io.md)
- [AbfallNavi.de (RegioIT.de)](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/abfallnavi_de.md)
- [Abfallkalender Würzburg](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/wuerzburg_de.md)
- [Abfallwirtschaft Rendsburg](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/awr_de.md)
- [Abfallwirtschaft Stuttgart](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/stuttgart_de.md)
- [Abfallwirtschaft Südholstein](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/awsh_de.md)
Expand Down

0 comments on commit ef645c7

Please sign in to comment.