mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 04:06:03 +01:00
Add service appabfallplusde and corresponding source (#1313)
Adds a Source that support all abfallplus Apps
This commit is contained in:
@@ -17,7 +17,7 @@ repos:
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing, Adresse, termine, adresse
|
||||
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,Adresse,termine,adresse,oder,alle,assistent
|
||||
- --skip="./.*,*.csv,*.json"
|
||||
- --quiet-level=2
|
||||
exclude_types: [csv, json]
|
||||
|
||||
111
README.md
111
README.md
@@ -364,6 +364,8 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [AbfallNavi (RegioIT.de)](/doc/source/abfallnavi_de.md) / regioit.de
|
||||
- [Abfalltermine Forchheim](/doc/source/abfalltermine_forchheim_de.md) / abfalltermine-forchheim.de
|
||||
- [Abfallwirtschaft Alb-Donau-Kreis](/doc/source/buergerportal_de.md) / aw-adk.de
|
||||
- [Abfallwirtschaft Altkreis Göttingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkgoettingen
|
||||
- [Abfallwirtschaft Altkreis Osterode am Harz](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkgoettingen
|
||||
- [Abfallwirtschaft Enzkreis](/doc/ics/entsorgung_regional_de.md) / entsorgung-regional.de
|
||||
- [Abfallwirtschaft Freiburg](/doc/ics/abfallwirtschaft_freiburg_de.md) / abfall-eglz.de
|
||||
- [Abfallwirtschaft Germersheim](/doc/source/abfallwirtschaft_germersheim_de.md) / abfallwirtschaft-germersheim.de
|
||||
@@ -412,13 +414,17 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [AHE Ennepe-Ruhr-Kreis](/doc/source/ahe_de.md) / ahe.de
|
||||
- [ALBA Berlin](/doc/source/abfall_io.md) / berlin.alba.info
|
||||
- [ALBA Braunschweig](/doc/ics/alba_bs_de.md) / alba-bs.de
|
||||
- [ALF Lahn-Fulda](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallhr
|
||||
- [Altmarkkreis Salzwedel](/doc/ics/abfall_app_net.md) / altmarkkreis-salzwedel.de
|
||||
- [Altötting (LK)](/doc/source/jumomind_de.md) / lra-aoe.de
|
||||
- [Apps by Abfall+](/doc/source/app_abfallplus_de.md) / abfallplus.de
|
||||
- [ART Trier](/doc/source/art_trier_de.md) / art-trier.de
|
||||
- [Aschaffenburg (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [ASG Wesel](/doc/source/hausmuell_info.md) / asg-wesel.de
|
||||
- [ASO Abfall-Service Osterholz](/doc/source/abfall_io.md) / aso-ohz.de
|
||||
- [ASR Stadt Chemnitz](/doc/source/asr_chemnitz_de.md) / asr-chemnitz.de
|
||||
- [ATHOS GmbH](/doc/source/app_abfallplus_de.md) / Abfall+ App: athosmobil
|
||||
- [Augsburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: awa
|
||||
- [Aurich (MKW)](/doc/source/jumomind_de.md) / mkw-grossefehn.de
|
||||
- [AVL - Abfallverwertungsgesellschaft des Landkreises Ludwigsburg mbH](/doc/ics/avl_ludwigsburg_de.md) / avl-ludwigsburg.de
|
||||
- [AWA Entsorgungs GmbH](/doc/source/abfallnavi_de.md) / awa-gmbh.de
|
||||
@@ -430,6 +436,7 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [AWB Landkreis Göppingen](/doc/source/abfall_io.md) / awb-gp.de
|
||||
- [AWB Oldenburg](/doc/source/awb_oldenburg_de.md) / oldenburg.de
|
||||
- [AWB Westerwaldkreis](/doc/source/abfall_io.md) / wab.rlp.de
|
||||
- [AWG Donau-Wald](/doc/source/app_abfallplus_de.md) / Abfall+ App: zawdw
|
||||
- [AWG Kreis Warendorf](/doc/source/abfallnavi_de.md) / awg-waf.de
|
||||
- [AWIDO Online](/doc/source/awido_de.md) / awido-online.de
|
||||
- [AWIGO Abfallwirtschaft Landkreis Osnabrück GmbH](/doc/source/awigo_de.md) / awigo.de
|
||||
@@ -437,16 +444,21 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Awista Starnberg](/doc/ics/awista_starnberg_de.md) / awista-starnberg.de
|
||||
- [Bad Arolsen (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Bad Homburg vdH](/doc/source/jumomind_de.md) / bad-homburg.de
|
||||
- [Bad Kissingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappbk
|
||||
- [Barnim](/doc/source/jumomind_de.md) / kreiswerke-barnim.de
|
||||
- [Bau & Service Oberursel](/doc/source/c_trace_de.md) / bso-oberursel.de
|
||||
- [Bergischer Abfallwirtschaftverbund](/doc/source/abfallnavi_de.md) / bavweb.de
|
||||
- [Berlin](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Berlin Recycling](/doc/source/berlin_recycling_de.md) / berlin-recycling.de
|
||||
- [Berliner Stadtreinigungsbetriebe](/doc/source/bsr_de.md) / bsr.de
|
||||
- [Beverungen (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Bielefeld](/doc/source/bielefeld_de.md) / bielefeld.de
|
||||
- [Blaue Tonne - Schlaue Tonne](/doc/ics/blauetonne_schlauetonne_de.md) / blauetonne-schlauetonne.de
|
||||
- [Bogenschütz Entsorgung](/doc/source/infeo_at.md) / bogenschuetz-entsorgung.de
|
||||
- [Bonn](/doc/source/app_abfallplus_de.md) / Abfall+ App: bonnorange
|
||||
- [Braunschweig](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Bremer Stadtreinigung](/doc/source/c_trace_de.md) / die-bremer-stadtreinigung.de
|
||||
- [Burgenland (Landkreis)](/doc/source/app_abfallplus_de.md) / Abfall+ App: udb
|
||||
- [Bürgerportal](/doc/source/buergerportal_de.md) / c-trace.de
|
||||
- [C-Trace](/doc/source/c_trace_de.md) / c-trace.de
|
||||
- [Cham Landkreis](/doc/ics/entsorgung_cham_de.md) / entsorgung-cham.de
|
||||
@@ -458,6 +470,8 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Darmstadt-Dieburg (ZAW)](/doc/source/jumomind_de.md) / zaw-online.de
|
||||
- [Dillingen Saar](/doc/source/dillingen_saar_de.md) / dillingen-saar.de
|
||||
- [Dinslaken](/doc/source/abfallnavi_de.md) / dinslaken.de
|
||||
- [Drekopf](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallplaner
|
||||
- [Duisburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwbd
|
||||
- [EAD Darmstadt](/doc/source/ead_darmstadt_de.md) / ead.darmstadt.de
|
||||
- [EDG Entsorgung Dortmund](/doc/ics/edg_de.md) / edg.de
|
||||
- [EGN Abfallkalender](/doc/source/egn_abfallkalender_de.md) / egn-abfallkalender.de
|
||||
@@ -471,10 +485,13 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Entsorgungsbetriebe Essen](/doc/source/abfall_io.md) / ebe-essen.de
|
||||
- [Entsorgungsgesellschaft Görlitz-Löbau-Zittau](/doc/ics/abfall_eglz_de.md) / abfall-eglz.de
|
||||
- [Esens (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Essen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallebe
|
||||
- [EVA Abfallentsorgung](/doc/ics/eva_abfallentsorgung_de.md) / eva-abfallentsorgung.de
|
||||
- [EVS Entsorgungsverband Saar](/doc/source/muellmax_de.md) / evs.de
|
||||
- [FES Frankfurter Entsorgungs- und Service GmbH](/doc/ics/fes_frankfurt_de.md) / fes-frankfurt.de
|
||||
- [Flensburg (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Frankfurt (Oder)](/doc/source/app_abfallplus_de.md) / Abfall+ App: unterallgaeu
|
||||
- [Freiburg im Breisgau](/doc/source/app_abfallplus_de.md) / Abfall+ App: asf
|
||||
- [Gelsendienste Gelsenkirchen](/doc/ics/gelsendienste_de.md) / gelsendienste.de
|
||||
- [Gemeinde Aschheim](/doc/source/cmcitymedia_de.md) / cmcitymedia.de
|
||||
- [Gemeinde Blankenheim](/doc/source/cmcitymedia_de.md) / cmcitymedia.de
|
||||
@@ -492,24 +509,79 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Großkrotzenburg (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Göttinger Entsorgungsbetriebe](/doc/source/abfall_io.md) / geb-goettingen.de
|
||||
- [Gütersloh](/doc/source/abfallnavi_de.md) / guetersloh.de
|
||||
- [Hagen](/doc/source/app_abfallplus_de.md) / Abfall+ App: hebhagen
|
||||
- [Hainburg (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Hallesche Wasser und Stadtwirtschaft GmbH](/doc/ics/hws_halle_de.md) / hws-halle.de
|
||||
- [Halver](/doc/source/abfallnavi_de.md) / halver.de
|
||||
- [Hattersheim am Main](/doc/source/jumomind_de.md) / hattersheim.de
|
||||
- [hausmüll.info](/doc/source/hausmuell_info.md) / hausmuell.info
|
||||
- [Havelland](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Heilbronn Entsorgungsbetriebe](/doc/source/heilbronn_de.md) / heilbronn.de
|
||||
- [Hohenlohekreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: hokwaste
|
||||
- [Hohenlohekreis](/doc/source/cmcitymedia_de.md) / cmcitymedia.de
|
||||
- [Holtgast (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Ilm-Kreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappik
|
||||
- [Ingolstadt](/doc/source/jumomind_de.md) / in-kb.de
|
||||
- [Jumomind](/doc/source/jumomind_de.md) / jumomind.de
|
||||
- [KAEV Niederlausitz](/doc/source/kaev_niederlausitz.md) / kaev.de
|
||||
- [Kamp-Lintfort (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Kirchdorf (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Kommunalservice Landkreis Börde AöR](/doc/source/ks_boerde_de.md) / ks-boerde.de
|
||||
- [Kreis Augsburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallapp
|
||||
- [Kreis Bad Kissingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallscout
|
||||
- [Kreis Bautzen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfalllkbz
|
||||
- [Kreis Bayreuth](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfalllkbt
|
||||
- [Kreis Bergstraße](/doc/source/app_abfallplus_de.md) / Abfall+ App: zakb
|
||||
- [Kreis Breisgau-Hochschwarzwald](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappbh
|
||||
- [Kreis Calw](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallinfocw
|
||||
- [Kreis Cloppenburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappclp
|
||||
- [Kreis Coesfeld](/doc/source/abfallnavi_de.md) / wbc-coesfeld.de
|
||||
- [Kreis Cuxhaven](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappcux
|
||||
- [Kreis Diepholz](/doc/source/app_abfallplus_de.md) / Abfall+ App: awgbassum
|
||||
- [Kreis Emmendingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkemmendingen
|
||||
- [Kreis Emsland](/doc/source/app_abfallplus_de.md) / Abfall+ App: awbemsland
|
||||
- [Kreis Freudenstadt](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappfds
|
||||
- [Kreis Fürth](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappfuerth
|
||||
- [Kreis Garmisch-Partenkirchen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappgap
|
||||
- [Kreis Göppingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: awbgp
|
||||
- [Kreis Heilbronn](/doc/source/app_abfallplus_de.md) / Abfall+ App: de
|
||||
- [Kreis Heinsberg](/doc/source/abfallnavi_de.md) / kreis-heinsberg.de
|
||||
- [Kreis Karlsruhe](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappka
|
||||
- [Kreis Kitzingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwelt
|
||||
- [Kreis Landsberg am Lech](/doc/source/app_abfallplus_de.md) / Abfall+ App: llabfallapp
|
||||
- [Kreis Landshut](/doc/source/app_abfallplus_de.md) / Abfall+ App: landshutlk
|
||||
- [Kreis Limburg-Weilburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: meinawblm
|
||||
- [Kreis Ludwigsburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: avlserviceplus
|
||||
- [Kreis Lörrach](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallapploe
|
||||
- [Kreis Mayen-Koblenz](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappmyk
|
||||
- [Kreis Miesbach](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappvivo
|
||||
- [Kreis Miltenberg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappmil
|
||||
- [Kreis Märkisch-Oderland](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappmol
|
||||
- [Kreis Neustadt/Aisch-Bad Windsheim](/doc/source/app_abfallplus_de.md) / Abfall+ App: neustadtaisch
|
||||
- [Kreis Neuwied](/doc/source/app_abfallplus_de.md) / Abfall+ App: muellwecker_neuwied
|
||||
- [Kreis Nienburg / Weser](/doc/source/app_abfallplus_de.md) / Abfall+ App: bawnapp
|
||||
- [Kreis Nordfriesland](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappnf
|
||||
- [Kreis Ostallgäu](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappoal
|
||||
- [Kreis Osterholz](/doc/source/app_abfallplus_de.md) / Abfall+ App: asoapp
|
||||
- [Kreis Pinneberg](/doc/source/abfallnavi_de.md) / kreis-pinneberg.de
|
||||
- [Kreis Rastatt](/doc/source/app_abfallplus_de.md) / Abfall+ App: awbrastatt
|
||||
- [Kreis Ravensburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallapprv
|
||||
- [Kreis Reutlingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallkreisrt
|
||||
- [Kreis Rotenburg (Wümme)](/doc/source/app_abfallplus_de.md) / Abfall+ App: awrplus
|
||||
- [Kreis Schaumburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: aws
|
||||
- [Kreis Sigmaringen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappsig
|
||||
- [Kreis Starnberg](/doc/source/app_abfallplus_de.md) / Abfall+ App: awistasta
|
||||
- [Kreis Steinfurt](/doc/source/app_abfallplus_de.md) / Abfall+ App: egst
|
||||
- [Kreis Südwestpfalz](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfalllkswp
|
||||
- [Kreis Traunstein](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappts
|
||||
- [Kreis Trier-Saarburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappart
|
||||
- [Kreis Uelzen](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkruelzen
|
||||
- [Kreis Vechta](/doc/source/app_abfallplus_de.md) / Abfall+ App: awvapp
|
||||
- [Kreis Viersen](/doc/source/abfallnavi_de.md) / kreis-viersen.de
|
||||
- [Kreis Vorpommern-Rügen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappvorue
|
||||
- [Kreis Weißenburg-Gunzenhausen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappwug
|
||||
- [Kreis Wesermarsch](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappgib
|
||||
- [Kreis Würzburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: teamorange
|
||||
- [Kreisstadt Dietzenbach](/doc/source/c_trace_de.md) / dietzenbach.de
|
||||
- [Kreisstadt Friedberg](/doc/source/muellmax_de.md) / friedberg-hessen.de
|
||||
- [Kreisstadt Groß-Gerau](/doc/ics/gross_gerau_de.md) / gross-gerau.de
|
||||
@@ -525,6 +597,7 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Landkreis Bayreuth](/doc/source/abfall_io.md) / landkreis-bayreuth.de
|
||||
- [Landkreis Berchtesgadener Land](/doc/source/awido_de.md) / lra-bgl.de
|
||||
- [Landkreis Biberach (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Böblingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappbb
|
||||
- [Landkreis Böblingen](/doc/ics/abfall_app_net.md) / lrabb.de
|
||||
- [Landkreis Börde AöR (KsB)](/doc/source/hausmuell_info.md) / ks-boerde.de
|
||||
- [Landkreis Calw](/doc/source/abfall_io.md) / kreis-calw.de
|
||||
@@ -532,10 +605,12 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Landkreis Eichstätt (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Erding](/doc/source/awido_de.md) / landkreis-erding.de
|
||||
- [Landkreis Erlangen-Höchstadt](/doc/source/erlangen_hoechstadt_de.md) / erlangen-hoechstadt.de
|
||||
- [Landkreis Esslingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappes
|
||||
- [Landkreis Friesland (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Fulda](/doc/source/awido_de.md) / landkreis-fulda.de
|
||||
- [Landkreis Gießen](/doc/source/muellmax_de.md) / lkgi.de
|
||||
- [Landkreis Gotha](/doc/source/awido_de.md) / landkreis-gotha.de
|
||||
- [Landkreis Görlitz](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkgr
|
||||
- [Landkreis Günzburg](/doc/source/awido_de.md) / kaw.landkreis-guenzburg.de
|
||||
- [Landkreis Hameln-Pyrmont](/doc/ics/hameln_pyrmont_de.md) / hameln-pyrmont.de
|
||||
- [Landkreis Heilbronn](/doc/source/abfall_io.md) / landkreis-heilbronn.de
|
||||
@@ -544,8 +619,10 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Landkreis Kulmbach](/doc/source/awido_de.md) / landkreis-kulmbach.de
|
||||
- [Landkreis Kusel](/doc/source/landkreis_kusel_de.md) / landkreis-kusel.de
|
||||
- [Landkreis Leer (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Leipzig](/doc/source/app_abfallplus_de.md) / Abfall+ App: leipziglk
|
||||
- [Landkreis Limburg-Weilburg](/doc/source/abfall_io.md) / awb-lm.de
|
||||
- [Landkreis Lüchow-Dannenberg](/doc/ics/abfall_app_net.md) / luechow-dannenberg.de
|
||||
- [Landkreis Main-Spessart](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallmsp
|
||||
- [Landkreis Mettmann (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Mühldorf a. Inn](/doc/source/awido_de.md) / lra-mue.de
|
||||
- [Landkreis Nordwestmecklenburg](/doc/source/geoport_nwm_de.md) / geoport-nwm.de
|
||||
@@ -572,6 +649,7 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Landkreis Wittmund](/doc/source/landkreis_wittmund_de.md) / landkreis-wittmund.de
|
||||
- [Landkreis Wittmund (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Wittmund (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Landkreis Wunsiedel im Fichtelgebirge](/doc/source/app_abfallplus_de.md) / Abfall+ App: kufiapp
|
||||
- [Landkreisbetriebe Neuburg-Schrobenhausen](/doc/source/awido_de.md) / landkreisbetriebe.de
|
||||
- [Landratsamt Aichach-Friedberg](/doc/source/awido_de.md) / lra-aic-fdb.de
|
||||
- [Landratsamt Bodenseekreis](/doc/ics/bodenseekreis_de.md) / bodenseekreis.de
|
||||
@@ -579,37 +657,60 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Landratsamt Main-Tauber-Kreis](/doc/source/c_trace_de.md) / main-tauber-kreis.de
|
||||
- [Landratsamt Traunstein](/doc/source/abfall_io.md) / traunstein.com
|
||||
- [Landratsamt Unterallgäu](/doc/source/abfall_io.md) / landratsamt-unterallgaeu.de
|
||||
- [Landshut](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappla
|
||||
- [Lebacher Abfallzweckverband (LAZ)](/doc/ics/lebach_de.md) / lebach.de
|
||||
- [Leverkusen](/doc/source/app_abfallplus_de.md) / Abfall+ App: avea
|
||||
- [Ludwigshafen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfalllu
|
||||
- [Ludwigshafen am Rhein](/doc/source/abfall_io.md) / ludwigshafen.de
|
||||
- [Lübbecke (Jumomind)](/doc/source/jumomind_de.md) / luebbecke.de
|
||||
- [Lübeck Entsorgungsbetriebe](/doc/ics/luebeck_de.md) / luebeck.de
|
||||
- [mags Mönchengladbacher Abfall-, Grün- und Straßenbetriebe AöR](/doc/source/mags_de.md) / mags.de
|
||||
- [Main-Kinzig-Kreis (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Mannheim](/doc/source/app_abfallplus_de.md) / Abfall+ App: de
|
||||
- [Mechernich und Kommunen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallinfoapp
|
||||
- [Mein-Abfallkalender.de](/doc/ics/mein_abfallkalender_de.md) / mein-abfallkalender.de
|
||||
- [Metzingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappmetz
|
||||
- [Minden](/doc/source/jumomind_de.md) / minden.de
|
||||
- [MZV Biedenkopf](/doc/source/buergerportal_de.md) / mzv-biedenkopf.de
|
||||
- [Mühlheim am Main (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Müllabfuhr Deutschland](/doc/source/muellabfuhr_de.md) / portal.muellabfuhr-deutschland.de
|
||||
- [MüllALARM / Schönmackers](/doc/source/abfall_io.md) / schoenmackers.de
|
||||
- [Müllmax](/doc/source/muellmax_de.md) / muellmax.de
|
||||
- [München Landkreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: lkmabfallplus
|
||||
- [Neckar-Odenwald-Kreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappno
|
||||
- [Nenndorf (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Neumünster (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Neunkirchen Siegerland](/doc/source/abfall_neunkirchen_siegerland_de.md) / neunkirchen-siegerland.de
|
||||
- [Neustadt a.d. Waldnaab](/doc/source/awido_de.md) / neustadt.de
|
||||
- [Neustadt an der Weinstraße](/doc/source/jumomind_de.md) / neustadt.eu
|
||||
- [Nordsachsen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwecker
|
||||
- [Oberhavel](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Oberhavel AWU](/doc/ics/awu_oberhavel_de.md) / awu-oberhavel.de
|
||||
- [Oldenburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappol
|
||||
- [Ortenaukreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappog
|
||||
- [Ostprignitz-Ruppin](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Potsdam](/doc/source/potsdam_de.md) / potsdam.de
|
||||
- [Prignitz](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwecker
|
||||
- [Prignitz](/doc/source/app_abfallplus_de.md) / Abfall+ App: unterallgaeu
|
||||
- [Pullach im Isartal](/doc/source/awido_de.md) / pullach.de
|
||||
- [Recklinghausen](/doc/source/jumomind_de.md) / zbh-ksr.de
|
||||
- [RegioEntsorgung AöR](/doc/source/app_abfallplus_de.md) / Abfall+ App: regioentsorgung
|
||||
- [RegioEntsorgung Städteregion Aachen](/doc/source/regioentsorgung_de.md) / regioentsorgung.de
|
||||
- [Rhein-Hunsrück (Jumomind)](/doc/source/jumomind_de.md) / rh-entsorgung.de
|
||||
- [Rhein-Hunsrück Entsorgung (RHE)](/doc/source/rh_entsorgung_de.md) / rh-entsorgung.de
|
||||
- [Rhein-Neckar-Kreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallavr
|
||||
- [Rhein-Neckar-Kreis](/doc/source/abfall_io.md) / rhein-neckar-kreis.de
|
||||
- [Rhein-Pfalz-Kreis](/doc/ics/abfall_app_net.md) / rhein-pfalz-kreis.de
|
||||
- [Rottweil](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwecker
|
||||
- [Rottweil](/doc/source/app_abfallplus_de.md) / Abfall+ App: unterallgaeu
|
||||
- [RSAG Rhein-Sieg-Kreis](/doc/source/muellmax_de.md) / rsag.de
|
||||
- [Salzgitter (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Salzlandkreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallslk
|
||||
- [Schmitten im Taunus (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Schwarze Elster](/doc/source/app_abfallplus_de.md) / Abfall+ App: aevapp
|
||||
- [Schwarzwald-Baar-Kreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallsbk
|
||||
- [Schöneck (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Schönmackers](/doc/source/app_abfallplus_de.md) / Abfall+ App: muellalarm
|
||||
- [Sector 27 - Datteln, Marl, Oer-Erkenschwick](/doc/source/sector27_de.md) / muellkalender.sector27.de
|
||||
- [Seligenstadt (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Stadt Aachen](/doc/source/abfallnavi_de.md) / aachen.de
|
||||
@@ -652,6 +753,9 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [Südbrandenburgischer Abfallzweckverband](/doc/source/sbazv_de.md) / sbazv.de
|
||||
- [TBR Remscheid](/doc/source/muellmax_de.md) / tbr-info.de
|
||||
- [Technischer Betriebsdienst Reutlingen](/doc/ics/tbr_reutlingen_de.md) / tbr-reutlingen.de
|
||||
- [Tuttlingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwecker
|
||||
- [Tuttlingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: unterallgaeu
|
||||
- [Tübingen](/doc/source/app_abfallplus_de.md) / Abfall+ App: app
|
||||
- [Uckermark](/doc/source/jumomind_de.md) / udg-uckermark.de
|
||||
- [Ulm (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [USB Bochum](/doc/source/muellmax_de.md) / usb-bochum.de
|
||||
@@ -659,17 +763,24 @@ Waste collection schedules in the following formats and countries are supported.
|
||||
- [VIVO Landkreis Miesbach](/doc/source/abfall_io.md) / vivowarngau.de
|
||||
- [Volkmarsen (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Vöhringen (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Waldshut](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallwecker
|
||||
- [Waldshut](/doc/source/app_abfallplus_de.md) / Abfall+ App: unterallgaeu
|
||||
- [WBO Wirtschaftsbetriebe Oberhausen](/doc/source/abfallnavi_de.md) / wbo-online.de
|
||||
- [Wegberg (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Wermelskirchen](/doc/source/wermelskirchen_de.md) / wermelskirchen.de
|
||||
- [Westerholt (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Westerwaldkreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: wabapp
|
||||
- [WGV Recycling GmbH](/doc/source/awido_de.md) / wgv-quarzbichl.de
|
||||
- [Wilhelmshaven (MyMuell App)](/doc/source/jumomind_de.md) / mymuell.de
|
||||
- [Wolfsburger Abfallwirtschaft und Straßenreinigung](/doc/source/was_wolfsburg_de.md) / was-wolfsburg.de
|
||||
- [WZV Kreis Segeberg](/doc/source/c_trace_de.md) / wzv.de
|
||||
- [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-SR Straubing](/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
|
||||
- [Zollernalbkreis](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallzak
|
||||
- [Zweckverband Abfallwirtschaft Kreis Bergstraße](/doc/source/zakb_de.md) / zakb.de
|
||||
- [Zweckverband Abfallwirtschaft Oberes Elbtal](/doc/ics/zaoe_de.md) / zaoe.de
|
||||
- [Zweckverband Abfallwirtschaft Region Hannover](/doc/source/aha_region_de.md) / aha-region.de
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"documentation": "https://github.com/mampfes/hacs_waste_collection_schedule#readme",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["icalendar", "recurring_ical_events", "icalevents", "bs4"],
|
||||
"requirements": ["icalendar", "recurring_ical_events", "icalevents", "bs4", "lxml"],
|
||||
"version": "1.42.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,768 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import random
|
||||
import re
|
||||
from datetime import date, datetime
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
SUPPORTED_APPS = [
|
||||
"de.albagroup.app",
|
||||
"de.k4systems.abfallinfocw",
|
||||
"de.k4systems.abfallinfoapp",
|
||||
"de.k4systems.abfallappes",
|
||||
"de.k4systems.egst",
|
||||
"de.idcontor.abfallwbd",
|
||||
"de.ucom.abfallavr",
|
||||
"de.k4systems.abfallapprv",
|
||||
"de.k4systems.avlserviceplus",
|
||||
"de.k4systems.muellalarm",
|
||||
"de.k4systems.abfallapploe",
|
||||
"de.k4systems.abfallappart",
|
||||
"de.k4systems.abfallapp",
|
||||
"de.k4systems.abfallappvorue",
|
||||
"de.k4systems.abfallappfds",
|
||||
"de.k4systems.abfallscout",
|
||||
"de.k4systems.avea",
|
||||
"de.k4systems.neustadtaisch",
|
||||
"de.k4systems.abfalllkswp",
|
||||
"de.k4systems.awbemsland",
|
||||
"de.k4systems.abfallappclp",
|
||||
"de.k4systems.abfallappnf",
|
||||
"de.k4systems.abfallappog",
|
||||
"de.k4systems.abfallappmol",
|
||||
"de.k4systems.kufiapp",
|
||||
"de.k4systems.abfalllkbz",
|
||||
"de.k4systems.abfallappbb",
|
||||
"de.k4systems.abfallappla",
|
||||
"de.k4systems.abfallappwug",
|
||||
"de.k4systems.abfallappik",
|
||||
"de.k4systems.leipziglk",
|
||||
"de.k4systems.abfallappbk",
|
||||
"de.cmcitymedia.hokwaste",
|
||||
"de.abfallwecker",
|
||||
"de.k4systems.abfallappka",
|
||||
"de.k4systems.lkgoettingen",
|
||||
"de.k4systems.abfallappcux",
|
||||
"de.k4systems.abfallslk",
|
||||
"de.k4systems.abfallappzak",
|
||||
"de.zawsr",
|
||||
"de.k4systems.teamorange",
|
||||
"de.k4systems.abfallappvivo",
|
||||
"de.k4systems.lkgr",
|
||||
"de.k4systems.zawdw",
|
||||
"de.k4systems.abfallappgib",
|
||||
"de.k4systems.wuerzburg",
|
||||
"de.k4systems.abfallappgap",
|
||||
"de.k4systems.bonnorange",
|
||||
"de.gimik.apps.muellwecker_neuwied",
|
||||
"abfallH.ucom.de",
|
||||
"de.k4systems.abfallappts",
|
||||
"de.k4systems.awa",
|
||||
"de.k4systems.abfallappfuerth",
|
||||
"de.k4systems.abfallwelt",
|
||||
"de.k4systems.lkemmendingen",
|
||||
"de.k4systems.abfallkreisrt",
|
||||
"de.k4systems.abfallappmetz",
|
||||
"de.k4systems.abfallappmyk",
|
||||
"de.k4systems.abfallappoal",
|
||||
"de.k4systems.regioentsorgung",
|
||||
"de.k4systems.abfalllkbt",
|
||||
"de.k4systems.awvapp",
|
||||
"de.k4systems.aevapp",
|
||||
"de.k4systems.awbgp",
|
||||
"de.k4systems.abfallhr",
|
||||
"de.k4systems.abfallappbh",
|
||||
"de.k4systems.awgbassum",
|
||||
"de.data_at_work.aws",
|
||||
"de.k4systems.hebhagen",
|
||||
"de.k4systems.meinawblm",
|
||||
"de.k4systems.abfallmsp",
|
||||
"de.k4systems.asoapp",
|
||||
"de.k4systems.awistasta",
|
||||
"de.ucom.abfallebe",
|
||||
"de.k4systems.abfallinfocw",
|
||||
"de.k4systems.bawnapp",
|
||||
"de.k4systems.abfallappol",
|
||||
"de.k4systems.awbrastatt",
|
||||
"de.k4systems.abfallappmil",
|
||||
"de.k4systems.abfallsbk",
|
||||
"de.k4systems.wabapp",
|
||||
"abfallMA.ucom.de",
|
||||
"de.k4systems.llabfallapp",
|
||||
"de.k4systems.lkruelzen",
|
||||
"de.k4systems.abfallzak",
|
||||
"de.k4systems.abfallappno",
|
||||
"de.k4systems.udb",
|
||||
"de.k4systems.abfallappsig",
|
||||
"de.k4systems.asf",
|
||||
"de.drekopf.abfallplaner",
|
||||
"de.k4systems.unterallgaeu",
|
||||
"de.k4systems.landshutlk",
|
||||
"de.k4systems.zakb",
|
||||
"de.k4systems.abfallinfoapp",
|
||||
"de.k4systems.awrplus",
|
||||
"de.k4systems.lkmabfallplus",
|
||||
"de.k4systems.athosmobil",
|
||||
"de.k4systems.willkommen",
|
||||
"de.idcontor.abfalllu",
|
||||
]
|
||||
|
||||
SUPPORTED_SERVICES = {
|
||||
"de.albagroup.app": [
|
||||
"Berlin",
|
||||
"Braunschweig",
|
||||
"Havelland",
|
||||
"Oberhavel",
|
||||
"Ostprignitz-Ruppin",
|
||||
"Tübingen",
|
||||
],
|
||||
"de.k4systems.abfallinfocw": ["Kreis Calw"],
|
||||
"de.k4systems.abfallinfoapp": ["Mechernich und Kommunen"],
|
||||
"de.k4systems.abfallappes": ["Landkreis Esslingen"],
|
||||
"de.k4systems.egst": ["Kreis Steinfurt"],
|
||||
"de.idcontor.abfallwbd": ["Duisburg"],
|
||||
"de.ucom.abfallavr": ["Rhein-Neckar-Kreis"],
|
||||
"de.k4systems.abfallapprv": ["Kreis Ravensburg"],
|
||||
"de.k4systems.avlserviceplus": ["Kreis Ludwigsburg"],
|
||||
"de.k4systems.muellalarm": ["Schönmackers"],
|
||||
"de.k4systems.abfallapploe": ["Kreis Lörrach"],
|
||||
"de.k4systems.abfallappart": ["Kreis Trier-Saarburg"],
|
||||
"de.k4systems.abfallapp": ["Kreis Augsburg"],
|
||||
"de.k4systems.abfallappvorue": ["Kreis Vorpommern-Rügen"],
|
||||
"de.k4systems.abfallappfds": ["Kreis Freudenstadt"],
|
||||
"de.k4systems.abfallscout": ["Kreis Bad Kissingen"],
|
||||
"de.k4systems.avea": ["Leverkusen"],
|
||||
"de.k4systems.neustadtaisch": ["Kreis Neustadt/Aisch-Bad Windsheim"],
|
||||
"de.k4systems.abfalllkswp": ["Kreis Südwestpfalz"],
|
||||
"de.k4systems.awbemsland": ["Kreis Emsland"],
|
||||
"de.k4systems.abfallappclp": ["Kreis Cloppenburg"],
|
||||
"de.k4systems.abfallappnf": ["Kreis Nordfriesland"],
|
||||
"de.k4systems.abfallappog": ["Ortenaukreis"],
|
||||
"de.k4systems.abfallappmol": ["Kreis Märkisch-Oderland"],
|
||||
"de.k4systems.kufiapp": ["Landkreis Wunsiedel im Fichtelgebirge"],
|
||||
"de.k4systems.abfalllkbz": ["Kreis Bautzen"],
|
||||
"de.k4systems.abfallappbb": ["Landkreis Böblingen"],
|
||||
"de.k4systems.abfallappla": ["Landshut"],
|
||||
"de.k4systems.abfallappwug": ["Kreis Weißenburg-Gunzenhausen"],
|
||||
"de.k4systems.abfallappik": ["Ilm-Kreis"],
|
||||
"de.k4systems.leipziglk": ["Landkreis Leipzig"],
|
||||
"de.k4systems.abfallappbk": ["Bad Kissingen"],
|
||||
"de.cmcitymedia.hokwaste": ["Hohenlohekreis"],
|
||||
"de.abfallwecker": [
|
||||
"Rottweil",
|
||||
"Tuttlingen",
|
||||
"Waldshut",
|
||||
"Prignitz",
|
||||
"Nordsachsen",
|
||||
],
|
||||
"de.k4systems.abfallappka": ["Kreis Karlsruhe"],
|
||||
"de.k4systems.lkgoettingen": [
|
||||
"Abfallwirtschaft Altkreis Göttingen",
|
||||
"Abfallwirtschaft Altkreis Osterode am Harz",
|
||||
],
|
||||
"de.k4systems.abfallappcux": ["Kreis Cuxhaven"],
|
||||
"de.k4systems.abfallslk": ["Salzlandkreis"],
|
||||
"de.k4systems.abfallappzak": ["ZAK Kempten"],
|
||||
"de.zawsr": ["ZAW-SR Straubing"],
|
||||
"de.k4systems.teamorange": ["Kreis Würzburg"],
|
||||
"de.k4systems.abfallappvivo": ["Kreis Miesbach"],
|
||||
"de.k4systems.lkgr": ["Landkreis Görlitz"],
|
||||
"de.k4systems.zawdw": ["AWG Donau-Wald"],
|
||||
"de.k4systems.abfallappgib": ["Kreis Wesermarsch"],
|
||||
"de.k4systems.wuerzburg": ["Würzburg"],
|
||||
"de.k4systems.abfallappgap": ["Kreis Garmisch-Partenkirchen"],
|
||||
"de.k4systems.bonnorange": ["Bonn"],
|
||||
"de.gimik.apps.muellwecker_neuwied": ["Kreis Neuwied"],
|
||||
"abfallH.ucom.de": ["Kreis Heilbronn"],
|
||||
"de.k4systems.abfallappts": ["Kreis Traunstein"],
|
||||
"de.k4systems.awa": ["Augsburg"],
|
||||
"de.k4systems.abfallappfuerth": ["Kreis Fürth"],
|
||||
"de.k4systems.abfallwelt": ["Kreis Kitzingen"],
|
||||
"de.k4systems.lkemmendingen": ["Kreis Emmendingen"],
|
||||
"de.k4systems.abfallkreisrt": ["Kreis Reutlingen"],
|
||||
"de.k4systems.abfallappmetz": ["Metzingen"],
|
||||
"de.k4systems.abfallappmyk": ["Kreis Mayen-Koblenz"],
|
||||
"de.k4systems.abfallappoal": ["Kreis Ostallgäu"],
|
||||
"de.k4systems.regioentsorgung": ["RegioEntsorgung AöR"],
|
||||
"de.k4systems.abfalllkbt": ["Kreis Bayreuth"],
|
||||
"de.k4systems.awvapp": ["Kreis Vechta"],
|
||||
"de.k4systems.aevapp": ["Schwarze Elster"],
|
||||
"de.k4systems.awbgp": ["Kreis Göppingen"],
|
||||
"de.k4systems.abfallhr": ["ALF Lahn-Fulda"],
|
||||
"de.k4systems.abfallappbh": ["Kreis Breisgau-Hochschwarzwald"],
|
||||
"de.k4systems.awgbassum": ["Kreis Diepholz"],
|
||||
"de.data_at_work.aws": ["Kreis Schaumburg"],
|
||||
"de.k4systems.hebhagen": ["Hagen"],
|
||||
"de.k4systems.meinawblm": ["Kreis Limburg-Weilburg"],
|
||||
"de.k4systems.abfallmsp": ["Landkreis Main-Spessart"],
|
||||
"de.k4systems.asoapp": ["Kreis Osterholz"],
|
||||
"de.k4systems.awistasta": ["Kreis Starnberg"],
|
||||
"de.ucom.abfallebe": ["Essen"],
|
||||
"de.k4systems.bawnapp": ["Kreis Nienburg / Weser"],
|
||||
"de.k4systems.abfallappol": ["Oldenburg"],
|
||||
"de.k4systems.awbrastatt": ["Kreis Rastatt"],
|
||||
"de.k4systems.abfallappmil": ["Kreis Miltenberg"],
|
||||
"de.k4systems.abfallsbk": ["Schwarzwald-Baar-Kreis"],
|
||||
"de.k4systems.wabapp": ["Westerwaldkreis"],
|
||||
"abfallMA.ucom.de": ["Mannheim"],
|
||||
"de.k4systems.llabfallapp": ["Kreis Landsberg am Lech"],
|
||||
"de.k4systems.lkruelzen": ["Kreis Uelzen"],
|
||||
"de.k4systems.abfallzak": ["Zollernalbkreis"],
|
||||
"de.k4systems.abfallappno": ["Neckar-Odenwald-Kreis"],
|
||||
"de.k4systems.udb": ["Burgenland (Landkreis)"],
|
||||
"de.k4systems.abfallappsig": ["Kreis Sigmaringen"],
|
||||
"de.k4systems.asf": ["Freiburg im Breisgau"],
|
||||
"de.drekopf.abfallplaner": ["Drekopf"],
|
||||
"de.k4systems.unterallgaeu": [
|
||||
"Rottweil",
|
||||
"Tuttlingen",
|
||||
"Waldshut",
|
||||
"Frankfurt (Oder)",
|
||||
"Prignitz",
|
||||
],
|
||||
"de.k4systems.landshutlk": ["Kreis Landshut"],
|
||||
"de.k4systems.zakb": ["Kreis Bergstraße"],
|
||||
"de.k4systems.awrplus": ["Kreis Rotenburg (Wümme)"],
|
||||
"de.k4systems.lkmabfallplus": ["München Landkreis"],
|
||||
"de.k4systems.athosmobil": ["ATHOS GmbH"],
|
||||
"de.k4systems.willkommen": [],
|
||||
"de.idcontor.abfalllu": ["Ludwigshafen"],
|
||||
}
|
||||
|
||||
|
||||
def get_extra_info():
|
||||
for app, services in SUPPORTED_SERVICES.items():
|
||||
for service in services:
|
||||
app_name = app.split(".")[-1]
|
||||
if app_name == "abfallapp" or app_name == "app":
|
||||
app_name = app.split(".")[-2]
|
||||
if app_name == "abfallapp" or app_name == "app":
|
||||
app_name = ""
|
||||
yield {
|
||||
"title": service,
|
||||
"url": "Abfall+ App" + (": " + app.split(".")[-1]) if app_name else "",
|
||||
"country": "de",
|
||||
}
|
||||
|
||||
|
||||
def random_hex(length: int = 1) -> str:
|
||||
return "".join(random.choice("0123456789abcdef") for _ in range(length))
|
||||
|
||||
|
||||
API_BASE = "https://app.abfallplus.de/{}"
|
||||
API_ASSISTANT = API_BASE.format("assistent/{}") # ignore: E501
|
||||
|
||||
|
||||
def extract_onclicks(
|
||||
data: BeautifulSoup | str | requests.Response, hnr=False
|
||||
) -> list[list]:
|
||||
if isinstance(data, requests.Response):
|
||||
data = data.text
|
||||
if isinstance(data, str):
|
||||
data = BeautifulSoup(data, features="html.parser")
|
||||
|
||||
to_return = []
|
||||
for a in data.find_all("a"):
|
||||
onclick: str = a.attrs["onclick"].replace("('#f_ueberspringen').val('0')", "")
|
||||
start = onclick.find("(") + 1
|
||||
end = onclick.find("})") + 1
|
||||
string = ("[" + onclick[start:end] + "]").replace("'", '"')
|
||||
try:
|
||||
to_return.append(json.loads(string))
|
||||
except json.decoder.JSONDecodeError:
|
||||
raise Exception(f"Failed to parse '{string}', onclick: '{onclick}'")
|
||||
if hnr:
|
||||
res = re.search(r"\.val\([0-9]+\)", onclick)
|
||||
if res:
|
||||
to_return[-1].append(res.group()[5:-1])
|
||||
return to_return
|
||||
|
||||
|
||||
def compare(a, b, remove_space=False):
|
||||
if remove_space:
|
||||
a = a.replace(" ", "")
|
||||
b = b.replace(" ", "")
|
||||
return a.lower().strip() == b.lower().strip()
|
||||
|
||||
|
||||
class AppAbfallplusDe:
|
||||
def __init__(
|
||||
self,
|
||||
app_id,
|
||||
strasse,
|
||||
hnr=None,
|
||||
kommune=None,
|
||||
bundesland=None,
|
||||
landkreis=None,
|
||||
bundesland_id=None,
|
||||
landkreis_id=None,
|
||||
kommune_id=None,
|
||||
bezirk_id="",
|
||||
strasse_id=None,
|
||||
hnr_id=None,
|
||||
):
|
||||
self._client = (
|
||||
random_hex(8)
|
||||
+ "-"
|
||||
+ random_hex(4)
|
||||
+ "-"
|
||||
+ random_hex(4)
|
||||
+ "-"
|
||||
+ random_hex(4)
|
||||
+ "-"
|
||||
+ random_hex(12)
|
||||
)
|
||||
self._app_id = app_id
|
||||
self._session = requests.Session()
|
||||
self._bundesland_search = bundesland
|
||||
self._landkreis_search = landkreis
|
||||
self._region_search = kommune
|
||||
self._strasse_search = strasse
|
||||
self._hnr_search = hnr
|
||||
|
||||
self._hnr = hnr_id
|
||||
self._bundesland_id = bundesland_id
|
||||
self._landkreis_id = landkreis_id
|
||||
self._kommune_id = kommune_id
|
||||
self._bezirk_id = bezirk_id
|
||||
self._strasse_id = strasse_id
|
||||
|
||||
def _request(
|
||||
self,
|
||||
url_ending,
|
||||
base=API_ASSISTANT,
|
||||
data=None,
|
||||
params=None,
|
||||
method="post",
|
||||
headers=None,
|
||||
):
|
||||
if method not in ("get", "post"):
|
||||
raise Exception(f"Method {method} not supported.")
|
||||
if method == "get":
|
||||
r = self._session.get(
|
||||
base.format(url_ending), params=params, headers=headers
|
||||
)
|
||||
elif method == "post":
|
||||
r = self._session.post(
|
||||
base.format(url_ending), data=data, params=params, headers=headers
|
||||
)
|
||||
return r
|
||||
|
||||
def get_kom_or_lk_name(self) -> str | bool:
|
||||
"""Get the landkreis or kommune name if the app is designed for a specific one."""
|
||||
if self._kommune_id and "|" in self._kommune_id:
|
||||
if self._kommune_id.split("|")[0] != "0":
|
||||
return self._kommune_id.split("|")[-1]
|
||||
|
||||
if self._landkreis_id and "|" in self._landkreis_id:
|
||||
if self._landkreis_id and "|" in self._landkreis_id:
|
||||
if self._landkreis_id.split("|")[0] != "0":
|
||||
return self._landkreis_id.split("|")[-1]
|
||||
return False
|
||||
|
||||
def init_connection(self):
|
||||
data = {
|
||||
"client": self._client,
|
||||
"app_id": self._app_id,
|
||||
}
|
||||
self._request("config.xml", base=API_BASE, data=data).raise_for_status()
|
||||
r = self._request("login/", base=API_BASE, data=data)
|
||||
r.raise_for_status()
|
||||
soup = BeautifulSoup(r.text, features="html.parser")
|
||||
if not (inputs := soup.find_all("input")):
|
||||
return
|
||||
|
||||
for input in inputs:
|
||||
if input.attrs["name"] == "f_id_bundesland":
|
||||
self._bundesland_id = input.attrs["value"]
|
||||
elif input.attrs["name"] == "f_id_landkreis":
|
||||
self._landkreis_id = input.attrs["value"]
|
||||
elif input.attrs["name"] == "f_id_kommune":
|
||||
self._kommune_id = input.attrs["value"]
|
||||
|
||||
def get_bundeslaender(self):
|
||||
r = self._request("bundesland/", method="get")
|
||||
r.raise_for_status()
|
||||
bundeslaender = []
|
||||
for a in extract_onclicks(r):
|
||||
bundeslaender.append(
|
||||
{
|
||||
"id": [0],
|
||||
"name": a[1],
|
||||
}
|
||||
)
|
||||
return bundeslaender
|
||||
|
||||
def select_bundesland(self, bundesland=None):
|
||||
if bundesland:
|
||||
self._bundesland_search = bundesland
|
||||
for bundesland in self.get_bundeslaender():
|
||||
if compare(bundesland["name"], self._bundesland_search):
|
||||
self._bundesland_id = bundesland["id"]
|
||||
return
|
||||
|
||||
def get_landkreise(self):
|
||||
data = {"id_bundesland": self._bundesland_id}
|
||||
r = self._request("landkreis/", data=data)
|
||||
r.raise_for_status()
|
||||
landkreise = []
|
||||
for a in extract_onclicks(r):
|
||||
landkreise.append(
|
||||
{
|
||||
"id": a[0],
|
||||
"name": a[1],
|
||||
}
|
||||
)
|
||||
return landkreise
|
||||
|
||||
def select_landkreis(self, landkreis=None):
|
||||
if landkreis:
|
||||
self._landkreis_search = landkreis
|
||||
for landkreis in self.get_landkreise():
|
||||
if compare(landkreis["name"], self._landkreis_search):
|
||||
self._landkreis_id = landkreis["id"]
|
||||
return
|
||||
|
||||
def get_kommunen(self, region_key_name="kommune") -> list:
|
||||
data = {}
|
||||
if self._bundesland_id:
|
||||
data["id_bundesland"] = self._bundesland_id
|
||||
if self._landkreis_id:
|
||||
data["id_landkreis"] = self._landkreis_id
|
||||
# if self._kommune_id:
|
||||
# data["id_kommune"] = self._kommune_id
|
||||
r = self._request(region_key_name + "/", data=data)
|
||||
r.raise_for_status()
|
||||
regions = []
|
||||
for a in extract_onclicks(r):
|
||||
regions.append(
|
||||
{
|
||||
"id": a[0],
|
||||
"name": a[1],
|
||||
"bundesland_id": a[5].get("set_id_bundesland"),
|
||||
"landkreis_id": a[5].get("set_id_landkreis"),
|
||||
"kommune_id": a[5].get("set_id_kommune"),
|
||||
}
|
||||
)
|
||||
# name = a.text.strip()
|
||||
# id = a.attrs()["onclick"].split("'")[1]
|
||||
if region_key_name == "kommune" and regions == []:
|
||||
return self.get_kommunen("region")
|
||||
return regions
|
||||
|
||||
def select_kommune(self, kommune=None):
|
||||
if kommune:
|
||||
self._region_search = kommune
|
||||
|
||||
regions = self.get_kommunen()
|
||||
for region in regions:
|
||||
if compare(region["name"], self._region_search):
|
||||
if region["bundesland_id"] is not None:
|
||||
self._bundesland_id = region["bundesland_id"]
|
||||
if region["landkreis_id"] is not None:
|
||||
self._landkreis_id = region["landkreis_id"]
|
||||
self._region_id = region["id"]
|
||||
self._kommune_id = (
|
||||
region["kommune_id"]
|
||||
if region["kommune_id"] is not None
|
||||
else region["id"]
|
||||
)
|
||||
return
|
||||
|
||||
raise Exception(f"Region {self._region_search} not found.")
|
||||
|
||||
def get_streets(self, search=None):
|
||||
if search:
|
||||
self._strasse_search = search
|
||||
|
||||
data = {
|
||||
"id_landkreis": self._landkreis_id,
|
||||
"id_bezirk": self._bezirk_id,
|
||||
"id_kommune": self._kommune_id,
|
||||
"id_kommune_qry": self._kommune_id,
|
||||
"strasse_qry": self._strasse_search,
|
||||
}
|
||||
|
||||
r = self._request("strasse/", data=data)
|
||||
r.raise_for_status()
|
||||
streets = []
|
||||
for a in extract_onclicks(r):
|
||||
streets.append(
|
||||
{
|
||||
"id": a[0],
|
||||
"name": a[1],
|
||||
"id_kommune": a[5]["set_id_kommune"]
|
||||
if "set_id_kommune" in a[5]
|
||||
else None,
|
||||
"id_beirk": a[5]["set_id_bezirk"]
|
||||
if "set_id_bezirk" in a[5]
|
||||
else None,
|
||||
"hrns": a[3] != "fertig",
|
||||
}
|
||||
)
|
||||
return streets
|
||||
|
||||
def select_street(self, street=None):
|
||||
if street:
|
||||
self._strasse_search = street
|
||||
for street in self.get_streets():
|
||||
if compare(street["name"], self._strasse_search):
|
||||
self._f_id_strasse = self._strasse_id = street["id"]
|
||||
if street["id_kommune"] is not None:
|
||||
self._kommune_id = street["id_kommune"]
|
||||
if street["id_beirk"] is not None:
|
||||
self._bezirk_id = street["id_beirk"]
|
||||
self._hnrs = street["hrns"]
|
||||
return
|
||||
raise Exception(f"Street {self._strasse_search} not found.")
|
||||
|
||||
def get_hrn_needed(self) -> bool:
|
||||
return self._hnrs
|
||||
|
||||
def get_hnrs(self):
|
||||
data = {
|
||||
"id_landkreis": self._landkreis_id,
|
||||
"id_kommune": self._kommune_id,
|
||||
"id_bezirk": self._bezirk_id if self._bezirk_id else "",
|
||||
"id_strasse": self._strasse_id,
|
||||
}
|
||||
|
||||
r = self._request(
|
||||
"hnr/",
|
||||
data=data,
|
||||
headers={
|
||||
"content-type": "application/x-www-form-urlencoded; charset=UTF-8"
|
||||
},
|
||||
)
|
||||
hnrs = []
|
||||
for a in extract_onclicks(r, hnr=True):
|
||||
hnrs.append(
|
||||
{
|
||||
"id": a[0],
|
||||
"name": a[0].split("|")[0],
|
||||
"f_id_strasse": a[6] if len(a) > 6 else None,
|
||||
}
|
||||
)
|
||||
return hnrs
|
||||
|
||||
def select_hnr(self, hnr=None):
|
||||
if hnr:
|
||||
self._hnr_search = hnr
|
||||
for hnr in self.get_hnrs():
|
||||
if compare(hnr["name"], self._hnr_search, remove_space=True):
|
||||
self._hnr = hnr["id"]
|
||||
if hnr["f_id_strasse"] is not None:
|
||||
self._f_id_strasse = hnr["f_id_strasse"]
|
||||
return
|
||||
raise Exception(f"HNR {self._hnr_search} not found.")
|
||||
|
||||
def select_all_waste_types(self):
|
||||
data = {
|
||||
"f_id_region": self._region_id if hasattr(self, "_region_id") else "",
|
||||
"f_id_bundesland": self._bundesland_id,
|
||||
"f_id_landkreis": self._landkreis_id,
|
||||
"f_id_kommune": self._kommune_id,
|
||||
"f_id_bezirk": "", # self._bezirk_id,
|
||||
"f_id_strasse": self._f_id_strasse,
|
||||
"f_hnr": self._hnr,
|
||||
"f_kdnr": "",
|
||||
}
|
||||
r = self._request("abfallarten/", data=data)
|
||||
r.raise_for_status()
|
||||
soup = BeautifulSoup(r.text, features="html.parser")
|
||||
self._f_id_abfallart = []
|
||||
for input in soup.find_all("input", {"name": "f_id_abfallart[]"}):
|
||||
self._f_id_abfallart.append(input.attrs["value"])
|
||||
|
||||
def validate(self):
|
||||
data = {
|
||||
# "f_id_region": self._region_id if hasattr(self, "_region_id") else "",
|
||||
"f_id_bundesland": self._bundesland_id,
|
||||
"f_id_landkreis": self._landkreis_id,
|
||||
"f_id_kommune": self._kommune_id,
|
||||
"f_id_bezirk": "", # self._bezirk_id,
|
||||
"f_id_strasse": self._f_id_strasse,
|
||||
"f_hnr": self._hnr,
|
||||
"f_kdnr": "",
|
||||
"f_id_abfallart[]": self._f_id_abfallart,
|
||||
"f_uhrzeit_tag": "86400|0",
|
||||
"f_uhrzeit_stunden": 54000,
|
||||
"f_uhrzeit_minuten": 600,
|
||||
"f_anonym": 1,
|
||||
"f_ausgangspunkt": 1,
|
||||
"f_ueberspringen": 0,
|
||||
}
|
||||
|
||||
r = self._request("ueberpruefen/", data=data)
|
||||
r.raise_for_status()
|
||||
data["f_datenschutz"] = datetime.now().strftime("%Y%m%d%H%M%S")
|
||||
r = self._request("finish/", data=data)
|
||||
r.raise_for_status()
|
||||
|
||||
def get_collections(self) -> list[dict[str, date | str]]:
|
||||
"""Get collections for the selected address as a list of dicts.
|
||||
|
||||
Returns:
|
||||
list[dict[str, date|str]]: all collection dates
|
||||
"""
|
||||
r = self._request(
|
||||
"version.xml",
|
||||
base=API_BASE,
|
||||
data={"client": self._client, "app_id": self._app_id},
|
||||
)
|
||||
r = self._request(
|
||||
"version.xml",
|
||||
params={"renew": 1},
|
||||
base=API_BASE,
|
||||
data={"client": self._client, "app_id": self._app_id},
|
||||
)
|
||||
r = self._request(
|
||||
"struktur.xml.zip",
|
||||
base=API_BASE,
|
||||
data={"client": self._client, "app_id": self._app_id},
|
||||
)
|
||||
r.raise_for_status()
|
||||
|
||||
soup = BeautifulSoup(r.text, "xml")
|
||||
categories = {}
|
||||
for category in (
|
||||
soup.find("key", text="categories")
|
||||
.find_next_sibling("array")
|
||||
.find_all("dict")
|
||||
):
|
||||
id = category.find("key", text="id").find_next_sibling("string").text
|
||||
name = (
|
||||
category.find("key", text="name")
|
||||
.find_next_sibling("string")
|
||||
.text.replace("![CDATA[", "")
|
||||
.replace("]]", "")
|
||||
.strip()
|
||||
)
|
||||
categories[id] = name
|
||||
|
||||
collections: list[dict] = []
|
||||
for collection in (
|
||||
soup.find("key", text="dates").find_next_sibling("array").find_all("dict")
|
||||
):
|
||||
category = (
|
||||
collection.find("key", text="category_id")
|
||||
.find_next_sibling("string")
|
||||
.text
|
||||
)
|
||||
category_name = categories[category]
|
||||
pickup_date_str = (
|
||||
collection.find("key", text="pickup_date")
|
||||
.find_next_sibling("string")
|
||||
.text
|
||||
)
|
||||
pickup_date = datetime.strptime(
|
||||
pickup_date_str, "%Y-%m-%dT%H:%M:%S%z"
|
||||
).date()
|
||||
|
||||
collections.append({"category": category_name, "date": pickup_date})
|
||||
|
||||
return collections
|
||||
|
||||
def generate_calendar(self) -> list[dict[str, date | str]]:
|
||||
"""Run all necessary function and return the output of get_collections.
|
||||
|
||||
Returns:
|
||||
list[dict[str, date|str]]: all collection dates
|
||||
"""
|
||||
self.init_connection()
|
||||
if self._bundesland_search:
|
||||
self.select_bundesland()
|
||||
if self._landkreis_search:
|
||||
self.select_landkreis()
|
||||
if self._region_search:
|
||||
self.select_kommune()
|
||||
self.select_street()
|
||||
if self._hnrs and self._hnr_search is not None:
|
||||
self.select_hnr()
|
||||
self.select_all_waste_types()
|
||||
self.validate()
|
||||
return self.get_collections()
|
||||
|
||||
def test(self):
|
||||
print(self.generate_calendar())
|
||||
|
||||
def get_suppoted_by_bl(self):
|
||||
supported = []
|
||||
for i in range(1, 17):
|
||||
r = self._request("landkreis/", data={"id_bundesland": i})
|
||||
r.raise_for_status()
|
||||
soup = BeautifulSoup(r.text, features="html.parser")
|
||||
|
||||
for a in soup.find_all("a"):
|
||||
if "gibt es bereits eine eigene App" in str(a):
|
||||
continue
|
||||
if "Dieser Landkreis wird aktuell nicht unterstützt" in str(a):
|
||||
continue
|
||||
if "in Kürze unterstützt." in str(a):
|
||||
continue
|
||||
supported.append(a.text.strip())
|
||||
return supported
|
||||
|
||||
def clear(self, above):
|
||||
if above >= 4:
|
||||
self._bundesland_id = None
|
||||
if above >= 3:
|
||||
self._landkreis_id = None
|
||||
if above >= 2:
|
||||
self._kommune_id = None
|
||||
if above >= 1:
|
||||
self._bezirk_id = None
|
||||
self._strasse_id = None
|
||||
if above >= 0:
|
||||
self._hnr = None
|
||||
self._hnr_id = None
|
||||
|
||||
def debug(self):
|
||||
r = "AppAbfallplusDe("
|
||||
r += f"""app_id={self._app_id},
|
||||
hnr={self._hnr},
|
||||
bundesland_id={self._bundesland_id},
|
||||
landkreis_id={self._landkreis_id},
|
||||
kommune_id={self._kommune_id},
|
||||
bezirk_id={self._bezirk_id},
|
||||
strasse_id={self._strasse_id}
|
||||
-- SEARCH --
|
||||
(
|
||||
bundesland_search={self._bundesland_search},
|
||||
landkreis_search={self._landkreis_search},
|
||||
region_search={self._region_search},
|
||||
strasse_search={self._strasse_search},
|
||||
hnr_search={self._hnr_search},
|
||||
)
|
||||
"""
|
||||
return r + ")"
|
||||
|
||||
|
||||
def generate_supported_services(suppoted_apps=SUPPORTED_APPS):
|
||||
supported_services = {}
|
||||
for index, app_id in enumerate(suppoted_apps):
|
||||
print(f"starting {index+1}/{len(suppoted_apps)}: {app_id}")
|
||||
supported_services[app_id] = []
|
||||
app = AppAbfallplusDe(app_id, "", "", "")
|
||||
app.init_connection()
|
||||
if name := app.get_kom_or_lk_name():
|
||||
supported_services[app_id].append(name)
|
||||
continue
|
||||
print(json.dumps(supported_services, indent=4, ensure_ascii=False))
|
||||
|
||||
for region in app.get_kommunen():
|
||||
supported_services[app_id].append(region["name"])
|
||||
|
||||
if supported_services[app_id] == []:
|
||||
supported_services[app_id].extend(app.get_suppoted_by_bl())
|
||||
|
||||
print(json.dumps(supported_services, indent=4, ensure_ascii=False))
|
||||
print("\n\n\nFINAL:" + json.dumps(supported_services, indent=4, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_supported_services()
|
||||
# app = AppAbfallplusDe("de.albagroup.app", "Braunschweig", "Hauptstraße", "7A")
|
||||
# app.test()
|
||||
@@ -0,0 +1,114 @@
|
||||
import waste_collection_schedule.service.AppAbfallplusDe as AppAbfallplusDe
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
SUPPORTED_SERVICES = AppAbfallplusDe.SUPPORTED_SERVICES
|
||||
EXTRA_INFO = AppAbfallplusDe.get_extra_info
|
||||
TITLE = "Apps by Abfall+"
|
||||
DESCRIPTION = "Source for Apps by Abfall+."
|
||||
URL = "https://www.abfallplus.de/"
|
||||
TEST_CASES = {
|
||||
"de.albagroup.app Braunschweig Hauptstraße 7A ": {
|
||||
"app_id": "de.albagroup.app",
|
||||
"city": "Braunschweig",
|
||||
"strasse": "Hauptstraße",
|
||||
"hnr": "7A",
|
||||
},
|
||||
"de.k4systems.bonnorange Auf dem Hügel": {
|
||||
"app_id": "de.k4systems.bonnorange",
|
||||
"strasse": "Auf dem Hügel",
|
||||
"hnr": "6",
|
||||
},
|
||||
"de.ucom.abfallavr Brühl Habichtstr. 4A": {
|
||||
"app_id": "de.ucom.abfallavr",
|
||||
"strasse": "Habichtstr.",
|
||||
"hnr": "4A",
|
||||
"city": "Brühl",
|
||||
},
|
||||
"de.k4systems.abfallappwug Bergen hauptstr. 1": {
|
||||
"app_id": "de.k4systems.abfallappwug",
|
||||
"strasse": "Alle Straßen",
|
||||
"city": "Bergen",
|
||||
},
|
||||
# MORE TEST CASES UNCOMMENT IF NEEDED FOR DEBUGGING
|
||||
# "de.k4systems.zakb Fürth Ahornweg 3 A": {
|
||||
# "app_id": "de.k4systems.zakb",
|
||||
# "strasse": "Ahornweg",
|
||||
# "hnr": "3 A",
|
||||
# "city": "Fürth",
|
||||
# },
|
||||
# "de.k4systems.avea Leverkusen Haberstr.": {
|
||||
# "app_id": "de.k4systems.avea",
|
||||
# "strasse": "Haberstr.",
|
||||
# "city": "Leverkusen",
|
||||
# },
|
||||
# "de.k4systems.abfallappog Bad Peterstal-Griesbach alle Straßen": {
|
||||
# "app_id": "de.k4systems.abfallappog",
|
||||
# "strasse": "Alle Straßen",
|
||||
# "city": "Bad Peterstal-Griesbach",
|
||||
# },
|
||||
# "de.k4systems.abfallappfuerth Großhabersdorf Am Dürren Grund 1 a": {
|
||||
# "app_id": "de.k4systems.abfallappfuerth",
|
||||
# "strasse": "Am Dürren Grund",
|
||||
# "hnr": "1 a",
|
||||
# "city": "Großhabersdorf",
|
||||
# },
|
||||
# "de.k4systems.awbgp Bad Boll Ahornstraße Alle Hausnummern": {
|
||||
# "app_id": "de.k4systems.awbgp",
|
||||
# "strasse": "Ahornstraße",
|
||||
# "hnr": "Alle Hausnummern",
|
||||
# "city": "Bad Boll",
|
||||
# }
|
||||
}
|
||||
|
||||
|
||||
ICON_MAP = {
|
||||
"restmüll": "mdi:trash-can",
|
||||
"schwarz": "mdi:trash-can",
|
||||
"grau": "mdi:trash-can",
|
||||
"glass": "mdi:bottle-soda",
|
||||
"bio": "mdi:leaf",
|
||||
"braun": "mdi:leaf",
|
||||
"pappier": "mdi:package-variant",
|
||||
"blaue tonne": "mdi:package-variant",
|
||||
"plastik": "mdi:recycle",
|
||||
"wertstoff": "mdi:recycle",
|
||||
"gelber sack": "mdi:recycle",
|
||||
}
|
||||
|
||||
|
||||
API_URL = ""
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(
|
||||
self,
|
||||
app_id: str,
|
||||
strasse: str,
|
||||
hnr: str | int | None = None,
|
||||
city: str = None,
|
||||
bundesland: str = None,
|
||||
landkreis: str = None,
|
||||
):
|
||||
self._app = AppAbfallplusDe.AppAbfallplusDe(
|
||||
app_id=app_id,
|
||||
kommune=city,
|
||||
strasse=strasse,
|
||||
hnr=hnr,
|
||||
bundesland=bundesland,
|
||||
landkreis=landkreis,
|
||||
)
|
||||
|
||||
def fetch(self):
|
||||
entries = []
|
||||
for d in self._app.generate_calendar():
|
||||
bin_type = d["category"]
|
||||
icon = None
|
||||
for name, icon_str in ICON_MAP.items():
|
||||
if name in bin_type.lower():
|
||||
icon = icon_str
|
||||
break
|
||||
|
||||
# Collection icon
|
||||
entries.append(Collection(date=d["date"], t=bin_type, icon=icon))
|
||||
|
||||
return entries
|
||||
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python3
|
||||
import site
|
||||
from pathlib import Path
|
||||
|
||||
import inquirer
|
||||
|
||||
package_dir = Path(__file__).resolve().parents[2]
|
||||
site.addsitedir(str(package_dir))
|
||||
import waste_collection_schedule.service.AppAbfallplusDe as AppAbfallplusDe # noqa: E402
|
||||
|
||||
YAML = """
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: {app_id}
|
||||
city: {city}
|
||||
strasse: {strasse}
|
||||
hnr: {hnr}
|
||||
"""
|
||||
|
||||
bundesland = None
|
||||
landkreis = None
|
||||
city = None
|
||||
street = None
|
||||
house_number = None
|
||||
|
||||
|
||||
def select_bundesland(app: AppAbfallplusDe.AppAbfallplusDe):
|
||||
bundeslaender = app.get_bundeslaender()
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"bundesland",
|
||||
choices=[(s["name"], s["name"]) for s in bundeslaender],
|
||||
message="Select your Bundesland",
|
||||
)
|
||||
]
|
||||
bundesland = inquirer.prompt(questions)["bundesland"]
|
||||
app.select_bundesland(bundesland)
|
||||
return bundesland
|
||||
|
||||
|
||||
def select_landkreis(app: AppAbfallplusDe.AppAbfallplusDe):
|
||||
landkreise = app.get_landkreise()
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"landkreis",
|
||||
choices=[(s["name"], s["name"]) for s in landkreise] + [("BACK", "BACK")],
|
||||
message="Select your Landkreis",
|
||||
)
|
||||
]
|
||||
landkreis = inquirer.prompt(questions)["landkreis"]
|
||||
if landkreis == "BACK":
|
||||
app.clear(0)
|
||||
select_bundesland(app)
|
||||
return select_landkreis(app)
|
||||
app.select_landkreis(landkreis)
|
||||
return landkreis
|
||||
|
||||
|
||||
def select_city(app: AppAbfallplusDe.AppAbfallplusDe, bund_select: bool):
|
||||
cities = app.get_kommunen()
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"city",
|
||||
choices=[(s["name"], s["name"]) for s in cities]
|
||||
+ ([("BACK", "BACK")] if bund_select else []),
|
||||
message="Select your Kommune",
|
||||
)
|
||||
]
|
||||
city = inquirer.prompt(questions)["city"]
|
||||
if city == "BACK":
|
||||
app.clear(1)
|
||||
select_landkreis(app)
|
||||
return select_city(app, bund_select)
|
||||
|
||||
app.select_kommune(city)
|
||||
return city
|
||||
|
||||
|
||||
def select_street(app: AppAbfallplusDe.AppAbfallplusDe, bund_select: bool):
|
||||
street = None
|
||||
street_search = ""
|
||||
while street is None:
|
||||
questions = [
|
||||
inquirer.Text(
|
||||
"street_search",
|
||||
message="Search your street you will be given some options to choose from",
|
||||
default=street_search,
|
||||
)
|
||||
]
|
||||
streets = app.get_streets(inquirer.prompt(questions)["street_search"])
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"street",
|
||||
choices=[(s["name"], s["name"]) for s in streets] + [("BACK", "BACK")],
|
||||
message="Select your Street",
|
||||
)
|
||||
]
|
||||
street = inquirer.prompt(questions)["street"]
|
||||
if street == "BACK":
|
||||
street = None
|
||||
|
||||
if street == "BACK":
|
||||
app.clear(2)
|
||||
select_city(app, bund_select)
|
||||
return select_street(app, bund_select)
|
||||
|
||||
app.select_street(street)
|
||||
return street
|
||||
|
||||
|
||||
def select_house_number(app: AppAbfallplusDe.AppAbfallplusDe, bund_select: bool):
|
||||
house_numbers = app.get_hnrs()
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"house_number",
|
||||
choices=[(s["name"], s["name"]) for s in house_numbers]
|
||||
+ [("BACK", "BACK")],
|
||||
message="Select your House Number",
|
||||
)
|
||||
]
|
||||
house_number = inquirer.prompt(questions)["house_number"]
|
||||
if house_number == "BACK":
|
||||
app.clear(3)
|
||||
select_street(app, bund_select)
|
||||
return select_house_number(app, bund_select)
|
||||
app.select_hnr(house_number)
|
||||
return house_number
|
||||
|
||||
|
||||
def main():
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"app-id",
|
||||
choices=[(s, s) for s in AppAbfallplusDe.SUPPORTED_APPS],
|
||||
message="Select your App",
|
||||
)
|
||||
]
|
||||
app_id = inquirer.prompt(questions)["app-id"]
|
||||
|
||||
app = AppAbfallplusDe.AppAbfallplusDe(app_id, "", "", "")
|
||||
app.init_connection()
|
||||
cities = app.get_kommunen()
|
||||
bund_select = cities == []
|
||||
|
||||
bundesland = landkreis = None
|
||||
if bund_select:
|
||||
bundesland = select_bundesland(app)
|
||||
landkreis = select_landkreis(app)
|
||||
# cities = app.get_kommunen()
|
||||
|
||||
city = select_city(app, bund_select)
|
||||
street = select_street(app, bund_select)
|
||||
if app.get_hrn_needed():
|
||||
house_number = select_house_number(app, bund_select)
|
||||
else:
|
||||
house_number = ""
|
||||
|
||||
yaml = YAML.format(
|
||||
app_id=app_id,
|
||||
city=city,
|
||||
strasse=street,
|
||||
hnr=house_number,
|
||||
)
|
||||
if bundesland:
|
||||
yaml += " bundesland=bundesland,\n"
|
||||
if landkreis:
|
||||
yaml += " landkreis=landkreis,\n"
|
||||
|
||||
print(yaml)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
45
custom_components/waste_collection_schedule/waste_collection_schedule/wizard/citiesapps_com.py
Normal file → Executable file
45
custom_components/waste_collection_schedule/waste_collection_schedule/wizard/citiesapps_com.py
Normal file → Executable file
@@ -1,21 +1,27 @@
|
||||
from waste_collection_schedule.service.CitiesAppsCom import CitiesApps
|
||||
import inquirer
|
||||
#!/usr/bin/env python3
|
||||
import site
|
||||
from pathlib import Path
|
||||
|
||||
import inquirer
|
||||
|
||||
package_dir = Path(__file__).resolve().parents[2]
|
||||
site.addsitedir(str(package_dir))
|
||||
|
||||
app = CitiesApps()
|
||||
import waste_collection_schedule.service.CitiesAppsCom as CitiesAppsCom # noqa: E402
|
||||
|
||||
app = CitiesAppsCom.CitiesApps()
|
||||
|
||||
|
||||
def ask_city():
|
||||
cities = app.get_cities()
|
||||
cities.sort(key=lambda d: d['name'])
|
||||
cities.sort(key=lambda d: d["name"])
|
||||
|
||||
questions = [
|
||||
inquirer.List("city",
|
||||
choices=[(c["name"], c["_id"]) for c in cities], message="Select a city"
|
||||
)
|
||||
inquirer.List(
|
||||
"city",
|
||||
choices=[(c["name"], c["_id"]) for c in cities],
|
||||
message="Select a city",
|
||||
)
|
||||
]
|
||||
city_id = inquirer.prompt(questions)["city"]
|
||||
city = [c["name"] for c in cities if c["_id"] == city_id][0]
|
||||
@@ -34,7 +40,12 @@ def ask_calendar(city_id, allow_search=True):
|
||||
if allow_search:
|
||||
choices = ["Search By Street", *choices]
|
||||
questions = [
|
||||
inquirer.List("cal", choices=choices, message="Select a calendar", default="Search By Street")
|
||||
inquirer.List(
|
||||
"cal",
|
||||
choices=choices,
|
||||
message="Select a calendar",
|
||||
default="Search By Street",
|
||||
)
|
||||
]
|
||||
cal = inquirer.prompt(questions)["cal"]
|
||||
return cal
|
||||
@@ -48,12 +59,14 @@ def ask_by_street(city_id):
|
||||
|
||||
streetlist = streets["streets"]
|
||||
|
||||
streetlist.sort(key=lambda d: d['full_names'])
|
||||
calendars = {s_cal["garbage_areaid"]: s_cal["name"] for s_cal in streets["calendars"]}
|
||||
choices = [(" ".join(c["full_names"]), calendars[c["areaids"][0]]) for c in streetlist]
|
||||
questions = [
|
||||
inquirer.List("cal", choices=choices, message="Select a street")
|
||||
streetlist.sort(key=lambda d: d["full_names"])
|
||||
calendars = {
|
||||
s_cal["garbage_areaid"]: s_cal["name"] for s_cal in streets["calendars"]
|
||||
}
|
||||
choices = [
|
||||
(" ".join(c["full_names"]), calendars[c["areaids"][0]]) for c in streetlist
|
||||
]
|
||||
questions = [inquirer.List("cal", choices=choices, message="Select a street")]
|
||||
return inquirer.prompt(questions)["cal"]
|
||||
|
||||
|
||||
@@ -64,12 +77,14 @@ def main():
|
||||
if cal == "Search By Street":
|
||||
cal = ask_by_street(city_id)
|
||||
|
||||
print(f"""waste_collection_schedule:
|
||||
print(
|
||||
f"""waste_collection_schedule:
|
||||
sources:
|
||||
- name: citiesapps_com
|
||||
args:
|
||||
city: {city}
|
||||
calendar: {cal}""")
|
||||
calendar: {cal}"""
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
197
doc/source/app_abfallplus_de.md
Normal file
197
doc/source/app_abfallplus_de.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Apps by Abfall+
|
||||
|
||||
Support for schedules provided by [Apps by Abfall+](https://www.abfallplus.de/), serving multiple, Germany.
|
||||
|
||||
## Configuration via configuration.yaml
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: APP ID
|
||||
city: STADT/KOMMUNE
|
||||
strasse: STRASSE
|
||||
hnr: HAUSNUMMER
|
||||
bundesland: BUNDESLAND
|
||||
landkreis: LANDKREIS
|
||||
|
||||
```
|
||||
|
||||
### Configuration Variables
|
||||
|
||||
**app_id**
|
||||
*(String) (required)*
|
||||
|
||||
**city**
|
||||
*(String) (optional)*
|
||||
|
||||
**strasse**
|
||||
*(String) (required)*
|
||||
|
||||
**hnr**
|
||||
*(String | Integer) (optional)*
|
||||
|
||||
**bundesland**
|
||||
*(String) (optional)*
|
||||
|
||||
**landkreis**
|
||||
*(String) (optional)*
|
||||
|
||||
## Examples
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: de.albagroup.app
|
||||
city: Braunschweig
|
||||
strasse: Hauptstraße
|
||||
hnr: 7A
|
||||
```
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: de.k4systems.bonnorange
|
||||
strasse: Auf dem Hügel
|
||||
hnr: 6
|
||||
```
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: de.k4systems.abfallappwug
|
||||
city: Bergen
|
||||
strasse: Alle Straßen
|
||||
```
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: app_abfallplus_de
|
||||
args:
|
||||
app_id: de.k4systems.awbgp
|
||||
city: Bad Boll
|
||||
hnr: Alle Hausnummern
|
||||
strasse: Ahornstraße
|
||||
```
|
||||
|
||||
## How to get the source argument
|
||||
|
||||
Use the app of your local provider and select your address. Provide all arguments that are requested by the app.
|
||||
|
||||
If you do not want to install a App you can run the script located at custom_components/waste_collection_schedule/waste_collection_schedule/wizard/app_abfallplus_de.py make sure that the python package inquirer is installed (`pip install inquirer`)
|
||||
|
||||
The app_id can be found from the url of the play store entry: https://play.google.com/store/apps/details?id={app_id} or from the following table:
|
||||
|
||||
<!--Begin of service section-->
|
||||
|app_id|supported regions|
|
||||
|-|-|
|
||||
| de.albagroup.app | Berlin, Braunschweig, Havelland, Oberhavel, Ostprignitz-Ruppin, Tübingen |
|
||||
| de.k4systems.abfallinfocw | Kreis Calw |
|
||||
| de.k4systems.abfallinfoapp | Mechernich und Kommunen |
|
||||
| de.k4systems.abfallappes | Landkreis Esslingen |
|
||||
| de.k4systems.egst | Kreis Steinfurt |
|
||||
| de.idcontor.abfallwbd | Duisburg |
|
||||
| de.ucom.abfallavr | Rhein-Neckar-Kreis |
|
||||
| de.k4systems.abfallapprv | Kreis Ravensburg |
|
||||
| de.k4systems.avlserviceplus | Kreis Ludwigsburg |
|
||||
| de.k4systems.muellalarm | Schönmackers |
|
||||
| de.k4systems.abfallapploe | Kreis Lörrach |
|
||||
| de.k4systems.abfallappart | Kreis Trier-Saarburg |
|
||||
| de.k4systems.abfallapp | Kreis Augsburg |
|
||||
| de.k4systems.abfallappvorue | Kreis Vorpommern-Rügen |
|
||||
| de.k4systems.abfallappfds | Kreis Freudenstadt |
|
||||
| de.k4systems.abfallscout | Kreis Bad Kissingen |
|
||||
| de.k4systems.avea | Leverkusen |
|
||||
| de.k4systems.neustadtaisch | Kreis Neustadt/Aisch-Bad Windsheim |
|
||||
| de.k4systems.abfalllkswp | Kreis Südwestpfalz |
|
||||
| de.k4systems.awbemsland | Kreis Emsland |
|
||||
| de.k4systems.abfallappclp | Kreis Cloppenburg |
|
||||
| de.k4systems.abfallappnf | Kreis Nordfriesland |
|
||||
| de.k4systems.abfallappog | Ortenaukreis |
|
||||
| de.k4systems.abfallappmol | Kreis Märkisch-Oderland |
|
||||
| de.k4systems.kufiapp | Landkreis Wunsiedel im Fichtelgebirge |
|
||||
| de.k4systems.abfalllkbz | Kreis Bautzen |
|
||||
| de.k4systems.abfallappbb | Landkreis Böblingen |
|
||||
| de.k4systems.abfallappla | Landshut |
|
||||
| de.k4systems.abfallappwug | Kreis Weißenburg-Gunzenhausen |
|
||||
| de.k4systems.abfallappik | Ilm-Kreis |
|
||||
| de.k4systems.leipziglk | Landkreis Leipzig |
|
||||
| de.k4systems.abfallappbk | Bad Kissingen |
|
||||
| de.cmcitymedia.hokwaste | Hohenlohekreis |
|
||||
| de.abfallwecker | Rottweil, Tuttlingen, Waldshut, Prignitz, Nordsachsen |
|
||||
| de.k4systems.abfallappka | Kreis Karlsruhe |
|
||||
| de.k4systems.lkgoettingen | Abfallwirtschaft Altkreis Göttingen, Abfallwirtschaft Altkreis Osterode am Harz |
|
||||
| de.k4systems.abfallappcux | Kreis Cuxhaven |
|
||||
| de.k4systems.abfallslk | Salzlandkreis |
|
||||
| de.k4systems.abfallappzak | ZAK Kempten |
|
||||
| de.zawsr | ZAW-SR Straubing |
|
||||
| de.k4systems.teamorange | Kreis Würzburg |
|
||||
| de.k4systems.abfallappvivo | Kreis Miesbach |
|
||||
| de.k4systems.lkgr | Landkreis Görlitz |
|
||||
| de.k4systems.zawdw | AWG Donau-Wald |
|
||||
| de.k4systems.abfallappgib | Kreis Wesermarsch |
|
||||
| de.k4systems.wuerzburg | Würzburg |
|
||||
| de.k4systems.abfallappgap | Kreis Garmisch-Partenkirchen |
|
||||
| de.k4systems.bonnorange | Bonn |
|
||||
| de.gimik.apps.muellwecker_neuwied | Kreis Neuwied |
|
||||
| abfallH.ucom.de | Kreis Heilbronn |
|
||||
| de.k4systems.abfallappts | Kreis Traunstein |
|
||||
| de.k4systems.awa | Augsburg |
|
||||
| de.k4systems.abfallappfuerth | Kreis Fürth |
|
||||
| de.k4systems.abfallwelt | Kreis Kitzingen |
|
||||
| de.k4systems.lkemmendingen | Kreis Emmendingen |
|
||||
| de.k4systems.abfallkreisrt | Kreis Reutlingen |
|
||||
| de.k4systems.abfallappmetz | Metzingen |
|
||||
| de.k4systems.abfallappmyk | Kreis Mayen-Koblenz |
|
||||
| de.k4systems.abfallappoal | Kreis Ostallgäu |
|
||||
| de.k4systems.regioentsorgung | RegioEntsorgung AöR |
|
||||
| de.k4systems.abfalllkbt | Kreis Bayreuth |
|
||||
| de.k4systems.awvapp | Kreis Vechta |
|
||||
| de.k4systems.aevapp | Schwarze Elster |
|
||||
| de.k4systems.awbgp | Kreis Göppingen |
|
||||
| de.k4systems.abfallhr | ALF Lahn-Fulda |
|
||||
| de.k4systems.abfallappbh | Kreis Breisgau-Hochschwarzwald |
|
||||
| de.k4systems.awgbassum | Kreis Diepholz |
|
||||
| de.data_at_work.aws | Kreis Schaumburg |
|
||||
| de.k4systems.hebhagen | Hagen |
|
||||
| de.k4systems.meinawblm | Kreis Limburg-Weilburg |
|
||||
| de.k4systems.abfallmsp | Landkreis Main-Spessart |
|
||||
| de.k4systems.asoapp | Kreis Osterholz |
|
||||
| de.k4systems.awistasta | Kreis Starnberg |
|
||||
| de.ucom.abfallebe | Essen |
|
||||
| de.k4systems.bawnapp | Kreis Nienburg / Weser |
|
||||
| de.k4systems.abfallappol | Oldenburg |
|
||||
| de.k4systems.awbrastatt | Kreis Rastatt |
|
||||
| de.k4systems.abfallappmil | Kreis Miltenberg |
|
||||
| de.k4systems.abfallsbk | Schwarzwald-Baar-Kreis |
|
||||
| de.k4systems.wabapp | Westerwaldkreis |
|
||||
| abfallMA.ucom.de | Mannheim |
|
||||
| de.k4systems.llabfallapp | Kreis Landsberg am Lech |
|
||||
| de.k4systems.lkruelzen | Kreis Uelzen |
|
||||
| de.k4systems.abfallzak | Zollernalbkreis |
|
||||
| de.k4systems.abfallappno | Neckar-Odenwald-Kreis |
|
||||
| de.k4systems.udb | Burgenland (Landkreis) |
|
||||
| de.k4systems.abfallappsig | Kreis Sigmaringen |
|
||||
| de.k4systems.asf | Freiburg im Breisgau |
|
||||
| de.drekopf.abfallplaner | Drekopf |
|
||||
| de.k4systems.unterallgaeu | Rottweil, Tuttlingen, Waldshut, Frankfurt (Oder), Prignitz |
|
||||
| de.k4systems.landshutlk | Kreis Landshut |
|
||||
| de.k4systems.zakb | Kreis Bergstraße |
|
||||
| de.k4systems.awrplus | Kreis Rotenburg (Wümme) |
|
||||
| de.k4systems.lkmabfallplus | München Landkreis |
|
||||
| de.k4systems.athosmobil | ATHOS GmbH |
|
||||
| de.k4systems.willkommen | |
|
||||
| de.idcontor.abfalllu | Ludwigshafen |
|
||||
<!--End of service section-->
|
||||
|
||||
## Note
|
||||
|
||||
Not all apps are extensively tested and some apps may have not edge cases taken into account. If you encounter any Errors feel free to open a new issue here: <https://github.com/mampfes/hacs_waste_collection_schedule/issues>
|
||||
@@ -119,6 +119,7 @@ def browse_sources():
|
||||
update_awido_de(modules)
|
||||
update_ctrace_de(modules)
|
||||
update_citiesapps_com(modules)
|
||||
update_app_abfallplus_de(modules)
|
||||
|
||||
return sources
|
||||
|
||||
@@ -318,6 +319,21 @@ def update_citiesapps_com(modules):
|
||||
_patch_file("doc/source/citiesapps_com.md", "service", str)
|
||||
|
||||
|
||||
def update_app_abfallplus_de(modules):
|
||||
module = modules.get("app_abfallplus_de")
|
||||
if not module:
|
||||
print("app_abfallplus_de not found")
|
||||
return
|
||||
services = getattr(module, "SUPPORTED_SERVICES", {})
|
||||
|
||||
str = "|app_id|supported regions|\n|-|-|\n"
|
||||
for app_id, region in services.items():
|
||||
regions = ", ".join(region)
|
||||
str += f"| {app_id} | {regions} |\n"
|
||||
|
||||
_patch_file("doc/source/app_abfallplus_de.md", "service", str)
|
||||
|
||||
|
||||
def _patch_file(filename, section_id, str):
|
||||
# read entire file
|
||||
with open(filename, encoding="utf-8") as f:
|
||||
|
||||
Reference in New Issue
Block a user