home · contact · privacy
Refactor ledger management out of Server class.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 19 Mar 2025 09:24:07 +0000 (10:24 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 19 Mar 2025 09:24:07 +0000 (10:24 +0100)
src/run.py

index d840ebe582e500a58d57dc45565972f83092af7b..91079d7832c6f942453dc8f5b87d06112247bdb5 100755 (executable)
@@ -391,15 +391,15 @@ class Handler(PlomHttpHandler):
         self.redirect(redir_target)
 
     def post_file_action(self, file_prefixed: str) -> None:
-        """Based on file_prefixed name, trigger .server.load or .save."""
+        """Based on file_prefixed name, trigger .server.ledger.(load|save)."""
         if file_prefixed == f'{PREFIX_FILE}load':
-            self.server.load()
+            self.server.ledger.load()
         elif file_prefixed == f'{PREFIX_FILE}save':
-            self.server.save()
+            self.server.ledger.save()
 
     def post_edit(self) -> Path:
         """Based on postvars, edit targeted Booking."""
-        booking = self.server.bookings[int(self.path_toks[2])]
+        booking = self.server.ledger.bookings[int(self.path_toks[2])]
         new_lines = []
         if self.pagename == EDIT_STRUCT:
             line_keys = self.postvars.keys_prefixed('line_')
@@ -432,21 +432,21 @@ class Handler(PlomHttpHandler):
         else:  # edit_raw
             new_lines += [DatLine(line) for line
                           in self.postvars.first('booking').splitlines()]
-        new_id = self.server.rewrite_booking(booking.id_, new_lines)
+        new_id = self.server.ledger.rewrite_booking(booking.id_, new_lines)
         return Path('/bookings').joinpath(f'{new_id}')
 
     def post_ledger_action(self) -> Path:
-        """Parse postvar to call .server.(move|copy|add_empty_new)_booking."""
+        """Call .server.ledger.(move|copy|add_empty_new)_booking."""
         if 'add_booking' in self.postvars.as_dict:
-            id_ = self.server.add_empty_booking()
+            id_ = self.server.ledger.add_empty_booking()
         else:
             keys_prefixed = self.postvars.keys_prefixed(PREFIX_LEDGER)
             action, id_str = keys_prefixed[0].split('_', maxsplit=2)[1:]
             id_ = int(id_str)
             if action.startswith('move'):
-                id_ = self.server.move_booking(id_, action == 'moveup')
+                id_ = self.server.ledger.move_booking(id_, action == 'moveup')
                 return Path(self.path).joinpath(f'#{id_}')
-            id_ = self.server.copy_booking(id_)
+            id_ = self.server.ledger.copy_booking(id_)
         return Path(EDIT_STRUCT).joinpath(f'{id_}')
 
     def do_GET(self) -> None:
@@ -456,7 +456,7 @@ class Handler(PlomHttpHandler):
             self.redirect(
                 Path('/').joinpath(EDIT_STRUCT).joinpath(self.path_toks[2]))
             return
-        ctx = {'tainted': self.server.tainted, 'path': self.path}
+        ctx = {'tainted': self.server.ledger.tainted, 'path': self.path}
         if self.pagename == 'balance':
             self.get_balance(ctx)
         elif self.pagename.startswith(PREFIX_EDIT):
@@ -469,17 +469,17 @@ class Handler(PlomHttpHandler):
     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')
-        ctx['roots'] = [ac for ac in self.server.accounts.values()
+        ctx['roots'] = [ac for ac in self.server.ledger.accounts.values()
                         if not ac.parent]
-        ctx['valid'] = self.server.bookings_valid_up_incl(id_)
-        ctx['booking'] = self.server.bookings[id_]
+        ctx['valid'] = self.server.ledger.bookings_valid_up_incl(id_)
+        ctx['booking'] = self.server.ledger.bookings[id_]
         ctx['path_up_incl'] = f'{self.path_toks[1]}?up_incl='
         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])
-        booking = self.server.bookings[id_]
+        booking = self.server.ledger.bookings[id_]
         observed_tree: list[dict[str, Any]] = []
         for full_path in sorted(booking.account_changes.keys()):
             parent_children: list[dict[str, Any]] = observed_tree
@@ -491,9 +491,9 @@ class Handler(PlomHttpHandler):
                     break
                 if already_registered:
                     continue
-                self.server.ensure_account(path)
-                before = self.server.accounts[path].get_wealth(id_ - 1)
-                after = self.server.accounts[path].get_wealth(id_)
+                self.server.ledger.ensure_account(path)
+                before = self.server.ledger.accounts[path].get_wealth(id_ - 1)
+                after = self.server.ledger.accounts[path].get_wealth(id_)
                 direct_target = full_path == path
                 diff = {
                     cur: amt for cur, amt in (after - before).moneys.items()
@@ -518,36 +518,44 @@ class Handler(PlomHttpHandler):
         ctx['id'] = id_
         ctx['dat_lines'] = [dl if raw else dl.as_dict
                             for dl in booking.booked_lines]
-        ctx['valid'] = self.server.bookings_valid_up_incl(id_)
+        ctx['valid'] = self.server.ledger.bookings_valid_up_incl(id_)
         if not raw:
-            ctx['all_accounts'] = sorted(self.server.accounts.keys())
+            ctx['all_accounts'] = sorted(self.server.ledger.accounts.keys())
         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'] = self.server.dat_lines
+        ctx['dat_lines'] = self.server.ledger.dat_lines
         self._send_rendered(LEDGER_RAW if raw else LEDGER_STRUCT, ctx)
 
 
 class Server(PlomHttpServer):
     """Extends parent by loading .dat file into database for Handler."""
+
+    def __init__(self, path_dat: Path, *args, **kwargs) -> None:
+        super().__init__(PATH_TEMPLATES, (SERVER_HOST, SERVER_PORT), Handler)
+        self.ledger = Ledger(path_dat)
+
+
+class Ledger:
+    """Collection of DatLines, and Accounts, Bookings derived from them."""
     accounts: dict[str, Account]
     bookings: list[Booking]
     dat_lines: list[DatLine]
     initial_gap_lines: list[DatLine]
 
-    def __init__(self, path_dat: Path, *args, **kwargs) -> None:
-        super().__init__(PATH_TEMPLATES, (SERVER_HOST, SERVER_PORT), Handler)
+    def __init__(self, path_dat: Path) -> None:
         self._path_dat = path_dat
         self.load()
 
     def load(self) -> None:
-        """Read into ledger file at .path_dat."""
-        self.dat_lines = [
+        """(Re-)read ledger from file at ._path_dat."""
+        self.accounts, self.bookings, self.initial_gap_lines = {}, [], []
+        self.initial_gap_lines: list[DatLine] = []  # TODO: fix duplicate booking
+        self.dat_lines: list[DatLine] = [
             DatLine(line)
             for line in self._path_dat.read_text(encoding='utf8').splitlines()]
         self.last_save_hash = self._hash_dat_lines()
-        self.bookings, self.initial_gap_lines = [], []
         booked: list[DatLine] = []
         gap_lines: list[DatLine] = []
         booking: Optional[Booking] = None