commit 5358ab86bb328b0912e4e468fe93ce887f0c1bd1
parent beabc49b77a26cfaf8263d34392d02ff44f9605c
Author: lash <dev@holbrook.no>
Date: Sun, 22 Mar 2026 22:29:43 -0600
Add asset adder cli
Diffstat:
4 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/dummy/tests/store.py b/dummy/tests/store.py
@@ -193,5 +193,6 @@ class TestStore(unittest.TestCase):
self.assertEqual(o.get_digest(binary=True), hash_of_foo)
self.assertEqual(o.get_ref(binary=True), uuid_for_foo.bytes)
+
if __name__ == '__main__':
unittest.main()
diff --git a/dummy/usawa/asset.py b/dummy/usawa/asset.py
@@ -56,13 +56,20 @@ class Asset(UsawaElement):
Asset.from_tree() - Recreate from an XML tree.
"""
- def __init__(self, digest=None, ref=None):
+ def __init__(self, digest=None, ref=None, slug=None, mimetype=None):
super(Asset, self).__init__(ref=ref)
self.digest = digest
- self.mime = None
- self.enc = None
- self.slug = None
self.ext = None
+ if mimetype == None:
+ mimetype = 'application/octet-stream'
+ else:
+ ext = mimetypes.guess_extension(mimetype, strict=True)
+ self.ext = ext[1:]
+ self.mime = mimetype
+ self.enc = None
+ if slug == None:
+ slug = self.get_ref()
+ self.slug = slug
self.extref = None
self.description = None
@@ -190,10 +197,10 @@ class Asset(UsawaElement):
closer()
o.digest = h.digest()
+ (o.slug, o.ext) = parse_path(src)
s = mimetypes.guess_extension(o.mime, strict=True)
if s != None:
o.ext = s[1:]
- (o.slug, o.ext) = parse_path(src)
if slug != None:
logg.info("overriding file base name {} -> {}".format(o.slug, slug))
o.slug = slug
diff --git a/dummy/usawa/runnable/asset.py b/dummy/usawa/runnable/asset.py
@@ -0,0 +1,47 @@
+import argparse
+import logging
+import os
+
+from whee.valkey import ValkeyStore
+
+import usawa.config
+from usawa import Asset
+from usawa.store import AssetStore
+
+logging.basicConfig(level=logging.WARNING)
+logg = logging.getLogger()
+
+
+class Context:
+
+ def __init__(self, args):
+ self.cfg = usawa.config.load_config(config_dir=args.c)
+ self.state = 0
+ self.asset = None
+ if args.f:
+ self.asset = Asset.from_file(args.f, extref=args.e, mimetype=args.m, slug=args.n)
+ elif args.z:
+ digest = bytes.fromhex(args.z)
+ self.asset = Asset(digest=digest, ref=args.e, mimetype=args.m, slug=args.n)
+ else:
+ raise ValueError('Must provide either file path or digest')
+
+
+
+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()))
+
+ctx = Context(args)
+
+print(ctx.asset)
diff --git a/dummy/usawa/runnable/craft.py b/dummy/usawa/runnable/craft.py
@@ -4,8 +4,8 @@ import logging
from whee.valkey import ValkeyStore
import usawa.config
-from usawa import Entry, Ledger, EntryPart
-from usawa.store import EntryStore
+from usawa import Entry, Ledger, EntryPart, Asset
+from usawa.store import LedgerStore
from usawa.account import Account, AccountIndex, AccountType, AccountDisplay
from usawa.constant import CATEGORIES
@@ -61,7 +61,7 @@ class Context:
host = self.cfg.get('VALKEY_HOST')
port = self.cfg.get('VALKEY_PORT')
self.db = ValkeyStore('', host=host, port=port)
- self.store = EntryStore(self.db)
+ self.store = LedgerStore(self.db, self.ledger)
if args.e:
self.entry = self.store.get_draft(self.entry)
self.state = 1
@@ -70,6 +70,7 @@ class Context:
self.ref = self.entry.get_ref()
+
def parse_type(self, v):
v = v.lower()
r = None
@@ -121,8 +122,8 @@ class Context:
argp = argparse.ArgumentParser()
argp.add_argument('-e', type=str, help='unique reference of entry')
-argp.add_argument('-x', type=str, help='unique reference of attachment')
-argp.add_argument('-z', type=str, help='sum of attachment')
+argp.add_argument('-x', type=str, action='append', default=[], help='unique reference of attachment')
+argp.add_argument('-z', type=str, action='append', default=[], help='sum of attachment')
argp.add_argument('-v', type=str, choices=['info','debug','warning','error'], help='be verbose')
argp.add_argument('-c', type=str, help='override config dir')
argp.add_argument('-l', type=str, help='ledger file')
@@ -191,14 +192,26 @@ def do_interactive(ctx):
#return ctx.open(output)
entry = None
-if self.cmd == 'entry':
+if ctx.state == 0:
do_interactive(ctx)
ctx.validate()
entry = Entry.empty(description=ctx.description, ref=ctx.ref, unitindex=ctx.uidx)
entry.add_part(ctx.part[0], debit=True)
entry.add_part(ctx.part[1])
+else:
entry = ctx.entry
-elif self.cmd == 'asset':
+
+
+for v in args.x:
+ k = uuid.UUID(k)
+ asset = Asset(ref=str(k))
+ attach = self.store.get_asset_indexed(asset)
+ entry.attach(asset)
+for v in args.z:
+ k = bytes.fromhex(v)
+ asset = Asset(digest=k)
+ attach = self.store.get_asset_indexed(asset)
+ entry.attach(asset)
ctx.store.put_draft(entry)