mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 05:06:33 +01:00
Merge pull request #85 from Jakob-Gliwa/patch-1
Added ALBA Berlin, support for Text-Inputs & Hidden-Inputs
This commit is contained in:
@@ -4,53 +4,97 @@ from html.parser import HTMLParser
|
||||
|
||||
import inquirer
|
||||
import requests
|
||||
import re
|
||||
|
||||
MODUS_KEY = "d6c5855a62cf32a4dadbc2831f0f295f"
|
||||
HEADERS = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
|
||||
|
||||
# IDs of CONFIG VARIABLES
|
||||
CONFIG_VARIABLES = ["f_id_kommune", "f_id_bezirk", "f_id_strasse", "f_id_strasse_hnr", "f_abfallarten"]
|
||||
|
||||
ACTION_EXTRACTOR_PATTERN = re.compile('(?<=awk-data-onchange-submit-waction=")[^\\n\\r"]+')
|
||||
|
||||
DISTRICT_CHOICES = [
|
||||
("ALBA Berlin", "9583a2fa1df97ed95363382c73b41b1b"),
|
||||
("Böblingen", "8215c62763967916979e0e8566b6172e"),
|
||||
("Kitzingen", "594f805eb33677ad5bc645aeeeaf2623"),
|
||||
("Freudenstadt", "595f903540a36fe8610ec39aa3a06f6a"),
|
||||
("Göppingen", "365d791b58c7e39b20bb8f167bd33981"),
|
||||
("Landsberg am Lech", "7df877d4f0e63decfb4d11686c54c5d6"),
|
||||
("Landshut", "bd0c2d0177a0849a905cded5cb734a6f"),
|
||||
("Rotenburg (Wümme)", "645adb3c27370a61f7eabbb2039de4f1"),
|
||||
("Sigmaringen", "39886c5699d14e040063c0142cd0740b"),
|
||||
("MüllALARM / Schönmackers", "e5543a3e190cb8d91c645660ad60965f"),
|
||||
("Unterallgäu", "c22b850ea4eff207a273e46847e417c5"),
|
||||
("Westerwaldkreis", "248deacbb49b06e868d29cb53c8ef034"),
|
||||
("Calw", "690a3ae4906c52b232c1322e2f88550c"),
|
||||
]
|
||||
|
||||
|
||||
class OptionParser(HTMLParser):
|
||||
"""Parser for HTML option list."""
|
||||
TEXTBOXES = "textboxes"
|
||||
|
||||
def __init__(self):
|
||||
def error(self, message):
|
||||
pass
|
||||
|
||||
def __init__(self, target_var):
|
||||
super().__init__()
|
||||
self._target_var = target_var
|
||||
self._within_option = False
|
||||
self._option_name = ""
|
||||
self._option_value = "-1"
|
||||
self._choices = []
|
||||
self._select_name = ""
|
||||
self._waction = ""
|
||||
self._is_selector = False
|
||||
self._is_text_input = False
|
||||
self._text_field_id = ""
|
||||
self._text_hint = ""
|
||||
self._text_name = ""
|
||||
self._label_for_id = ""
|
||||
self._label_contents = {}
|
||||
|
||||
@property
|
||||
def choices(self):
|
||||
return self._choices
|
||||
|
||||
@property
|
||||
def select_name(self):
|
||||
return self._select_name
|
||||
|
||||
@property
|
||||
def waction(self):
|
||||
return self._waction
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == "option":
|
||||
attributes = dict(attrs)
|
||||
|
||||
if tag == "label":
|
||||
if "for" in attributes:
|
||||
self._label_for_id = attributes["for"]
|
||||
|
||||
if tag == "input":
|
||||
if "type" in attributes:
|
||||
if attributes["type"] == "hidden":
|
||||
if "name" in attributes and "value" in attributes and attributes["name"] == self._target_var:
|
||||
# self._within_option = True
|
||||
self._is_selector = True
|
||||
self._option_value = attributes["value"]
|
||||
self._choices.append((attributes["value"], attributes["value"]))
|
||||
elif self._target_var == OptionParser.TEXTBOXES and attributes["type"] == "text":
|
||||
self._is_text_input = True
|
||||
if "id" in attributes:
|
||||
self._text_field_id = attributes["id"]
|
||||
if "placeholder" in attributes:
|
||||
self._text_hint = attributes["placeholder"]
|
||||
if "name" in attributes:
|
||||
self._text_name = attributes["name"]
|
||||
|
||||
if tag == "select":
|
||||
if "name" in attributes and attributes["name"] == self._target_var:
|
||||
self._is_selector = True
|
||||
|
||||
if tag == "option" and self._is_selector:
|
||||
self._within_option = True
|
||||
for attr in attrs:
|
||||
if attr[0] == "value":
|
||||
self._option_value = attr[1]
|
||||
elif tag == "select":
|
||||
for attr in attrs:
|
||||
if attr[0] == "name":
|
||||
self._select_name = attr[1]
|
||||
elif attr[0] == "awk-data-onchange-submit-waction":
|
||||
self._waction = attr[1]
|
||||
if "value" in attributes:
|
||||
self._option_value = attributes["value"]
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if (
|
||||
self._within_option
|
||||
and len(self._option_name) > 0
|
||||
and self._option_value != "-1"
|
||||
self._within_option
|
||||
and len(self._option_name) > 0
|
||||
and self._option_value != "-1"
|
||||
):
|
||||
self._choices.append((self._option_name, self._option_value))
|
||||
self._within_option = False
|
||||
@@ -61,47 +105,76 @@ class OptionParser(HTMLParser):
|
||||
if self._within_option:
|
||||
self._option_name += data
|
||||
|
||||
if len(self._label_for_id) > 0:
|
||||
self._label_contents[self._label_for_id] = data
|
||||
self._label_for_id = ""
|
||||
|
||||
@property
|
||||
def is_selector(self):
|
||||
return self._is_selector
|
||||
|
||||
@property
|
||||
def is_text_input(self):
|
||||
return self._is_text_input
|
||||
|
||||
@property
|
||||
def text_name(self):
|
||||
return self._text_name
|
||||
|
||||
@property
|
||||
def text_field_id(self):
|
||||
return self._text_field_id
|
||||
|
||||
@property
|
||||
def label_contents(self):
|
||||
return self._label_contents
|
||||
|
||||
@property
|
||||
def text_hint(self):
|
||||
return self._text_hint
|
||||
|
||||
|
||||
def select_and_query(data, answers):
|
||||
# parser HTML option list
|
||||
parser = OptionParser()
|
||||
relevant_config_vars = []
|
||||
for config_var in CONFIG_VARIABLES:
|
||||
if config_var not in answers and config_var in data:
|
||||
relevant_config_vars.append(config_var)
|
||||
|
||||
for target_var in relevant_config_vars:
|
||||
# parser HTML option list
|
||||
parser = OptionParser(target_var)
|
||||
parser.feed(data)
|
||||
|
||||
if parser.is_selector:
|
||||
questions = [
|
||||
inquirer.List(
|
||||
target_var,
|
||||
choices=parser.choices,
|
||||
message=f"Select {target_var}",
|
||||
)
|
||||
]
|
||||
answers.update(inquirer.prompt(questions))
|
||||
|
||||
# Search for Textboxes (currently just supports one textbox per request)
|
||||
parser = OptionParser(OptionParser.TEXTBOXES)
|
||||
parser.feed(data)
|
||||
if parser.is_text_input:
|
||||
message = parser.label_contents[parser.text_field_id]
|
||||
if parser.text_hint != "":
|
||||
message = message + " (" + parser.text_hint + ")"
|
||||
|
||||
questions = [
|
||||
inquirer.List(
|
||||
parser.select_name,
|
||||
choices=parser.choices,
|
||||
message=f"Select {parser.select_name}",
|
||||
)
|
||||
]
|
||||
answers.update(inquirer.prompt(questions))
|
||||
questions = [inquirer.Text(parser.text_name, message=message)]
|
||||
answers.update(inquirer.prompt(questions))
|
||||
|
||||
args = {"key": answers["key"], "modus": MODUS_KEY, "waction": parser.waction}
|
||||
r = requests.post(
|
||||
"https://api.abfall.io", params=args, data=answers, headers=HEADERS
|
||||
)
|
||||
args = {"key": answers["key"], "modus": MODUS_KEY, "waction": ACTION_EXTRACTOR_PATTERN.findall(data)[0]}
|
||||
r = requests.post("https://api.abfall.io", params=args, data=answers, headers=HEADERS)
|
||||
return r.text
|
||||
|
||||
|
||||
def main():
|
||||
# select district
|
||||
district_choices = [
|
||||
("Böblingen", "8215c62763967916979e0e8566b6172e"),
|
||||
("Kitzingen", "594f805eb33677ad5bc645aeeeaf2623"),
|
||||
("Freudenstadt", "595f903540a36fe8610ec39aa3a06f6a"),
|
||||
("Göppingen", "365d791b58c7e39b20bb8f167bd33981"),
|
||||
("Landsberg am Lech", "7df877d4f0e63decfb4d11686c54c5d6"),
|
||||
("Landshut", "bd0c2d0177a0849a905cded5cb734a6f"),
|
||||
("Rotenburg (Wümme)", "645adb3c27370a61f7eabbb2039de4f1"),
|
||||
("Sigmaringen", "39886c5699d14e040063c0142cd0740b"),
|
||||
("MüllALARM / Schönmackers", "e5543a3e190cb8d91c645660ad60965f"),
|
||||
("Unterallgäu", "c22b850ea4eff207a273e46847e417c5"),
|
||||
("Westerwaldkreis", "248deacbb49b06e868d29cb53c8ef034"),
|
||||
("Calw", "690a3ae4906c52b232c1322e2f88550c"),
|
||||
]
|
||||
questions = [
|
||||
inquirer.List(
|
||||
"key", choices=district_choices, message="Select service provider"
|
||||
"key", choices=DISTRICT_CHOICES, message="Select service provider"
|
||||
)
|
||||
]
|
||||
answers = inquirer.prompt(questions)
|
||||
@@ -124,7 +197,8 @@ def main():
|
||||
print(" - name: abfall_io")
|
||||
print(" args:")
|
||||
for key, value in answers.items():
|
||||
print(f" {key}: {value}")
|
||||
if key in CONFIG_VARIABLES or key == "key":
|
||||
print(f" {key}: {value}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user