usawa

Signed, immutable accounting.
Log | Files | Refs | Submodules | LICENSE

commit 5fce8ea4700e511b59cb87df9d2b852569d40cc1
parent 8e64f048687ef5affed079788f285e3c0ad9b4ef
Author: lash <dev@holbrook.no>
Date:   Sun, 24 May 2026 11:52:52 -0600

Add xml export import for entry index

Diffstat:
Mdummy/tests/entryindex.py | 56++++++++++++++++++++++++++++++++++++++------------------
Mdummy/tests/store.py | 6+-----
Mdummy/usawa/index/entry.py | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mdummy/usawa/store.py | 3---
4 files changed, 95 insertions(+), 34 deletions(-)

diff --git a/dummy/tests/entryindex.py b/dummy/tests/entryindex.py @@ -20,39 +20,59 @@ class TestEntryIndex(unittest.TestCase): self.eidx = EntryIndex(digest=True) self.uidx = UnitIndex('FOO') self.ledger = Ledger(self.uidx, topic=b'bar', entry_index=self.eidx) - - - def test_entry_index(self): - wallet = DemoWallet() + self.wallet = DemoWallet() dst = EntryPart('FOO.Asset/foo', 1337) src = EntryPart('FOO.Income/foo', 1337, debit=True) - entry_a = Entry(1, datetime.datetime.strptime('2025-11-11', '%Y-%m-%d'), ref=str(uuid.uuid4()), description='foo', unitindex=self.uidx) - o = entry_a + self.entry_a = Entry(1, datetime.datetime.strptime('2025-11-11', '%Y-%m-%d'), ref=str(uuid.uuid4()), description='foo', unitindex=self.uidx) + o = self.entry_a o.add_part(src) o.add_part(dst) - o.sign(wallet) + o.sign(self.wallet) self.ledger.add_entry(o) dst = EntryPart('FOO.Expense/bar', 42) src = EntryPart('FOO.Asset/bar', -42, debit=True) now = datetime.datetime.now(datetime.UTC) - entry_b = Entry(2, now, parent=self.ledger.cur, ref=str(uuid.uuid4()), description='bar', unitindex=self.uidx) - o = entry_b + self.entry_b = Entry(2, now, parent=self.ledger.cur, ref=str(uuid.uuid4()), description='bar', unitindex=self.uidx) + o = self.entry_b o.add_part(src) o.add_part(dst) - o.sign(wallet) + o.sign(self.wallet) self.ledger.add_entry(o) - r = self.eidx.get_ref(entry_a) - self.assertEqual(r, entry_a.ref) - r = self.eidx.get_digest(entry_a) - self.assertEqual(r, entry_a.sum()) - r = self.eidx.get_ref(entry_b) - self.assertEqual(r, entry_b.ref) - r = self.eidx.get_digest(entry_b) - self.assertEqual(r, entry_b.sum()) + def test_entry_check_index(self): + r = self.eidx.get_ref(self.entry_a) + self.assertEqual(r, self.entry_a.ref) + r = self.eidx.get_digest(self.entry_a) + z = self.entry_a.sum() + self.assertEqual(r, z[0]) + + r = self.eidx.get_ref(self.entry_b) + self.assertEqual(r, self.entry_b.ref) + r = self.eidx.get_digest(self.entry_b) + z = self.entry_b.sum() + self.assertEqual(r, z[0]) + + + def test_entry_export(self): + o = self.eidx.to_tree() + idx = EntryIndex.from_tree(o) + r = idx.get_ref(1) + self.assertEqual(r, self.entry_a.ref) + r = idx.get_ref(2) + self.assertEqual(r, self.entry_b.ref) + z = self.entry_a.sum()[0] + r = idx.get_digest(1) + self.assertEqual(r, z) + z = self.entry_b.sum()[0] + r = idx.get_digest(2) + self.assertEqual(r, z) + + +if __name__ == '__main__': + unittest.main() if __name__ == '__main__': diff --git a/dummy/tests/store.py b/dummy/tests/store.py @@ -227,11 +227,7 @@ class TestStore(unittest.TestCase): ledger = Ledger(uidx, topic=b'foobar') store = LedgerStore(self.store, ledger) store.load() - #r = store.get_entry(o.serial, acl=acl) - #self.assertEqual(r.ref, o.ref) - #self.assertEqual(r.description, o.description) - #self.assertEqual(r.attachment[0].description, 'foobar') - + def test_store_link(self): uidx = UnitIndex('FOO') diff --git a/dummy/usawa/index/entry.py b/dummy/usawa/index/entry.py @@ -1,3 +1,9 @@ +import lxml.etree + +from usawa.xml import nsmap +from usawa import Entry + + class EntryIndex: def __init__(self, ref=True, digest=False): @@ -14,25 +20,67 @@ class EntryIndex: raise AttributeError('nonsense index without anything to index') - def register(self, entry): + def register(self, entry, digest=None): if self.m & 1 > 0: if entry.ref == None: raise AttrubuteError('ref missing') self.idx[entry.serial] = entry.ref self.idx_r[entry.ref] = entry.serial if self.m & 2 > 0: - z = entry.sum() - self.idx_z[entry.serial] = z - self.idx_zr[z] = entry.serial + if digest == None: + digest = entry.sum()[0] + self.idx_z[entry.serial] = digest + self.idx_zr[digest] = entry.serial def get_ref(self, entry): if self.m & 1 == 0: raise AttributeError('not a ref index') - return self.idx[entry.serial] + v = entry + if isinstance(v, Entry): + v = entry.serial + return self.idx[v] def get_digest(self, entry): - if self.m & 1 == 0: - raise AttributeError('not a ref index') - return self.idx_z[entry.serial] + if self.m & 2 == 0: + raise AttributeError('not a digest index') + v = entry + if isinstance(v, Entry): + v = entry.serial + return self.idx_z[v] + + + def to_tree(self): + tree = lxml.etree.Element('index', nsmap=nsmap()) + i = 0 + while True: + i += 1 + try: + v = self.get_digest(i) + except KeyError: + break + o = lxml.etree.Element('entry') + o.text = v.hex() + o.set('serial', str(i)) + if self.m & 1 > 0: + v = self.get_ref(i) + o.set('ref', v) + tree.append(o) + return tree + + + @staticmethod + def from_tree(tree): + have_refs = False + idx = EntryIndex(ref=True, digest=True) + for v in tree.findall('entry'): + ref = v.get('ref') + if ref != None: + have_refs = True + digest = v.text + digest = bytes.fromhex(digest) + serial = int(v.get('serial')) + o = Entry.empty(serial=serial, ref=ref) + idx.register(o, digest=digest) + return idx diff --git a/dummy/usawa/store.py b/dummy/usawa/store.py @@ -370,9 +370,6 @@ class EntryStore(KeyStore, LinkStore): return entry - - -#class LedgerStore(EntryStore, AssetStore, KeyStore): class LedgerStore(EntryStore, AssetStore): """Wrapper for an implementation of the whee store that handles encoding of ledgers and entries.