#!/usr/bin/env python3
"""Viewer for ledger .dat files."""
+from abc import ABC, abstractmethod
from datetime import date as dt_date
from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
from os import environ
return total
-class DatLine:
+class Line(ABC):
+ """Line abstraction featuring .as_dict property."""
+
+ @property
+ @abstractmethod
+ def as_dict(self) -> dict:
+ """Return as JSON-ready dict."""
+
+
+class DatLine(Line):
"""Line of .dat file parsed into comments and machine-readable data."""
def __init__(self, line: str) -> None:
@property
def as_dict(self) -> dict:
- """Return as JSON-ready dict."""
- assert isinstance(self.booking_line, (IntroLine, TransferLine))
+ assert self.booking_line is not None
return {'comment': self.comment, 'code': self.code,
'is_intro': self.is_intro, 'error': self.error,
'booking_line': self.booking_line.as_dict}
return self.raw.replace(' ', ' ')
-class BookingLine:
+class BookingLine(Line):
"""Parsed code part of a DatLine belonging to a Booking."""
def __init__(self, booking: 'Booking') -> None:
@property
def as_dict(self) -> dict:
- """Return as JSON-ready dict."""
return {'date': self.date, 'target': self.target}
@property
def as_dict(self) -> dict:
- """Return as JSON-ready dict."""
return {'account': self.account, 'currency': self.currency,
'amount': str(self.amount)}
DatLine(line)
for line in self._path_dat.read_text(encoding='utf8').splitlines()]
self.last_save_hash = self._hash_dat_lines()
- self._load_bookings()
-
- def save(self) -> None:
- """Save current state to ._path_dat."""
- self._path_dat.write_text(
- '\n'.join([line.raw for line in self.dat_lines]), encoding='utf8')
- self.load()
-
- def _hash_dat_lines(self) -> int:
- return hash(tuple(dl.raw for dl in self.dat_lines))
-
- @property
- def tainted(self) -> bool:
- """If .dat_lines different to those of last .load()."""
- return self._hash_dat_lines() != self.last_save_hash
-
- def _load_bookings(self) -> None:
booked_lines: list[DatLine] = []
gap_lines: list[DatLine] = []
booking: Optional[Booking] = None
if booking:
booking.gap_lines = gap_lines[:-1]
+ def save(self) -> None:
+ """Save current state to ._path_dat."""
+ self._path_dat.write_text(
+ '\n'.join([line.raw for line in self.dat_lines]), encoding='utf8')
+ self.load()
+
+ def _hash_dat_lines(self) -> int:
+ return hash(tuple(dl.raw for dl in self.dat_lines))
+
+ @property
+ def tainted(self) -> bool:
+ """If .dat_lines different to those of last .load()."""
+ return self._hash_dat_lines() != self.last_save_hash
+
def _recalc_dat_lines(self) -> None:
self.dat_lines = self.initial_gap_lines[:]
for booking in self.bookings: