From: Christian Heller Date: Sun, 2 Feb 2025 21:54:58 +0000 (+0100) Subject: Refactor do_GET routes. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%7B%7Bdb.prefix%7D%7D/%7B%7B%20web_path%20%7D%7D/condition?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=plomledger Refactor do_GET routes. --- diff --git a/ledger.py b/ledger.py index fb2abcf..f994721 100755 --- a/ledger.py +++ b/ledger.py @@ -6,7 +6,7 @@ from decimal import Decimal, InvalidOperation as DecimalInvalidOperation from os import environ from pathlib import Path from sys import exit as sys_exit -from typing import Optional, Self +from typing import Any, Optional, Self from plomlib.web import PlomHttpHandler, PlomHttpServer, PlomQueryMap @@ -15,6 +15,15 @@ SERVER_PORT = 8084 SERVER_HOST = '127.0.0.1' PATH_TEMPLATES = Path('templates') +PREFIX_LEDGER = 'ledger_' +PREFIX_EDIT = 'edit_' +TOK_STRUCT = 'structured' +TOK_RAW = 'raw' +EDIT_STRUCT = f'{PREFIX_EDIT}{TOK_STRUCT}' +EDIT_RAW = f'{PREFIX_EDIT}{TOK_RAW}' +LEDGER_STRUCT = f'{PREFIX_LEDGER}{TOK_STRUCT}' +LEDGER_RAW = f'{PREFIX_LEDGER}{TOK_RAW}' + class Wealth: """Collects amounts mapped to currencies.""" @@ -313,16 +322,19 @@ class Handler(PlomHttpHandler): # pylint: disable=missing-class-docstring mapper = PlomQueryMap + def _send_rendered(self, tmpl_name: str, ctx: dict[str, Any]) -> None: + self.send_rendered(Path(f'{tmpl_name}.tmpl'), ctx) + def do_POST(self) -> None: # pylint: disable=invalid-name,missing-function-docstring - prefix_file, prefix_ledger = 'file_', 'ledger_' + prefix_file = 'file_' if (file_prefixed := self.postvars.keys_prefixed(prefix_file)): getattr(self.server, file_prefixed[0][len(prefix_file):])() - elif (self.pagename.startswith('edit_') + elif (self.pagename.startswith(PREFIX_EDIT) and self.postvars.first('apply')): booking = self.server.bookings[int(self.path_toks[2])] new_lines = [] - if self.pagename == 'edit_structured': + if self.pagename == EDIT_STRUCT: line_keys = self.postvars.keys_prefixed('line_') lineno_to_inputs: dict[int, list[str]] = {} for key in line_keys: @@ -356,9 +368,9 @@ class Handler(PlomHttpHandler): new_id = self.server.rewrite_booking(booking.id_, new_lines) self.redirect(Path('/bookings').joinpath(f'{new_id}')) return - elif self.pagename.startswith(prefix_ledger): + elif self.pagename.startswith(PREFIX_LEDGER): action, id_str, dir_ =\ - self.postvars.keys_prefixed(prefix_ledger)[0].split('_')[1:] + self.postvars.keys_prefixed(PREFIX_LEDGER)[0].split('_')[1:] new_id = getattr(self.server, f'{action}_booking')( int(id_str), dir_ == 'up' if action == 'move' else 'to_end') self.redirect(Path(self.path).joinpath(f'#{new_id}')) @@ -368,35 +380,64 @@ class Handler(PlomHttpHandler): def do_GET(self) -> None: # pylint: disable=invalid-name,missing-function-docstring ctx = {'tainted': self.server.tainted, 'path': self.path} - if self.pagename == 'bookings' or self.pagename.startswith('edit_'): - id_ = int(self.path_toks[2]) - if self.pagename.startswith('edit_'): - ctx['id'] = id_ - if self.pagename == 'balance': - id_ = int(self.params.first('up_incl') or '-1') - valid, balance_roots = self.server.balance_roots(id_) - self.send_rendered(Path('balance.tmpl'), - ctx | {'roots': balance_roots, - 'valid': valid, - 'booking': self.server.bookings[id_]}) - elif self.pagename == 'bookings': + if self.pagename == 'bookings': self.redirect( - Path('/').joinpath('edit_structured').joinpath(str(id_))) - elif self.pagename == 'edit_structured': - ctx['dat_lines'] = [ - dl.as_dict for dl - in self.server.bookings[ctx['id']].booked_lines] - self.send_rendered(Path('edit_structured.tmpl'), ctx) - elif self.pagename == 'edit_raw': - ctx['dat_lines'] = self.server.bookings[ctx['id']].booked_lines - self.send_rendered(Path('edit_raw.tmpl'), ctx) - elif self.pagename == 'ledger_raw': - self.send_rendered(Path('ledger_raw.tmpl'), - ctx | {'dat_lines': self.server.dat_lines}) + Path('/').joinpath(EDIT_STRUCT).joinpath(self.path_toks[2])) + elif self.pagename == 'balance': + self.get_balance(ctx) + elif self.pagename.startswith(PREFIX_EDIT): + self.get_edit(ctx, self.pagename == EDIT_RAW) + elif self.pagename.startswith(PREFIX_LEDGER): + self.get_ledger(ctx, self.pagename == LEDGER_RAW) else: - self.send_rendered( - Path('ledger_structured.tmpl'), - ctx | {'dat_lines': self.server.dat_lines_sans_empty}) + self.get_ledger(ctx, False) + + def get_balance(self, ctx) -> None: + """Display tree of calculated Accounts over .bookings[:up_incl+1].""" + id_ = int(self.params.first('up_incl') or '-1') + valid = True + account_names = set() + to_balance = (self.server.bookings[:id_ + 1] if id_ >= 0 + else self.server.bookings) + for booking in to_balance: + valid = valid if not booking.is_questionable else False + for account_name in booking.account_changes: + account_names.add(account_name) + full_names_to_accounts: dict[str, Account] = {} + for full_name in sorted(list(account_names)): + step_names = full_name.split(':') + path = '' + for step_name in step_names: + parent_name = path[:] + path = ':'.join([path, step_name]) if path else step_name + if path not in full_names_to_accounts: + full_names_to_accounts[path] = Account( + full_names_to_accounts[parent_name] if parent_name + else None, + step_name) + for booking in to_balance: + for account_name in booking.account_changes: + full_names_to_accounts[account_name].local_wealth +=\ + booking.account_changes[account_name] + ctx['roots'] = [ac for ac in full_names_to_accounts.values() + if not ac.parent] + ctx['valid'] = valid + ctx['booking'] = self.server.bookings[id_] + self._send_rendered('balance', ctx) + + def get_edit(self, ctx, raw: bool) -> None: + """Display edit form for individual Booking.""" + id_ = int(self.path_toks[2]) + ctx['id'] = id_ + ctx['dat_lines'] = [dl if raw else dl.as_dict for dl + in self.server.bookings[id_].booked_lines] + self._send_rendered(EDIT_RAW if raw else EDIT_STRUCT, ctx) + + def get_ledger(self, ctx: dict[str, Any], raw: bool) -> None: + """Display ledger of all Bookings.""" + ctx['dat_lines'] = [dl for dl in self.server.dat_lines + if raw or not dl.is_empty] + self._send_rendered(LEDGER_RAW if raw else LEDGER_STRUCT, ctx) class Server(PlomHttpServer): @@ -543,40 +584,6 @@ class Server(PlomHttpServer): self._recalc_dat_lines() return new_id - @property - def dat_lines_sans_empty(self) -> list[DatLine]: - """Return only those .data_lines with .code or .comment.""" - return [dl for dl in self.dat_lines if not dl.is_empty] - - def balance_roots(self, up_incl: int) -> tuple[bool, list[Account]]: - """Return tree of calculated Accounts over .bookings[:up_incl+1].""" - account_names = set() - valid = True - to_balance = (self.bookings[:up_incl + 1] if up_incl >= 0 - else self.bookings) - for booking in to_balance: - valid = valid if not booking.is_questionable else False - for account_name in booking.account_changes: - account_names.add(account_name) - full_names_to_accounts: dict[str, Account] = {} - for full_name in sorted(list(account_names)): - step_names = full_name.split(':') - path = '' - for step_name in step_names: - parent_name = path[:] - path = ':'.join([path, step_name]) if path else step_name - if path not in full_names_to_accounts: - full_names_to_accounts[path] = Account( - full_names_to_accounts[parent_name] if parent_name - else None, - step_name) - for booking in to_balance: - for account_name in booking.account_changes: - full_names_to_accounts[account_name].local_wealth +=\ - booking.account_changes[account_name] - return valid, [ac for ac in full_names_to_accounts.values() - if not ac.parent] - if __name__ == "__main__": if not LEDGER_DAT: