Make use of new Renosyd (DK) API and update devcontainer (#1812)

* Update `devcontainer` to latest structure and images

Current source has deprecation message, and simply did not work

* Adapt `renosyd_dk` to new API

* Remove storskrald

It's now sourced on a different endpoint. It's also a service that is ordered, so may make little sense to keep on a schedule.

* reformatting

* allow integer house_number

---------

Co-authored-by: 5ila5 <5ila5@users.noreply.github.com>
This commit is contained in:
Carl Reid
2024-02-21 18:13:41 +01:00
committed by GitHub
parent 361cb4ec19
commit 0dc13c3522
3 changed files with 68 additions and 139 deletions

View File

@@ -1,15 +1,18 @@
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
{
"name": "Waste Collection Schedule development",
"image": "ghcr.io/ludeeus/devcontainer/integration:stable",
"context": "..",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"appPort": [
"9123:8123"
],
"containerEnv": {
"TZ": "Europe/Berlin" // Set your local timezone here
},
"postCreateCommand": "container install",
"features": {
"ghcr.io/devcontainers/features/python:1": {}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"github.vscode-pull-request-github",
@@ -31,3 +34,5 @@
"files.trimTrailingWhitespace": true
}
}
}
}

View File

@@ -1,134 +1,59 @@
import requests, re, time, datetime
from bs4 import BeautifulSoup, NavigableString
from dateutil import parser
from waste_collection_schedule import Collection # type: ignore[attr-defined]
from datetime import datetime
from typing import List
import requests
from waste_collection_schedule import Collection # type: ignore[attr-defined]
TITLE = "Renosyd"
DESCRIPTION = "Renosyd collections for Skanderborg and Odder kommunes"
URL = "https://renosyd.dk"
TEST_CASES = {
"TestCase1": {
"kommune": "skanderborg",
"husnummer": 123000,
"house_number": "013000",
},
"TestCase2": {
"kommune": "skanderborg",
"husnummer": 186305,
"house_number": "012000",
},
"TestCase3": {
"kommune": "odder",
"husnummer": 89042,
"house_number": 11000,
},
}
ICON_MAP = {
"RESTAFFALD": "mdi:trash-can",
"PAPIR/PAP": "mdi:note-multiple",
"PAPIR": "mdi:newspaper",
"PAP": "mdi:archive",
"EMBALLAGE": "mdi:recycle",
"STORSKRALD": "mdi:dump-truck",
"HAVEAFFALD": "mdi:leaf", # Uncertain about this name, can't find an example
"GLAS": "mdi:bottle-wine",
"METAL": "mdi:wrench",
"HÅRD PLAST": "mdi:bottle-soda-classic",
}
DANISH_MONTHS = [
None,
"jan",
"feb",
"mar",
"apr",
"maj",
"jun",
"jul",
"aug",
"sep",
"okt",
"nov",
"dec",
]
class Source:
def __init__(self, kommune: str, husnummer: int):
self._kommune = kommune
self._husnummer = husnummer
self._api_url = (
"https://"
+ self._kommune.lower()
+ ".netdialog.renosyd.dk/citizen/default.aspx"
)
def __init__(self, house_number: str | int):
house_number = str(house_number).zfill(6)
self._api_url = f"https://skoda-selvbetjeningsapi.renosyd.dk/api/v1/toemmekalender?nummer={house_number}"
def fetch(self) -> List[Collection]:
session = requests.Session()
session.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
}
address_select = session.get(
self._api_url,
cookies={"StoredAddress": str(self._husnummer)},
)
address_select.raise_for_status()
address_select_soup = BeautifulSoup(address_select.text, "html.parser")
data = {
i["name"]: i.get("value", "")
for i in address_select_soup.select("input[name]")
}
binfo = session.post(self._api_url, data=data)
binfo.raise_for_status()
binfo_soup = BeautifulSoup(binfo.text, "html.parser")
calendar = binfo_soup.find_all(attrs={"class": "tableContainersAtProperty"})
months = []
this_year = time.localtime().tm_year
for month in calendar[1].find_all("th"):
value = month.contents[0].strip()
if value == "Beholder":
continue
months.append(datetime.date(this_year, DANISH_MONTHS.index(value), 1))
if value == "dec":
this_year += 1
response = requests.get(self._api_url)
response.raise_for_status()
data = response.json()
entries = []
rows = calendar[1].find_all("tr")
for row in rows[1:]:
elements = row.find_all("td")
result = re.search(
r"^(\d{1,2}\s?x\s?)([A-Za-z\/]*)(\s*\d{1,4}\s?L)?$",
elements[0].contents[0].strip(),
)
if result is None:
continue
container_type = result.groups()[1]
for idx, element in enumerate(elements[1:]):
for subelement in element.contents:
if not isinstance(subelement, NavigableString):
continue
if subelement.strip() == "":
continue
for item in data:
for toemning in item.get("planlagtetømninger", []):
date = datetime.strptime(toemning["dato"], "%Y-%m-%dT%H:%M:%SZ").date()
for fraktion in toemning["fraktioner"]:
entries.append(
Collection(
date=months[idx]
+ datetime.timedelta(days=int(subelement.strip()) - 1),
t=container_type,
icon=ICON_MAP.get(container_type.upper()),
date=date,
t=fraktion,
icon=ICON_MAP.get(
fraktion.upper(), "mdi:trash-can-outline"
),
)
)
return entries

View File

@@ -9,19 +9,15 @@ waste_collection_schedule:
sources:
- name: renosyd_dk
args:
kommune: "odder" OR "skanderborg"
husnummer: See description
house_number: See description
```
### Configuration Variables
**kommune**
**house_number**
*(String) (required)*
**husnummer**
*(Int) (required)*
## Example
```yaml
@@ -29,16 +25,20 @@ waste_collection_schedule:
sources:
- name: renosyd_dk
args:
kommune: skanderborg
husnummer: 123000
house_number: "023000"
```
## How to get the house number / husnummer
Go to the page for either [Odder](https://odder.netdialog.renosyd.dk/citizen/) or [Skanderborg](https://skanderborg.netdialog.renosyd.dk/citizen/). Select your street and then house/apartment number. Select "husk min adresse", and then select "Næste...".
Go to the [Mit renosyd](https://mit.renosyd.dk/toemmekalender) page, enter your address and click "Gem".
Now the house number is saved as a cookie. Open developer tools (right-click-> inspect in Firefox/Chrome), and look at the cookies (in Storage in Firefox, Application->Storage->Cookies in Chrome). There should be a single cookie storing a "StoredAddress" value - the house id number - and a session id which you can ignore.
Your house number is saved in Local Storage. To get this, you can:
1) Open Developer Console
- Chrome / Microsoft Edge: `CTRL + SHIFT + J` or `Cmd + Option + J`
- Firefox: `CTRL + SHIFT + K` or `Cmd + Option + K`
- Safari: `CMD + OPTION + C`
2) Paste the following and press `enter`, which will output the number you need: `JSON.parse(localStorage.getItem('bookmarkedCollectionSites'))[0].standpladsNummer`
### Filtering Example
@@ -49,8 +49,7 @@ waste_collection_schedule:
sources:
- name: renosyd_dk
args:
kommune: skanderborg
husnummer: 123001
house_number: 123001
customize:
- type: Storskrald
show: false