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:
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.