home
·
contact
·
privacy
projects
/
plomledger
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
1311dd8
)
Refactor .as_dict properties.
master
author
Christian Heller
<c.heller@plomlompom.de>
Tue, 4 Feb 2025 13:29:37 +0000
(14:29 +0100)
committer
Christian Heller
<c.heller@plomlompom.de>
Tue, 4 Feb 2025 13:29:37 +0000
(14:29 +0100)
ledger.py
patch
|
blob
|
history
diff --git
a/ledger.py
b/ledger.py
index 30f93dd3221c3cba1be1caed4e0e155c8421c408..614fef5f98cbc1492c0ec7586ddce64bba7c9209 100755
(executable)
--- a/
ledger.py
+++ b/
ledger.py
@@
-1,6
+1,5
@@
#!/usr/bin/env python3
"""Viewer for ledger .dat files."""
#!/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
from datetime import date as dt_date
from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
from os import environ
@@
-26,6
+25,24
@@
LEDGER_STRUCT = f'{PREFIX_LEDGER}{TOK_STRUCT}'
LEDGER_RAW = f'{PREFIX_LEDGER}{TOK_RAW}'
LEDGER_RAW = f'{PREFIX_LEDGER}{TOK_RAW}'
+class Dictable:
+ """Line abstraction featuring .as_dict property."""
+ dictables: set[str] = set()
+
+ @property
+ def as_dict(self) -> dict[str, Any]:
+ """Return as JSON-ready dict attributes listed in .dictables."""
+ d = {}
+ for name in self.dictables:
+ value = getattr(self, name)
+ if hasattr(value, 'as_dict'):
+ value = value.as_dict
+ elif not isinstance(value, (str, int)):
+ value = str(value)
+ d[name] = value
+ return d
+
+
class Wealth:
"""Collects amounts mapped to currencies."""
class Wealth:
"""Collects amounts mapped to currencies."""
@@
-98,17
+115,9
@@
class Account:
return sorted(list(names))
return sorted(list(names))
-class Line(ABC):
- """Line abstraction featuring .as_dict property."""
-
- @property
- @abstractmethod
- def as_dict(self) -> dict:
- """Return as JSON-ready dict."""
-
-
-class DatLine(Line):
+class DatLine(Dictable):
"""Line of .dat file parsed into comments and machine-readable data."""
"""Line of .dat file parsed into comments and machine-readable data."""
+ dictables = {'booking_line', 'code', 'comment', 'error', 'is_intro'}
def __init__(self, line: str) -> None:
self.raw = line[:]
def __init__(self, line: str) -> None:
self.raw = line[:]
@@
-117,13
+126,6
@@
class DatLine(Line):
self.code = halves[0]
self.booking_line: Optional[BookingLine] = None
self.code = halves[0]
self.booking_line: Optional[BookingLine] = None
- @property
- def as_dict(self) -> dict:
- 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}
-
@property
def is_intro(self) -> bool:
"""Return if intro line of a Booking."""
@property
def is_intro(self) -> bool:
"""Return if intro line of a Booking."""
@@
-163,7
+165,7
@@
class DatLine(Line):
return self.raw.replace(' ', ' ')
return self.raw.replace(' ', ' ')
-class BookingLine(
Lin
e):
+class BookingLine(
Dictabl
e):
"""Parsed code part of a DatLine belonging to a Booking."""
def __init__(self, booking: 'Booking') -> None:
"""Parsed code part of a DatLine belonging to a Booking."""
def __init__(self, booking: 'Booking') -> None:
@@
-174,6
+176,7
@@
class BookingLine(Line):
class IntroLine(BookingLine):
"""First line of a Booking, expected to carry date etc."""
class IntroLine(BookingLine):
"""First line of a Booking, expected to carry date etc."""
+ dictables = {'date', 'target'}
def __init__(self, booking: 'Booking', code: str) -> None:
super().__init__(booking)
def __init__(self, booking: 'Booking', code: str) -> None:
super().__init__(booking)
@@
-189,13
+192,10
@@
class IntroLine(BookingLine):
except ValueError:
self.errors += [f'not properly formatted legal date: {self.date}']
except ValueError:
self.errors += [f'not properly formatted legal date: {self.date}']
- @property
- def as_dict(self) -> dict:
- return {'date': self.date, 'target': self.target}
-
class TransferLine(BookingLine):
"""Non-first Booking line, expected to carry value movement."""
class TransferLine(BookingLine):
"""Non-first Booking line, expected to carry value movement."""
+ dictables = {'amount', 'account', 'currency'}
def __init__(self, booking: 'Booking', code: str, idx: int) -> None:
super().__init__(booking)
def __init__(self, booking: 'Booking', code: str, idx: int) -> None:
super().__init__(booking)
@@
-224,11
+224,6
@@
class TransferLine(BookingLine):
return f'{self.amount:.1f}…' if exp < -2 else f'{self.amount:.2f}'
return ''
return f'{self.amount:.1f}…' if exp < -2 else f'{self.amount:.2f}'
return ''
- @property
- def as_dict(self) -> dict:
- return {'account': self.account, 'currency': self.currency,
- 'amount': str(self.amount)}
-
class Booking:
"""Represents lines of individual booking."""
class Booking:
"""Represents lines of individual booking."""