commit 93faf56e03006afdc6553d2ec7fc644fe057449c
parent bd16a7342fce2870d408b4ad8b5b7c5f94bc0565
Author: lash <dev@holbrook.no>
Date: Wed, 24 Sep 2025 04:56:44 +0100
Add claims, behalf list in testimony
Diffstat:
10 files changed, 121 insertions(+), 25 deletions(-)
diff --git a/adesse/__init__.py b/adesse/__init__.py
@@ -1,2 +1,8 @@
from .base import Serializer
from .entity import Entity
+from .org import Org
+from .cert import Cert
+from .event import Event
+from .bundle import Bundle
+from .testimony import Testimony
+from .attachment import Attachment
diff --git a/adesse/attachment.py b/adesse/attachment.py
@@ -0,0 +1,41 @@
+import datetime
+import hashlib
+
+from rdflib import Literal, DC, DCTERMS, XSD, RDF
+from adesse import Entity
+from adesse.uri import to_uuid_uri
+from adesse.ns import DF
+
+
+class Attachment(Entity):
+
+ def __init__(self, title, description, date, mime, typ=None, lang=None, uu=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
+
+
+ def set_sum(self, v):
+ if not isinstance(v, bytes):
+ raise TypeError('sum not bytes')
+ if len(v) > 32:
+ raise ValueError('sum must be sha256')
+ self.sum = v
+
+
+ def set_sum_from_url(self, v):
+ raise NotImplementedError()
+
+
+ def apply(self, g):
+ uu = to_uuid_uri(self.uu)
+ 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.sum, Literal(self.sum.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))
+ super().apply(g)
diff --git a/adesse/bundle.py b/adesse/bundle.py
@@ -8,6 +8,10 @@ class Bundle(Entity):
super().__init__(label, uu=uu)
self.cert = crt
self.testimony = []
+
+
+ def add_testimony(self, v):
+ self.testimony.append(v)
def apply(self, g):
diff --git a/adesse/claim.py b/adesse/claim.py
@@ -1,22 +0,0 @@
-import hashlib
-
-from mimeparse import parse_mime_type
-
-class Attachment(Entity):
-
- def __init__(self, title, description, date, mime, fmt=None, lang=None, uu=None):
- super().__init__(title, uu=uu)
- self.description = description
- self.date = date
- mimeparts = parse_mime_type(mime)
- self.mime = mimeparts
- self.fmt = fmt
- self.sum = None
-
-
- def set_sum(self, v):
- self.sum = v
-
-
- def set_sum_from_file(self, v):
- pass
diff --git a/adesse/entity.py b/adesse/entity.py
@@ -32,7 +32,7 @@ class Entity:
def to_ref(self):
return to_uuid_uri(self.uu)
-
+
def apply(self, g):
uu = to_uuid_uri(self.uu)
g.add((uu, DCTERMS.created, Literal(self.dt.isoformat(timespec='seconds'), datatype=XSD.dateTime)))
diff --git a/adesse/event.py b/adesse/event.py
@@ -14,7 +14,9 @@ class Event(Entity):
def __init__(self, title, start: datetime.datetime, end: datetime.datetime, uu=None):
super().__init__(title, uu=uu)
self.dtstart = start
+ self.dtstart = self.dtstart.astimezone(datetime.timezone.utc)
self.dtend = end
+ self.dtend = self.dtend.astimezone(datetime.timezone.utc)
self.topic = []
diff --git a/adesse/ns.py b/adesse/ns.py
@@ -7,15 +7,28 @@ COUNTRY = Namespace('http://www.iso.org/obp/ui/#iso:code:3166:')
SHA256 = Namespace('URN:sha256:')
+MIME = Namespace('http://www.iana.org/assignments/media-types/')
+
class DF(DefinedNamespace):
subject: URIRef
object: URIRef
agent: URIRef
+ perceivedThrough: URIRef
+ verdict: URIRef
+ hasClaim: URIRef
+ testimonyFor: URIRef
+
+ # classes
Event: URIRef
+ AttachmentData: URIRef
+ Testimony: URIRef
# perceptionmedium
inPerson: URIRef
+ # results
+ certified: URIRef
+
_NS = Namespace('http://defalsify.org/rdf/0.1/core/')
diff --git a/adesse/testimony.py b/adesse/testimony.py
@@ -1,5 +1,11 @@
import datetime
+from rdflib import Literal, PROV, XSD, RDF
+from adesse import Entity
+from adesse.ns import DF
+from adesse.uri import to_uuid_uri
+
+
class Testimony(Entity):
def __init__(self, label, date: datetime.datetime, target, identity, medium=DF.inPerson, uu=None):
@@ -10,7 +16,29 @@ class Testimony(Entity):
self.identity = identity
self.claim = []
self.behalf = []
+ self.verdict = DF.certified
def add_claim(self, v):
self.claim.append(v)
+
+
+ def add_behalf(self, v):
+ self.behalf.append(v)
+
+
+ def apply(self, g):
+ uu = to_uuid_uri(self.uu)
+ g.add((uu, RDF.type, DF.Testimony))
+ g.add((uu, DF.perceivedTime, Literal(self.dt.isoformat(timespec='seconds'), datatype=XSD.dateTime)))
+ g.add((uu, DF.perceivedThrough, DF.inPerson))
+ g.add((uu, DF.verdict, self.verdict))
+ g.add((uu, DF.testimonyFor, self.target.to_ref()))
+ g.add((uu, DF.hasIdentity, self.identity))
+ for v in self.behalf:
+ g.add((uu, PROV.actedOnBehalfOf, v))
+ for v in self.claim:
+ g.add((uu, DF.hasClaim, v.to_ref()))
+ for v in self.claim:
+ v.apply(g)
+ super().apply(g)
diff --git a/adesse/uri.py b/adesse/uri.py
@@ -1,5 +1,6 @@
from uuid import UUID
+from mimeparse import parse_mime_type
from iso3166 import countries
from rdflib import Literal
from rdflib.namespace import Namespace
@@ -7,10 +8,18 @@ from rdflib.namespace import URIPattern
from rdflib.namespace import URIRef
from rdflib.namespace import XSD
-from .ns import COUNTRY
+from .ns import COUNTRY, MIME
uu = URIPattern("URN:uuid:%s")
+
+def to_mime_uri(v):
+ if not u:
+ raise ValueError("undefined uuid")
+ parse_mime_type(v)
+ return MIME[v]
+
+
def to_uuid_uri(u):
if not u:
raise ValueError("undefined uuid")
@@ -27,5 +36,4 @@ def to_country_uri(s):
pass
if v == None:
raise ValueError('invalid country: ' + s)
- #return URIRef(v.alpha2, datatype=XSD.Datetime)
return COUNTRY[v.alpha2]
diff --git a/test/test_serialize.py b/test/test_serialize.py
@@ -1,5 +1,8 @@
import unittest
import datetime
+import hashlib
+
+from rdflib.term import URIRef
from adesse import Serializer, Entity
from adesse.person import Person
@@ -7,6 +10,8 @@ from adesse.org import Org
from adesse.cert import Cert
from adesse.event import Event
from adesse.bundle import Bundle
+from adesse.testimony import Testimony
+from adesse.attachment import Attachment
class TestSerialize(unittest.TestCase):
@@ -25,6 +30,17 @@ class TestSerialize(unittest.TestCase):
agent.set_url('http://foo.xyz')
crt = Cert(subj, obj, agent)
o = Bundle('bundle in the jungle', crt)
+ v = Testimony('testify', datetime.datetime.now(), crt, URIRef('did:deadbeef'))
+ d = Attachment('some medium', 'foo baz bar', datetime.datetime.now(), 'image/png')
+ h = hashlib.sha256()
+ h.update(b'foo')
+ d.set_sum(h.digest())
+ v.add_claim(d)
+
+ b = URIRef('http://internetofproduction.org')
+ v.add_behalf(b)
+
+ o.add_testimony(v)
o.apply(z)
print(str(z))