usawa

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

commit 715ebf5221d24ac5796de5957974263e15e89ae6
parent 9f602dea9b84af57bb3d3c9cffa06297e61e14c0
Author: lash <dev@holbrook.no>
Date:   Mon,  6 Apr 2026 11:42:11 -0600

Make asset overwrite from cli explicit, put parent hash in new entry object in cli

Diffstat:
Mdummy/usawa/cli/entry.py | 8++++++--
Mdummy/usawa/runnable/asset.py | 17+++++++++++++----
Mdummy/usawa/runnable/entry.py | 5-----
3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/dummy/usawa/cli/entry.py b/dummy/usawa/cli/entry.py @@ -189,7 +189,7 @@ def try_entry_digest(ctx, k): def try_entry(ctx, entry_spec): if not entry_spec: - return Entry.empty(unitindex=ctx.uidx) + return Entry.empty(unitindex=ctx.uidx, parent=ctx.ledger.cur) try: return try_entry_serial(ctx, entry_spec) @@ -252,6 +252,8 @@ class EntrySession: def _cur_amount(self): + if self.amount == None: + return 0 amount = self.ctx.uidx.val(self.unitbase, self.amount) if amount == None: amount = self.entry.balancer.value() @@ -379,8 +381,10 @@ class EntrySession: def do_interactive_one(self): v = input_or_default('Entry description', self.entry.description) self.entry.description = v - v = input_or_default('External ref', self.entry.ref) + v = input_or_default('Internal ref', self.entry.ref) self.entry.ref = v + v = input_or_default('External ref', self.entry.ref) + self.entry.extref = v v = input_or_default('Transaction date(time)', self.entry.dt) if isinstance(v, str): v = parse_txdate(self.ctx, v) diff --git a/dummy/usawa/runnable/asset.py b/dummy/usawa/runnable/asset.py @@ -2,6 +2,7 @@ import argparse import logging import os import io +import sys from whee.valkey import ValkeyStore @@ -20,6 +21,7 @@ def main(): 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('--force', action='store_true', default=False, help='overwrite if exists') 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') @@ -37,18 +39,25 @@ def main(): if ctx.resolver: w = io.BytesIO() asset = None + digest = None if args.f: - asset = Asset.from_file(args.f, extref=args.e, mimetype=args.m, slug=args.n, w=w) + asset = Asset.from_file(args.f, extref=args.e, mimetype=args.m, slug=args.n, w=w) + digest = asset.get_digest(binary=True) 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) + try: + ctx.store.add_asset(asset, overwrite=args.force) + except FileExistsError: + logg.error('record already exists for {}'.format(digest)) + sys.exit(1) if w != None: - k = asset.get_digest(binary=True) - ctx.resolver.put(k, w.getvalue()) + k = digest + v = w.getvalue() + ctx.resolver.put(k, v) print(asset.ref) diff --git a/dummy/usawa/runnable/entry.py b/dummy/usawa/runnable/entry.py @@ -56,11 +56,6 @@ 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)