From: Christian Heller Date: Wed, 27 Mar 2024 02:29:03 +0000 (+0100) Subject: Add PostvarsParser to isolate postvars parsing/checking. X-Git-Url: https://plomlompom.com/repos/balance?a=commitdiff_plain;h=8aa3103f8e131b8925ac9daafadf2db77886c910;p=plomtask Add PostvarsParser to isolate postvars parsing/checking. --- diff --git a/plomtask/http.py b/plomtask/http.py index 3396125..933662f 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -24,6 +24,28 @@ class TaskServer(HTTPServer): self.jinja = JinjaEnv(loader=JinjaFSLoader(TEMPLATES_DIR)) +class PostvarsParser: + """Postvars wrapper for validating and retrieving posted form data.""" + + def __init__(self, postvars: dict[str, list[str]]) -> None: + self.postvars = postvars + + def get_str(self, key: str) -> str: + """Retrieve string value of key from self.postvars.""" + if key not in self.postvars: + raise BadFormatException(f'missing value for form field: {key}') + return self.postvars[key][0] + + def get_float(self, key: str) -> float: + """Retrieve float value of key from self.postvars.""" + val = self.get_str(key) + try: + return float(val) + except ValueError as e: + msg = f'cannot float form field value: {val}' + raise BadFormatException(msg) from e + + class TaskHandler(BaseHTTPRequestHandler): """Handles single HTTP request.""" server: TaskServer @@ -87,48 +109,37 @@ class TaskHandler(BaseHTTPRequestHandler): length = int(self.headers['content-length']) postvars = parse_qs(self.rfile.read(length).decode(), keep_blank_values=True) + form_data = PostvarsParser(postvars) if 'day' == site: date = params.get('date', [''])[0] - self.do_POST_day(conn, date, postvars) + self.do_POST_day(conn, date, form_data) elif 'process' == site: id_ = params.get('id', [''])[0] try: id__ = int(id_) if id_ else None except ValueError as e: raise BadFormatException(f'Bad ?id= value: {id_}') from e - self.do_POST_process(conn, id__, postvars) + self.do_POST_process(conn, id__, form_data) conn.commit() conn.close() self._redirect('/') except HandledException as error: self._send_msg(error, code=error.http_code) - def do_POST_day(self, conn: DatabaseConnection, - date: str, postvars: dict[str, list[str]]) -> None: + def do_POST_day(self, conn: DatabaseConnection, date: str, + form_data: PostvarsParser) -> None: """Update or insert Day of date and fields defined in postvars.""" day = Day.by_date(conn, date, create=True) - if 'comment' not in postvars.keys(): - raise BadFormatException('missing Day.comment value') - day.comment = postvars['comment'][0] + day.comment = form_data.get_str('comment') day.save(conn) def do_POST_process(self, conn: DatabaseConnection, id_: int | None, - postvars: dict[str, list[str]]) -> None: + form_data: PostvarsParser) -> None: """Update or insert Process of id_ and fields defined in postvars.""" process = Process.by_id(conn, id_, create=True) - if 'title' not in postvars.keys(): - raise BadFormatException('missing Process.title value') - if 'description' not in postvars.keys(): - raise BadFormatException('missing Process.description value') - if 'effort' not in postvars.keys(): - raise BadFormatException('missing Process.effort value') - process.title.set(postvars['title'][0]) - process.description.set(postvars['description'][0]) - effort = postvars['effort'][0] - try: - process.effort.set(float(effort)) - except ValueError as e: - raise BadFormatException(f'Bad effort value: {effort}') from e + process.title.set(form_data.get_str('title')) + process.description.set(form_data.get_str('description')) + process.effort.set(form_data.get_float('effort')) process.save(conn) def _init_handling(self) -> \