adesse

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs

commit bd16a7342fce2870d408b4ad8b5b7c5f94bc0565
parent 69ab1d1c984307e8d3e5aa9647d04028ffc7233e
Author: lash <dev@holbrook.no>
Date:   Wed, 24 Sep 2025 03:58:19 +0100

AADd bundle, event, claim, testimony WIP

Diffstat:
Madesse/base.py | 5+++--
Madesse/bundle.py | 17+++++++++++++----
Madesse/cert.py | 6++++--
Aadesse/claim.py | 22++++++++++++++++++++++
Madesse/entity.py | 6++++--
Aadesse/event.py | 34++++++++++++++++++++++++++++++++++
Madesse/ns.py | 20++++++++++++++++----
Aadesse/org.py | 15+++++++++++++++
Madesse/person.py | 17++++++++---------
Aadesse/testimony.py | 16++++++++++++++++
Aadesse/venue.py | 2++
Mpyproject.toml | 1+
Mtest/test_serialize.py | 14++++++++++----
13 files changed, 148 insertions(+), 27 deletions(-)

diff --git a/adesse/base.py b/adesse/base.py @@ -2,7 +2,7 @@ from rdflib import Graph from rdflib.namespace import NamespaceManager from rdflib.namespace import FOAF, XSD, PROV, DC, DCTERMS -from .ns import DF, COUNTRY, PSS +from .ns import DF, COUNTRY, PSS, UU class Serializer: @@ -10,6 +10,7 @@ class Serializer: def __init__(self): self.g = Graph() self.ns = NamespaceManager(self.g) + self.ns.bind('uuid', UU) self.ns.bind('dc', DC) self.ns.bind('prov', PROV) self.ns.bind('xsd', XSD) @@ -23,4 +24,4 @@ class Serializer: def __str__(self): - return self.g.serialize(format='xml') + return self.g.serialize(format='turtle') diff --git a/adesse/bundle.py b/adesse/bundle.py @@ -1,8 +1,17 @@ -from .base import Base +from .entity import Entity +from .uri import to_uuid_uri -class Bundle: +class Bundle(Entity): - def __init__(self, crt): + def __init__(self, label, crt, uu=None): + super().__init__(label, uu=uu) self.cert = crt - self.witness = [] + self.testimony = [] + + + def apply(self, g): + uu = to_uuid_uri(self.uu) + self.cert.apply(g) + for v in self.testimony: + v.apply(g) diff --git a/adesse/cert.py b/adesse/cert.py @@ -5,8 +5,8 @@ from .entity import Entity class Cert(Entity): - def __init__(self, subj, obj, agent, uu=None): - super().__init__(uu=uu) + def __init__(self, subj, obj, agent, uu=None, title=None): + super().__init__(str(uu), uu=uu) self.subject = subj self.object = obj self.agent = agent @@ -22,3 +22,5 @@ class Cert(Entity): g.add((uu, DF.agent, o)) self.subject.apply(g) + self.object.apply(g) + self.agent.apply(g) diff --git a/adesse/claim.py b/adesse/claim.py @@ -0,0 +1,22 @@ +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 @@ -10,13 +10,15 @@ from .uri import to_uuid_uri class Entity: - def __init__(self, uu=None): + def __init__(self, common_name, uu=None): if not uu: uu = uuid.uuid4() elif not isinstance(uu, uuid.UUID): raise ValueError("not uuid") self.uu = uu self.dt = datetime.datetime.now() + self.dt = self.dt.astimezone(datetime.timezone.utc) + self.common_name = common_name self.url = None @@ -33,6 +35,6 @@ class Entity: def apply(self, g): uu = to_uuid_uri(self.uu) - g.add((uu, DCTERMS.created, Literal(self.dt.isoformat(), datatype=XSD.dateTime))) + g.add((uu, DCTERMS.created, Literal(self.dt.isoformat(timespec='seconds'), datatype=XSD.dateTime))) if self.url: g.add((uu, FOAF.homepage, Literal(self.url))) diff --git a/adesse/event.py b/adesse/event.py @@ -0,0 +1,34 @@ +import datetime + +from rdflib import Literal +from rdflib.namespace import PROV, XSD, RDF +from rdflib.term import URIRef + +from .entity import Entity +from .ns import DF +from .uri import to_uuid_uri + + +class Event(Entity): + + def __init__(self, title, start: datetime.datetime, end: datetime.datetime, uu=None): + super().__init__(title, uu=uu) + self.dtstart = start + self.dtend = end + self.topic = [] + + + def add_topic(self, v): + if not isinstance(v, URIRef): + if not instance(v, str): + raise TypeError("topic must be URIRef or string") + v = URIRef(v) + self.cat.append(v) + + + def apply(self, g): + uu = to_uuid_uri(self.uu) + g.add((uu, PROV.startedAtTime, Literal(self.dtstart.isoformat(timespec='seconds'), datatype=XSD.dateTime))) + g.add((uu, PROV.endedAtTime, Literal(self.dtend.isoformat(timespec='seconds'), datatype=XSD.dateTime))) + g.add((uu, RDF.type, DF.Event)) + super().apply(g) diff --git a/adesse/ns.py b/adesse/ns.py @@ -1,23 +1,35 @@ from rdflib.namespace import Namespace, DefinedNamespace from rdflib.term import URIRef +UU = Namespace('URN:uuid:') + COUNTRY = Namespace('http://www.iso.org/obp/ui/#iso:code:3166:') +SHA256 = Namespace('URN:sha256:') + class DF(DefinedNamespace): subject: URIRef object: URIRef agent: URIRef + Event: URIRef + + # perceptionmedium + inPerson: URIRef _NS = Namespace('http://defalsify.org/rdf/0.1/core/') class PSS(DefinedNamespace): - Topic: URIRef - Nationality: URIRef - ResidenceCountry: URIRef + topic: URIRef + nationality: URIRef + residenceCountry: URIRef + + Person: URIRef + + PRINT3D: URIRef - _NS = Namespace('http://standards.internetofproduction.org/pub/r7g0n9fo/release/4') + _NS = Namespace('http://standards.internetofproduction.org/pub/r7g0n9fo/release/4#') class WOT(DefinedNamespace): diff --git a/adesse/org.py b/adesse/org.py @@ -0,0 +1,15 @@ +from adesse import Entity + +from rdflib import Literal +from rdflib.namespace import FOAF, RDF + +from .uri import to_uuid_uri + + +class Org(Entity): + + def apply(self, g): + uu = to_uuid_uri(self.uu) + g.add((uu, FOAF.name, Literal(self.common_name))) + g.add((uu, RDF.type, FOAF.Organization)) + super().apply(g) diff --git a/adesse/person.py b/adesse/person.py @@ -1,5 +1,5 @@ from rdflib import Literal -from rdflib.namespace import FOAF +from rdflib.namespace import FOAF, RDF from .entity import Entity from .ns import PSS @@ -9,7 +9,9 @@ from .uri import to_uuid_uri, to_country_uri class Person(Entity): def __init__(self, firstname, lastname, nationality, residence_country=None, common_name=None, uu=None): - super().__init__(uu=uu) + if not common_name: + common_name = firstname + ' ' + lastname + super().__init__(common_name, uu=uu) self.firstname = firstname self.lastname = lastname self.nationality = nationality @@ -17,16 +19,13 @@ class Person(Entity): self.residence_country = residence_country else: self.residence_country = nationality - if common_name: - self.common_name = common_name - else: - self.common_name = self.firstname + ' ' + self.lastname - + def apply(self, g): uu = to_uuid_uri(self.uu) g.add((uu, FOAF.givenName, Literal(self.firstname))) g.add((uu, FOAF.familyName, Literal(self.lastname))) g.add((uu, FOAF.name, Literal(self.common_name))) - g.add((uu, PSS.Nationality, to_country_uri(self.nationality))) - g.add((uu, PSS.ResidenceCountry, to_country_uri(self.residence_country))) + g.add((uu, PSS.nationality, to_country_uri(self.nationality))) + g.add((uu, PSS.residenceCountry, to_country_uri(self.residence_country))) + g.add((uu, RDF.type, PSS.Person)) super().apply(g) diff --git a/adesse/testimony.py b/adesse/testimony.py @@ -0,0 +1,16 @@ +import datetime + +class Testimony(Entity): + + def __init__(self, label, date: datetime.datetime, target, identity, medium=DF.inPerson, uu=None): + super().__init__(label, uu=uu) + self.medium = medium + self.dt = date + self.target = target + self.identity = identity + self.claim = [] + self.behalf = [] + + + def add_claim(self, v): + self.claim.append(v) diff --git a/adesse/venue.py b/adesse/venue.py @@ -0,0 +1,2 @@ +class Org(Entity): + pass diff --git a/pyproject.toml b/pyproject.toml @@ -11,6 +11,7 @@ dependencies = [ "lxml~=6.0.1", "rdflib~=7.2.1", "iso3166~=2.1.1", + "python-mimeparse~=2.0.0", ] [project.scripts] diff --git a/test/test_serialize.py b/test/test_serialize.py @@ -1,8 +1,12 @@ import unittest +import datetime from adesse import Serializer, Entity from adesse.person import Person +from adesse.org import Org from adesse.cert import Cert +from adesse.event import Event +from adesse.bundle import Bundle class TestSerialize(unittest.TestCase): @@ -16,10 +20,12 @@ class TestSerialize(unittest.TestCase): z = Serializer() subj = Person("Melvin", "Ferd", "SV", common_name="Melvin B. Ferd") subj.set_url('http://rotten.com') - obj = Entity() - agent = Entity() - c = Cert(subj, obj, agent) - c.apply(z) + obj = Event('foo', datetime.datetime.fromtimestamp(1758673250), datetime.datetime.fromtimestamp(1758679250)) + agent = Org("Toxic Mopping Inc.") + agent.set_url('http://foo.xyz') + crt = Cert(subj, obj, agent) + o = Bundle('bundle in the jungle', crt) + o.apply(z) print(str(z))