remove all carrier returns + 1 typo

This commit is contained in:
5ila5
2023-12-26 13:55:29 +01:00
committed by 5ila5
parent 897d8cb693
commit ca521c42ff
6 changed files with 360 additions and 360 deletions

View File

@@ -1,82 +1,82 @@
import datetime import datetime
import requests import requests
from lxml import etree from lxml import etree
from waste_collection_schedule import Collection # type: ignore[attr-defined] from waste_collection_schedule import Collection # type: ignore[attr-defined]
TITLE = "BIR (Bergensområdets Interkommunale Renovasjonsselskap)" TITLE = "BIR (Bergensområdets Interkommunale Renovasjonsselskap)"
DESCRIPTION = "Askøy, Bergen, Bjørnafjorden, Eidfjord, Kvam, Osterøy, Samnanger, Ulvik, Vaksdal, Øygarden og Voss Kommune (Norway)." DESCRIPTION = "Askøy, Bergen, Bjørnafjorden, Eidfjord, Kvam, Osterøy, Samnanger, Ulvik, Vaksdal, Øygarden og Voss Kommune (Norway)."
URL = "https://bir.no" URL = "https://bir.no"
TEST_CASES = { TEST_CASES = {
"Villa Paradiso": { "Villa Paradiso": {
"street_name": "Nordåsgrenda", "street_name": "Nordåsgrenda",
"house_number": 7, "house_number": 7,
"house_letter": "", "house_letter": "",
}, },
"Mardalsrenen 12 B": { "Mardalsrenen 12 B": {
"street_name": "Mardalsrenen", "street_name": "Mardalsrenen",
"house_number": "11", "house_number": "11",
}, },
"Alf Bondes Veg 13 B": { "Alf Bondes Veg 13 B": {
"street_name": "Alf Bondes Veg", "street_name": "Alf Bondes Veg",
"house_number": "13", "house_number": "13",
"house_letter": "B", "house_letter": "B",
}, },
} }
API_URL = "https://bir.no/api/search/AddressSearch" API_URL = "https://bir.no/api/search/AddressSearch"
ICON_MAP = {"restavfall": "mdi:trash-can", "papir": "mdi:newspaper-variant-multiple"} ICON_MAP = {"restavfall": "mdi:trash-can", "papir": "mdi:newspaper-variant-multiple"}
def map_icon(text): def map_icon(text):
for key, value in ICON_MAP.items(): for key, value in ICON_MAP.items():
if key in text: if key in text:
return value return value
return "mdi:trash-can" return "mdi:trash-can"
class Source: class Source:
def __init__(self, street_name, house_number, house_letter=""): def __init__(self, street_name, house_number, house_letter=""):
self._street_name = street_name self._street_name = street_name
self._house_number = house_number self._house_number = house_number
self._house_letter = house_letter self._house_letter = house_letter
def fetch(self): def fetch(self):
headers = {"user-agent": "Home-Assitant-waste-col-sched/0.1"} headers = {"user-agent": "Home-Assitant-waste-col-sched/0.1"}
args = { args = {
"q": f"{self._street_name} {self._house_number}{self._house_letter} ", # The space at the end is serving as a termination character for the query "q": f"{self._street_name} {self._house_number}{self._house_letter} ", # The space at the end is serving as a termination character for the query
"s": False, "s": False,
} }
r = requests.get(API_URL, params=args, headers=headers) r = requests.get(API_URL, params=args, headers=headers)
r = requests.get( r = requests.get(
f"{URL}/adressesoek/toemmekalender", f"{URL}/adressesoek/toemmekalender",
params={"rId": {r.json()[0]["Id"]}}, params={"rId": {r.json()[0]["Id"]}},
headers=headers, headers=headers,
) )
doc = etree.HTML(r.content) doc = etree.HTML(r.content)
month_containers = doc.cssselect( month_containers = doc.cssselect(
".main-content .address-page-box .month-container" ".main-content .address-page-box .month-container"
) )
return [ return [
Collection( Collection(
date=datetime.datetime.strptime( date=datetime.datetime.strptime(
f"{date.text.replace('des','dec').replace('mai','may').replace('okt','oct')} {container.cssselect('.month-title')[0].text.strip().split(' ')[1]}", f"{date.text.replace('des','dec').replace('mai','may').replace('okt','oct')} {container.cssselect('.month-title')[0].text.strip().split(' ')[1]}",
"%d. %b %Y", "%d. %b %Y",
).date(), ).date(),
t=doc.cssselect( t=doc.cssselect(
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text' f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
)[0].text, )[0].text,
icon=map_icon( icon=map_icon(
doc.cssselect( doc.cssselect(
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text' f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
)[0].text.lower() )[0].text.lower()
), ),
) )
for container in month_containers for container in month_containers
for category_row in container.cssselect(".category-row") for category_row in container.cssselect(".category-row")
for date in category_row.cssselect(".date-item > .date-item-date") for date in category_row.cssselect(".date-item > .date-item-date")
] ]

View File

@@ -1,92 +1,92 @@
import datetime import datetime
import json import json
import re import re
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from waste_collection_schedule import Collection # type: ignore[attr-defined] from waste_collection_schedule import Collection # type: ignore[attr-defined]
TITLE = "Cederbaum Braunschweig" TITLE = "Cederbaum Braunschweig"
DESCRIPTION = "Cederbaum Braunschweig Paperimüll" DESCRIPTION = "Cederbaum Braunschweig Paperimüll"
URL = "https://www.cederbaum.de" URL = "https://www.cederbaum.de"
TEST_CASES = { TEST_CASES = {
"Hans-Sommer-Str": {"street": "Hans-Sommer-Str."}, "Hans-Sommer-Str": {"street": "Hans-Sommer-Str."},
"Adolfstr 31-42": {"street": "Adolfstr. 31-42"}, "Adolfstr 31-42": {"street": "Adolfstr. 31-42"},
"Am Schwarzen Berge": {"street": "am Schwarzen Berge "}, "Am Schwarzen Berge": {"street": "am Schwarzen Berge "},
} }
API_URL = "https://www.cederbaum.de/blaue-tonne/abfuhrkalender" API_URL = "https://www.cederbaum.de/blaue-tonne/abfuhrkalender"
ICON_MAP = { ICON_MAP = {
"PAPER": "mdi:newspaper", "PAPER": "mdi:newspaper",
} }
class Source: class Source:
def __init__(self, street): def __init__(self, street):
self._street = street self._street = street
self.page_source = None self.page_source = None
self.street_id = None self.street_id = None
self.collection_data = None self.collection_data = None
def fetch_page_source(self): def fetch_page_source(self):
resp = requests.get(API_URL) resp = requests.get(API_URL)
soup = BeautifulSoup(resp.text, "html.parser") soup = BeautifulSoup(resp.text, "html.parser")
self.page_source = soup self.page_source = soup
def get_street_id(self): def get_street_id(self):
if not self.page_source: if not self.page_source:
raise ValueError("No page source found") raise ValueError("No page source found")
select = self.page_source.find("select") select = self.page_source.find("select")
if not select: if not select:
raise ValueError("No <select> tag found") raise ValueError("No <select> tag found")
options = select.find_all("option") options = select.find_all("option")
for option in options: for option in options:
value = option.get("value") value = option.get("value")
text = option.get_text() text = option.get_text()
if text.lower().strip() == self._street.lower().strip(): if text.lower().strip() == self._street.lower().strip():
self.street_id = value self.street_id = value
break break
def get_collection_data(self): def get_collection_data(self):
if not self.page_source: if not self.page_source:
raise ValueError("No page source found") raise ValueError("No page source found")
script_tags = self.page_source.find_all("script") script_tags = self.page_source.find_all("script")
script_with_text = [tag for tag in script_tags if tag.string] script_with_text = [tag for tag in script_tags if tag.string]
pattern = re.compile(r"var rate = (\{.*?\});") pattern = re.compile(r"var rate = (\{.*?\});")
for script_tag in script_with_text: for script_tag in script_with_text:
match = pattern.search(script_tag.string) match = pattern.search(script_tag.string)
if match: if match:
var_content = match.group(1) var_content = match.group(1)
self.collection_data = json.loads(var_content) self.collection_data = json.loads(var_content)
break break
def fetch(self): def fetch(self):
self.fetch_page_source() self.fetch_page_source()
self.get_street_id() self.get_street_id()
self.get_collection_data() self.get_collection_data()
if not self.collection_data: if not self.collection_data:
raise ValueError("No collection data found") raise ValueError("No collection data found")
entries = [] entries = []
waste_dates = self.collection_data[self.street_id]["Termine"] waste_dates = self.collection_data[self.street_id]["Termine"]
for waste_date in waste_dates: for waste_date in waste_dates:
date = datetime.datetime.strptime( date = datetime.datetime.strptime(
waste_dates[waste_date]["Termin"], "%d.%m.%Y" waste_dates[waste_date]["Termin"], "%d.%m.%Y"
) )
entries.append( entries.append(
Collection( Collection(
date=date.date(), date=date.date(),
t="Paper", t="Paper",
icon=ICON_MAP.get("PAPER"), icon=ICON_MAP.get("PAPER"),
) )
) )
return entries return entries

View File

@@ -1,57 +1,57 @@
# BIR - Bergensområdets Interkommunale Renovasjonsselskap # BIR - Bergensområdets Interkommunale Renovasjonsselskap
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: bir_no - name: bir_no
args: args:
street_name: "" street_name: ""
house_number: "" house_number: ""
house_letter: "" house_letter: ""
``` ```
### Configuration Variables ### Configuration Variables
**street_name** **street_name**
*(string) (required)* *(string) (required)*
**house_number** **house_number**
*(string|Integer) (required)* *(string|Integer) (required)*
**house_letter** **house_letter**
*(string) (optional)* *(string) (optional)*
The arguments should be written exactly like on the <https://bir.no/> website The arguments should be written exactly like on the <https://bir.no/> website
# Example configuration.yaml: # Example configuration.yaml:
```yaml ```yaml
# Waste collection # Waste collection
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: bir_no - name: bir_no
args: args:
street_name: "Alf Bondes Veg" street_name: "Alf Bondes Veg"
house_number: "13" house_number: "13"
house_letter: "B" house_letter: "B"
customize: customize:
- type: blue bin - type: blue bin
alias: Papir alias: Papir
- type: green bin - type: green bin
alias: Restavfall alias: Restavfall
# Optional Sensors # Optional Sensors
sensor: sensor:
- platform: waste_collection_schedule - platform: waste_collection_schedule
name: next_collection name: next_collection
- platform: waste_collection_schedule - platform: waste_collection_schedule
name: waste_collection_garbage name: waste_collection_garbage
details_format: upcoming details_format: upcoming
types: types:
- Restavfall - Restavfall
- platform: waste_collection_schedule - platform: waste_collection_schedule
name: waste_collection_paper name: waste_collection_paper
details_format: upcoming details_format: upcoming
types: types:
- Papir og plastemballasje - Papir og plastemballasje
``` ```

View File

@@ -1,32 +1,32 @@
# Cederbaum Braunschweig # Cederbaum Braunschweig
Support for paper waste collection schedules provided by [Cederbaum Container GmbH](https://www.cederbaum.de/), serving the city of Braunschweig, Germany. Support for paper waste collection schedules provided by [Cederbaum Container GmbH](https://www.cederbaum.de/), serving the city of Braunschweig, Germany.
## Configuration via configuration.yaml ## Configuration via configuration.yaml
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: cederbaum_de - name: cederbaum_de
args: args:
street: STREET street: STREET
``` ```
### Configuration Variables ### Configuration Variables
**street** **street**
*(String) (required)* *(String) (required)*
## Example ## Example
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: cederbaum_de - name: cederbaum_de
args: args:
street: "Hans-Sommer-Str." street: "Hans-Sommer-Str."
``` ```
## How to get the source argument ## How to get the source argument
Find the parameter of your street using [https://www.cederbaum.de/blaue-tonne/abfuhrkalender](https://www.cederbaum.de/blaue-tonne/abfuhrkalender) and write them exactly like on the web page. Find the parameter of your street using [https://www.cederbaum.de/blaue-tonne/abfuhrkalender](https://www.cederbaum.de/blaue-tonne/abfuhrkalender) and write them exactly like on the web page.

View File

@@ -1,56 +1,56 @@
# Samverkan Återvinning Miljö (SÅM) # Samverkan Återvinning Miljö (SÅM)
Support for schedules provided by [Samverkan Återvinning Miljö (SÅM)](https://samiljo.se/avfallshamtning/hamtningskalender/), serving the municipality of Gislaved, Gnosjö, Vaggeryd and Värnamo, Sweden. Support for schedules provided by [Samverkan Återvinning Miljö (SÅM)](https://samiljo.se/avfallshamtning/hamtningskalender/), serving the municipality of Gislaved, Gnosjö, Vaggeryd and Värnamo, Sweden.
Helgvecka means that the pickup day might deviate from the scheduled day due to a public holiday during the week. Helgvecka means that the pickup day might deviate from the scheduled day due to a public holiday during the week.
## Configuration via configuration.yaml ## Configuration via configuration.yaml
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: samiljo_se - name: samiljo_se
args: args:
street: STREET_NAME street: STREET_NAME
city: CITY_NAME city: CITY_NAME
``` ```
### Configuration Variables ### Configuration Variables
**street** **street**
*(string) (required)* *(string) (required)*
**city** **city**
*(string) (required)* *(string) (required)*
## Example ## Example
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: samiljo_se - name: samiljo_se
args: args:
street: Storgatan 1 street: Storgatan 1
city: Burseryd city: Burseryd
``` ```
## How to get the source argument ## How to get the source argument
The source argument is the street including number and the city to the house with waste collection. The source argument is the street including number and the city to the house with waste collection.
The address can be tested [here](https://samiljo.se/avfallshamtning/hamtningskalender/). The address can be tested [here](https://samiljo.se/avfallshamtning/hamtningskalender/).
## How to add new waste types ## How to add new waste types
If your address are missing any waste types that shows in the [Hämtningskalender](https://samiljo.se/avfallshamtning/hamtningskalender/). Then there might be missing mappings in the NAME_MAP. If your address are missing any waste types that shows in the [Hämtningskalender](https://samiljo.se/avfallshamtning/hamtningskalender/). Then there might be missing mappings in the NAME_MAP.
1. Run Samiljo_se_wastetype_searcher.py for the specific address or without arguments to scan all addresses in the database. <br /> 1. Run Samiljo_se_wastetype_searcher.py for the specific address or without arguments to scan all addresses in the database. <br />
Examples of valid command below. Examples of valid command below.
```shell ```shell
> samiljo_se_wastetype_searcher.py --street "Storgatan 1" --city "Burseryd" > samiljo_se_wastetype_searcher.py --street "Storgatan 1" --city "Burseryd"
> samiljo_se_wastetype_searcher.py --city "Burseryd" > samiljo_se_wastetype_searcher.py --city "Burseryd"
> samiljo_se_wastetype_searcher.py --street "Storgatan 1" > samiljo_se_wastetype_searcher.py --street "Storgatan 1"
> samiljo_se_wastetype_searcher.py > samiljo_se_wastetype_searcher.py
``` ```
2. Missing mappings will be returned together with an address. 2. Missing mappings will be returned together with an address.
3. Use the [Hämtningskalender](https://samiljo.se/avfallshamtning/hamtningskalender/) to extract the corresponding common name to the new wastetype. 3. Use the [Hämtningskalender](https://samiljo.se/avfallshamtning/hamtningskalender/) to extract the corresponding common name to the new wastetype.
4. Add the new types to the NAME_MAP and optionaly to the ICON_MAP in samiljo_se.py and samiljo_se_wastetype_searcher.py. 4. Add the new types to the NAME_MAP and optionally to the ICON_MAP in samiljo_se.py and samiljo_se_wastetype_searcher.py.

View File

@@ -1,42 +1,42 @@
# Uppsala Vatten och Avfall AB # Uppsala Vatten och Avfall AB
Support for schedules provided by [Uppsala Vatten och Avfall AB](https://www.uppsalavatten.se), serving the municipality of Uppsala. Support for schedules provided by [Uppsala Vatten och Avfall AB](https://www.uppsalavatten.se), serving the municipality of Uppsala.
## Configuration via configuration.yaml ## Configuration via configuration.yaml
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: uppsalavatten_se - name: uppsalavatten_se
args: args:
street: STREET_NAME street: STREET_NAME
city: CITY_NAME city: CITY_NAME
``` ```
### Configuration Variables ### Configuration Variables
**street** **street**
*(string) (required)* *(string) (required)*
**city** **city**
*(string) (required)* *(string) (required)*
## Example ## Example
```yaml ```yaml
waste_collection_schedule: waste_collection_schedule:
sources: sources:
- name: uppsalavatten_se - name: uppsalavatten_se
args: args:
street: SADELVÄGEN 1 street: SADELVÄGEN 1
city: BJÖRKLINGE city: BJÖRKLINGE
``` ```
## How to get the source argument ## How to get the source argument
The source argument is the street including number and the city to the house with waste collection. The source argument is the street including number and the city to the house with waste collection.
The address can be tested [here](https://www.uppsalavatten.se/sjalvservice/hamtningar-och-berakningar/dag-for-sophamtning-och-slamtomning). The address can be tested [here](https://www.uppsalavatten.se/sjalvservice/hamtningar-och-berakningar/dag-for-sophamtning-och-slamtomning).