Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add avfallsor.no, Kristiansand #3288

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,7 @@ If your service provider is not listed, feel free to open a [source request issu
<details>
<summary>Norway</summary>

- [Avfall Sør, Kristiansand](/doc/source/avfallsor_no.md) / avfallsor.no
- [BIR (Bergensområdets Interkommunale Renovasjonsselskap)](/doc/source/bir_no.md) / bir.no
- [Fosen Renovasjon](/doc/source/fosenrenovasjon_no.md) / fosenrenovasjon.no
- [IRiS](/doc/source/iris_salten_no.md) / iris-salten.no
Expand Down
6 changes: 6 additions & 0 deletions custom_components/waste_collection_schedule/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -11841,6 +11841,12 @@
}
],
"Norway": [
{
"title": "Avfall S\u00f8r, Kristiansand",
"module": "avfallsor_no",
"default_params": {},
"id": "avfallsor_no"
},
{
"title": "BIR (Bergensomr\u00e5dets Interkommunale Renovasjonsselskap)",
"module": "bir_no",
Expand Down
20 changes: 20 additions & 0 deletions custom_components/waste_collection_schedule/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -10331,6 +10331,26 @@
},
"data_description": {}
},
"args_avfallsor_no": {
"title": "Quelle konfigurieren",
"description": "Konfiguriere deinen Service Provider. Mehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md",
"data": {
"calendar_title": "Kalender Titel",
"address": "Addresse"
},
"data_description": {
"calendar_title": "Ein lesbarerer oder benutzerfreundlicherer Name für den Müllkalender. Wenn nichts angegeben wird, wird der Name der Quelle verwendet."
}
},
"reconfigure_avfallsor_no": {
"title": "Quelle Neu Konfigurieren",
"description": "Konfiguriere deinen Service Provider. Mehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md",
"data": {
"calendar_title": "Kalender Titel",
"address": "Addresse"
},
"data_description": {}
},
"args_bir_no": {
"title": "Quelle konfigurieren",
"description": "Konfiguriere deinen Service Provider. Mehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/bir_no.md",
Expand Down
20 changes: 20 additions & 0 deletions custom_components/waste_collection_schedule/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10343,6 +10343,26 @@
},
"data_description": {}
},
"args_avfallsor_no": {
"title": "Configure Source",
"description": "Configure your service provider. More details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md.",
"data": {
"calendar_title": "Calendar Title",
"address": "Address"
},
"data_description": {
"calendar_title": "A more readable, or user-friendly, name for the waste calendar. If nothing is provided, the name returned by the source will be used."
}
},
"reconfigure_avfallsor_no": {
"title": "Reconfigure Source",
"description": "Configure your service provider. More details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md.",
"data": {
"calendar_title": "Calendar Title",
"address": "Address"
},
"data_description": {}
},
"args_bir_no": {
"title": "Configure Source",
"description": "Configure your service provider. More details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/bir_no.md.",
Expand Down
20 changes: 20 additions & 0 deletions custom_components/waste_collection_schedule/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -10313,6 +10313,26 @@
},
"data_description": {}
},
"args_avfallsor_no": {
"title": "Configurazione Sorgente",
"description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. Maggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md.",
"data": {
"calendar_title": "Nome Calendario",
"address": "Address"
},
"data_description": {
"calendar_title": "Puoi cambiare il nome del calendario della raccolta dei rifiuti, altrimenti di default verra' utilizzato il nome del tuo fornitore di servizi."
}
},
"reconfigure_avfallsor_no": {
"title": "Riconfigurazione Sorgente",
"description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. Per maggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/avfallsor_no.md.",
"data": {
"calendar_title": "Nome Calendario",
"address": "Address"
},
"data_description": {}
},
"args_bir_no": {
"title": "Configurazione Sorgente",
"description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. Maggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/bir_no.md.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import datetime
import logging

import requests
from bs4 import BeautifulSoup, Tag
from waste_collection_schedule import Collection # type: ignore[attr-defined]
from waste_collection_schedule.exceptions import SourceArgumentNotFoundWithSuggestions

TITLE = "Avfall Sør, Kristiansand"
DESCRIPTION = "Source for Avfall Sør, Kristiansand."
URL = "https://avfallsor.no/"
TEST_CASES = {"Auglandslia 1, Kristiansand": {"address": "Auglandslia 1, Kristiansand"}}
_LOGGER = logging.getLogger(__name__)

ICON_MAP = {
"Restavfall": "mdi:trash-can",
"Bioavfall": "mdi:leaf",
"Papp og papir": "mdi:package-variant",
"Plastemballasje": "mdi:recycle",
"Glass- og metallemballasje": "mdi:bottle-soda",
}


API_URL = "https://avfallsor.no/wp-json/addresses/v1/address"


NO_WEEKDAYS = ["mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag", "søndag"]
NO_MONTHS = [
"januar",
"februar",
"mars",
"april",
"mai",
"juni",
"juli",
"august",
"september",
"oktober",
"november",
"desember",
]


def parse_date(date_str: str) -> datetime.date:
date_str = date_str.lower()
for weekday in NO_WEEKDAYS:
date_str = date_str.replace(weekday, "")

month_number = None
for i, month in enumerate(NO_MONTHS):
if month in date_str:
month_number = i + 1
date_str = date_str.replace(month, "")
break
if month_number is None:
raise ValueError("Could not find month in date string %s" % date_str)

date_str = date_str.replace(".", "").strip()
try:
day = int(date_str)
except ValueError:
raise ValueError("Day is not an integer: %s" % date_str)

date_ = datetime.date(datetime.datetime.now().year, month_number, day)
if datetime.date.today() > date_:
return date_.replace(year=datetime.datetime.now().year + 1)

return date_


class Source:
def __init__(self, address: str):
self._address: str = address

def fetch(self) -> list[Collection]:
args = {"address": self._address.split(",")[0].strip()}

r = requests.get(API_URL, params=args)
r.raise_for_status()
matches = r.json()
href: str | None = None

for match in matches:
if (
match["label"]
.lower()
.replace(" ", "")
.replace(",", "")
.replace(".", "")
.casefold()
== self._address.lower()
.replace(" ", "")
.replace(",", "")
.replace(".", "")
.casefold()
):
href = match["href"]
break

if not href:
raise SourceArgumentNotFoundWithSuggestions(
"address",
self._address,
[match["label"] for match in matches],
)
r = requests.get(href)
r.raise_for_status()

soup = BeautifulSoup(r.text, "html.parser")
pickup_div = (
soup.select_one("div.pickup-days-large")
or soup.select_one("div.pickup-days-small")
or soup.select_one("div.pickup-days")
)
if not pickup_div:
raise ValueError("Could not find pickup days")

entries = []
for h3 in soup.select("h3"):
date_ = parse_date(h3.text)
div = h3.find_next_sibling("div")

if not div or not isinstance(div, Tag):
_LOGGER.warning("Could not find div for %s", h3.text)
continue

for text_div in div.select("div.info-boxes-box-info"):
for span in text_div.select("span"):
span.decompose()
bin_type = text_div.text.strip()

icon = ICON_MAP.get(bin_type) # Collection icon
entries.append(Collection(date=date_, t=bin_type, icon=icon))

return entries
33 changes: 33 additions & 0 deletions doc/source/avfallsor_no.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Avfall Sør, Kristiansand

Support for schedules provided by [Avfall Sør, Kristiansand](https://avfallsor.no/), serving Kristiansand, Norway.

## Configuration via configuration.yaml

```yaml
waste_collection_schedule:
sources:
- name: avfallsor_no
args:
address: ADDRESS
```

### Configuration Variables

**address**
*(String) (required)*

## Example

```yaml
waste_collection_schedule:
sources:
- name: avfallsor_no
args:
address: Auglandslia 1, Kristiansand

```

## How to get the source argument

Visit [https://avfallsor.no/henting-av-avfall/finn-hentedag/](https://avfallsor.no/henting-av-avfall/finn-hentedag/) and write the address exactly like suggested by the input field.
2 changes: 1 addition & 1 deletion info.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Waste collection schedules from service provider web sites are updated daily, de
| Malta | Malta |
| Netherlands | 's-Hertogenbosch, ACV Group, Afval Wijzer, Afvalstoffendienst.nl, Alpen an den Rijn, Altena, Area Afval, Avalex, Avri, Bar Afvalbeheer, Bernheze, Circulus, Cyclus NV, Dar, Den Haag, Edam-Volendam, GAD, Gemeente Almere, Gemeente Berkelland, Gemeente Cranendonck, Gemeente Hellendoorn, Gemeente Lingewaard, Gemeente Meppel, Gemeente Middelburg + Vlissingen, Gemeente Peel en Maas, Gemeente Schouwen-Duiveland, Gemeente Sudwest-Fryslan, Gemeente Venray, Gemeente Voorschoten, Gemeente Waalre, Gemeente Westland, Goes, Heusden, HVC Groep, Meerlanden, Mijn Blink, Oisterwijk, PreZero, Purmerend, RAD BV, Rd4, Reinis, Spaarnelanden, Twente Milieu, Vught, Waardlanden, Ximmio, ZRD, Ôffalkalinder van Noardeast-Fryslân & Dantumadiel |
| New Zealand | Auckland Council, Christchurch City Council, Dunedin District Council, Gore, Invercargill & Southland, Hamilton City Council, Horowhenua District Council, Hutt City Council, Napier City Council, Porirua City, Rotorua Lakes Council, Tauranga City Council, Waipa District Council, Wellington City Council |
| Norway | BIR (Bergensområdets Interkommunale Renovasjonsselskap), Fosen Renovasjon, IRiS, Min Renovasjon, Movar IKS, Oslo Kommune, ReMidt Orkland muni, Sandnes Kommune, Stavanger Kommune, Trondheim |
| Norway | Avfall Sør, Kristiansand, BIR (Bergensområdets Interkommunale Renovasjonsselskap), Fosen Renovasjon, IRiS, Min Renovasjon, Movar IKS, Oslo Kommune, ReMidt Orkland muni, Sandnes Kommune, Stavanger Kommune, Trondheim |
| Poland | App Moje Odpady, Bydgoszcz Pronatura, Czerwonak, Murowana Goślina, Oborniki, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, MPGK Katowice, Poznań, Warsaw, Wrocław |
| Slovakia | fcc Environment |
| Slovenia | Moji odpadki, Ljubljana, Snaga Maribor |
Expand Down
Loading