usawa

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

commit b342d04ed3ea6d14021c9e99ba6b5ba79292979d
parent c14ff3fc9f6089b233dc616c3ae59ee824d62ab1
Author: lash <dev@holbrook.no>
Date:   Sat, 28 Mar 2026 21:52:13 -0600

Add entry tag mechanism

Diffstat:
Adummy/tests/tag.py | 21+++++++++++++++++++++
Mdummy/usawa/entry.py | 28++++++++++++++--------------
Adummy/usawa/tag.py | 40++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 14 deletions(-)

diff --git a/dummy/tests/tag.py b/dummy/tests/tag.py @@ -0,0 +1,21 @@ +import unittest +import logging + +from usawa.tag import Tags + +logging.basicConfig(level=logging.DEBUG) + + +class TestTag(unittest.TestCase): + + def test_tags_serialize(self): + o = Tags() + o.add('foo') + o.add('bar', description='baz') + v = o.serialize() + o = Tags.deserialize(v) + self.assertEqual('foo, bar', str(o)) + + +if __name__ == '__main__': + unittest.main() diff --git a/dummy/usawa/entry.py b/dummy/usawa/entry.py @@ -13,6 +13,7 @@ from .crypto import DemoWallet from .error import ACLError, VerifyError from .xml import nsmap from .asset import Asset +from .tag import Tags logg = logging.getLogger('usawa.entry') @@ -181,7 +182,7 @@ class Entry(UsawaElement): :todo: Prevent changes after the first signature calculation. :todo: Ensure canonical format of keyid. """ - def __init__(self, serial, tx_date, ref=None, description=None, parent=None, tx_datereg=None, unitindex=None): + def __init__(self, serial, tx_date, ref=None, description=None, parent=None, tx_datereg=None, unitindex=None, tags=None): super(Entry, self).__init__(ref=ref) if isinstance(parent, str): parent = bytes.fromhex(parent) @@ -207,6 +208,7 @@ class Entry(UsawaElement): self.lookup_algo = None self.parts = [] self.balancer = None + self.tags = tags if unitindex != None: self.balancer = Balancer(unitindex) @@ -342,6 +344,10 @@ class Entry(UsawaElement): for v in self.attachment: attach.append(v.get_digest(binary=True)) + tags = None + if self.tags: + tags = self.tags.serialize() + base = super(Entry, self).serialize() logg.debug('serializing with parent {}'.format(self.parent.hex())) d = [ @@ -355,6 +361,7 @@ class Entry(UsawaElement): credit, debit, attach, + tags, ] return d @@ -388,7 +395,12 @@ class Entry(UsawaElement): dst_data = v[7] src_data = v[8] attach_data = v[9] - o = Entry(serial, date, ref=ref, description=description, parent=parent, tx_datereg=date_reg) + tags = None + try: + tags = Tags.deserialize(v[10]) + except TypeError: + pass + o = Entry(serial, date, ref=ref, description=description, parent=parent, tx_datereg=date_reg, tags=tags) super(Entry, o).deserialize(v[0]) for v in src_data: src = EntryPart.deserialize(v, debit=True) @@ -638,18 +650,6 @@ class Entry(UsawaElement): h.update(b.encode('utf-8')) return (h.digest().hex(), b,) -# -# -# def tree_sum(self, lookup): -# tree = self.to_tree() -# b = lxml.etree.tostring(tree) -# h = None -# if lookup == 'sha512': -# h = hashlib.sha512() -# elif lookup == 'sha256': -# h = hashlib.sha256() -# h.update(b) -# return h.digest() """Generate canonical XML for signature material. diff --git a/dummy/usawa/tag.py b/dummy/usawa/tag.py @@ -0,0 +1,40 @@ +import rencode + +class Tags: + + def __init__(self, store=None): + self.store = store + self.tags = {} + + + def add(self, tag, description=None): + self.tags[tag] = description + if self.store != None: + self.store.put_tag(tag, description) + + + def to_list(self): + return list(self.tags.keys()) + + + def serialize(self): + v = self.to_list() + return rencode.dumps(v) + + + @staticmethod + def deserialize(data, store=None): + r = rencode.loads(data) + o = Tags(store=store) + for k in r: + k = k.decode('utf-8') + v = None + if o.store != None: + v = o.store.get_tag(k) + o.add(k, description=v) + return o + + + def __str__(self): + v = ', '.join(list(self.tags.keys())) + return v