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
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) -> \