usawa

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | Submodules | LICENSE

commit ecf43daafc656057cc72f5c0bcd70da3e4f0c060
parent 36c53b68d2a334d04c9d0e84b299a35a8be74626
Author: lash <dev@holbrook.no>
Date:   Sun, 15 Feb 2026 12:02:00 +0000

Add XML import for entries

Diffstat:
Mdummy/usawa/ledger.py | 11+++++++++++
Adummy/usawa/runnable/import.py | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdummy/usawa/store.py | 22++++++++++++++++++++++
3 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/dummy/usawa/ledger.py b/dummy/usawa/ledger.py @@ -140,6 +140,7 @@ class RunningTotal: return RunningTotal(unit, asset=asset, liability=liability) + """Generate an XML tree from the current state of the object. The XML generated can be used as a "real" or "virt" sub-element of the ledger/incoming/ element. @@ -566,6 +567,16 @@ class Ledger: return ledger.check() + @staticmethod + def from_file(filepath): + f = open(filepath, 'rb') + v = f.read() + f.close() + tree = lxml.etree.fromstring(v) + return Ledger.from_tree(tree) + + + """Append all entries from XML tree to ledger. :param tree: A parsed XML tree. diff --git a/dummy/usawa/runnable/import.py b/dummy/usawa/runnable/import.py @@ -0,0 +1,65 @@ +import os +import sys +import logging +import urllib.parse +import argparse +import uuid +import datetime + +from usawa import Ledger, Entry, EntryPart, DemoWallet, load, ACL +from usawa.constant import CATEGORIES +from usawa.store import LedgerStore +from whee.valkey import ValkeyStore + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class Context: + + def __init__(self): + self.unit = None + self.uidx = None + self.output = None + self.f = None + + + def close(self): + if self.f and self.f != sys.stdout: + self.f.close() + + + def open(self, output): + if output == '<stdout>': + self.f = sys.stdout.buffer + logg.debug('output is stdout') + else: + self.f = open(output, 'wb') + return self + + @staticmethod + def from_args(args): + ctx = Context() + if args.output != None: + ctx.output = os.path.realpath(args.output) + else: + ctx.output = '<stdout>' + return ctx + + +argp = argparse.ArgumentParser() +argp.add_argument('-o', type=str, dest='output', help='output file for resulting XML document') +argp.add_argument('ledger_xml_file', type=str, help='load ledger metadata from XML file') +arg = argp.parse_args() +ctx = Context.from_args(arg) + +ledger = Ledger.from_file(arg.ledger_xml_file) + +storedb = ValkeyStore('') +store = LedgerStore(storedb, ledger) +#pk = store.get_key() +#wallet = DemoWallet(privatekey=pk) +#acl = ACL.from_wallet(wallet) +#store.load(acl=acl) +store.put_all(store_assets=True) +sys.stdout.buffer.write(ledger.to_string()) diff --git a/dummy/usawa/store.py b/dummy/usawa/store.py @@ -282,3 +282,25 @@ class LedgerStore(Interface): """ def get(self, k): return self.__o.get(k) + + + """Store all entries in the ledger state. + + Errors due to duplicate entry and asset insert attempts will be ignored. + + :param store_assets: Add all attachment assets from each entry. + :type store_assets: boolean + :raises FileExistsError: If duplicate entry is found. + """ + def put_all(self, store_assets=False): + for k in self.ledger.entries.keys(): + entry = self.ledger.entries[k] + try: + self.add_entry(entry, update_ledger=False) + except FileExistsError as e: + logg.info('putall skip duplicate entry {}'.format(entry)) + for asset in entry.attachment: + try: + self.add_asset(asset) + except FileExistsError: + logg.info('putall skip duplicate asset {}'.format(asset))