adesse

Signed testimonials for certifications.
Log | Files | Refs

commit 5413251ea7939ffb7da95da941bde7f5af87892b
parent 949879bd36dd77d54cba35a5dc1658dc92dc1d44
Author: lash <dev@holbrook.no>
Date:   Mon,  7 Sep 2026 09:36:12 -0600

Add multiple hash support

Diffstat:
Madesse/attachment.py | 32++++++++++++++++++++++++--------
Madesse/crypto.py | 15++++++++++++++-
Madesse/store/base.py | 6++++++
Madesse/store/fs.py | 18+++++++++++++++++-
4 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/adesse/attachment.py b/adesse/attachment.py @@ -3,20 +3,30 @@ import hashlib from rdflib import Literal, DC, DCTERMS, XSD, RDF, BNode, Bag from adesse import Entity, rdfn -from adesse.crypto import Sums, sum_from_urn +from adesse.crypto import Sums, sum_from_urn, chk_sum from adesse.uri import to_uuid_uri from adesse.ns import DF +def to_df_sum(v): + if v == Sums.SHA256: + return DF.sumSHA256 + if v == Sums.SHA512: + return DF.sumSHA512 + raise ValueError() + + class Attachment(Entity): + default_sum = Sums.SHA256 + def __init__(self, title, description, date, mime, typ=None, lang=None, uu=None, opener=None): super().__init__(title, uu=uu) self.description = description self.dt = date.astimezone(datetime.timezone.utc) self.mime = mime self.typ = typ - self.sum = None + self.sums = {} self.tag = [] self.opener = opener self.source = [] @@ -35,13 +45,16 @@ class Attachment(Entity): def set_sum(self, v, typ=None): + if isinstance(v, str): + v = bytes.fromhex(v) if not isinstance(v, bytes): raise TypeError('sum not bytes') - if typ != None and typ != Sums.SHA256: - raise ValueError('sum must be sha256') - if len(v) > 32: - raise ValueError('sum must be sha256') - self.sum = v + if typ == None: + typ = Attachment.default_sum + if not isinstance(typ, Sums): + raise TypeError('invalid sub type') + chk_sum(typ, v) + self.sums[typ] = v def set_sum_from_url(self, v): @@ -70,7 +83,10 @@ class Attachment(Entity): g.add((uu, DC.format, Literal(self.mime))) g.add((uu, DCTERMS.title, Literal(self.common_name))) g.add((uu, DCTERMS.description, Literal(self.description))) - g.add((uu, DF.sumSHA256, Literal(self.sum.hex(), datatype=XSD.hexBinary))) + for k in self.sums.keys(): + v = self.sums[k] + prd = to_df_sum(k) + g.add((uu, prd, Literal(v.hex(), datatype=XSD.hexBinary))) g.add((uu, DCTERMS.created, Literal(self.dt.isoformat(timespec='seconds'), datatype=XSD.dateTime))) g.add((uu, RDF.type, DF.AttachmentData)) self._apply_tags(g.g, uu) diff --git a/adesse/crypto.py b/adesse/crypto.py @@ -1,7 +1,7 @@ import enum -class Sums(enum.Enum): +class Sums(enum.IntEnum): SHA256 = 32 SHA512 = 64 @@ -10,3 +10,16 @@ def sum_from_urn(v, scheme=None): if v[:11] != 'URN:sha256:': raise ValueError('only sha256 urn supported') return bytes.fromhex(v[11:]) + + +def chk_sum(typ, v): + if len(v) != typ.value: + raise ValueError() + + +def str_to_sumtype(v): + sumsidx = { + 'sha256': Sums.SHA256, + 'sha512': Sums.SHA512, + } + return sumsidx[v] diff --git a/adesse/store/base.py b/adesse/store/base.py @@ -1,7 +1,13 @@ import hashlib +import enum import uuid +class MetaType(enum.Enum): + ADESSE = ('-adesse.rdf', 'application/rdf+xml',) + XMP = ('.xmp', 'application/rdf+xml',) + + def hash_for_io(f, hasher): h = hasher() h.update(f.read()) diff --git a/adesse/store/fs.py b/adesse/store/fs.py @@ -3,7 +3,9 @@ import shutil import logging import tempfile -from .base import BaseStore +from .base import BaseStore, MetaType +from adesse import Serializer +from adesse.crypto import str_to_sumtype logg = logging.getLogger('store.fs') @@ -26,6 +28,10 @@ class FsStore(BaseStore): self.state = 1 + def canon_for(self, v): + return os.path.join(self.canon_path, v) + + def put(self, attachment): self._ensure_path() (f, fp) = tempfile.mkstemp() @@ -53,3 +59,13 @@ class FsStore(BaseStore): src = os.path.join(self.path, k, v.hex()) os.symlink(dst, src) logg.info('file link {} is {}'.format(k, src)) + typ = str_to_sumtype(k) + attachment.set_sum(v, typ=typ) + + dstmeta = dst + MetaType.ADESSE.value[0] + o = Serializer() + attachment.apply(o) + s = str(o) + w = open(dstmeta, 'w') + w.write(s) + w.close()