usawa

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

commit 9f602dea9b84af57bb3d3c9cffa06297e61e14c0
parent b8567b7c3cf6496e15dbf619c950289448ba5293
Author: lash <dev@holbrook.no>
Date:   Mon,  6 Apr 2026 09:39:56 -0600

Enable asset cli to put to resolver

Diffstat:
Mdummy/usawa/cli/entry.py | 13+++++++++----
Mdummy/usawa/context.py | 20+++++++++++---------
Mdummy/usawa/runnable/asset.py | 72++++++++++++++++++++++++++++++++++++++++++------------------------------
Mdummy/usawa/runnable/entry.py | 5+++++
4 files changed, 67 insertions(+), 43 deletions(-)

diff --git a/dummy/usawa/cli/entry.py b/dummy/usawa/cli/entry.py @@ -148,7 +148,7 @@ def handle_description(ctx, entry, v, prefix=None): def handle_reset(ctx, entry, v): entry.debit = [] entry.credit = [] - entry.balancer = Balancer(self.ctx.uidx) + entry.balancer = Balancer(ctx.uidx) def handle_ref(ctx, entry, v): @@ -239,7 +239,9 @@ class EntrySession: # supplementary props self.heading = heading self.lines = lines - self.amount = float(amount) + self.amount = None + if amount != None: + self.amount = float(amount) self.entry = try_entry(self.ctx, entry) if self.entry == None: @@ -338,8 +340,11 @@ class EntrySession: if v == 'i' or v == 'o': k = 'src' if v == 'o': - k = 'dst' - self.enter_part(side=k) + k = 'dst' + try: + self.enter_part(side=k) + except ValueError as e: + logg.error('enter part fail: ' + str(e)) return True if v == 'q': raise StopIteration() diff --git a/dummy/usawa/context.py b/dummy/usawa/context.py @@ -46,18 +46,20 @@ class UsawaContext: return self.o.get(k) - def init(self, args, store_scope=None): + def init(self, args=None, store_scope=None): v = None - try: - v = args.i - except AttributeError: - pass + if args != None: + try: + v = args.i + except AttributeError: + pass self.ledger_path_in = self.cfg.get('MAIN_LEDGER_FILE', v) v = None - try: - v = args.o - except AttributeError: - pass + if args != None: + try: + v = args.o + except AttributeError: + pass self.ledger_path_out = self.cfg.get('MAIN_LEDGER_FILE', v) if self.ledger_path_out == None: self.ledger_path_out = self.ledger_path_in diff --git a/dummy/usawa/runnable/asset.py b/dummy/usawa/runnable/asset.py @@ -1,6 +1,7 @@ import argparse import logging import os +import io from whee.valkey import ValkeyStore @@ -13,33 +14,44 @@ logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -argp = argparse.ArgumentParser() -argp.add_argument('-e', type=str, help='unique reference of asset') -argp.add_argument('-z', type=str, help='digest of asset') -argp.add_argument('-n', type=str, help='asset filename') -argp.add_argument('-f', type=str, help='asset file') -argp.add_argument('-d', type=str, help='description of asset') -argp.add_argument('-m', type=str, help='mime type of asset') -argp.add_argument('-c', type=str, help='override config dir') -argp.add_argument('-v', type=str, choices=['info','debug','warning','error'], help='be verbose') -args = argp.parse_args() - -if args.v: - logg.setLevel(getattr(logging, args.v.upper())) - -cfg = usawa.config.load_config(config_dir=args.c) -ctx = UsawaContext(cfg, signing=False) -ctx.init(args, store_scope='asset') - -asset = None -if args.f: - asset = Asset.from_file(args.f, extref=args.e, mimetype=args.m, slug=args.n) -elif args.z: - digest = bytes.fromhex(args.z) - asset = Asset(digest=digest, ref=args.e, mimetype=args.m, slug=args.n) -else: - raise ValueError('Must provide either file path or digest') - -ctx.store.add_asset(asset, overwrite=True) - -print(asset.ref) +def main(): + argp = argparse.ArgumentParser() + argp.add_argument('-e', type=str, help='unique reference of asset') + argp.add_argument('-z', type=str, help='digest of asset') + argp.add_argument('-n', type=str, help='asset filename') + argp.add_argument('-f', type=str, help='asset file') + argp.add_argument('-d', type=str, help='description of asset') + argp.add_argument('-m', type=str, help='mime type of asset') + argp.add_argument('-c', type=str, help='override config dir') + argp.add_argument('-v', type=str, choices=['info','debug','warning','error'], help='be verbose') + args = argp.parse_args() + + if args.v: + logg.setLevel(getattr(logging, args.v.upper())) + + cfg = usawa.config.load_config(config_dir=args.c) + ctx = UsawaContext(cfg, signing=False) + ctx.init(args, store_scope='asset') + + w = None + if ctx.resolver: + w = io.BytesIO() + asset = None + if args.f: + asset = Asset.from_file(args.f, extref=args.e, mimetype=args.m, slug=args.n, w=w) + elif args.z: + digest = bytes.fromhex(args.z) + asset = Asset(digest=digest, ref=args.e, mimetype=args.m, slug=args.n) + else: + raise ValueError('Must provide either file path or digest') + + ctx.store.add_asset(asset, overwrite=True) + if w != None: + k = asset.get_digest(binary=True) + ctx.resolver.put(k, w.getvalue()) + + print(asset.ref) + + +if __name__ == '__main__': + main() diff --git a/dummy/usawa/runnable/entry.py b/dummy/usawa/runnable/entry.py @@ -56,6 +56,11 @@ def main(): o = EntrySession(ctx, args.entry) + for v in args.a: + if ctx.resolver == None: + logg.warning('attachment specified without resolver, file must be made available manually') + + for v in args.x: o.attach_ref(v)