(ns org.domaindrivenarchitecture.activity-pub-poc.activitystreams2-legacy (:require [clojure.spec.alpha :as s] [org.domaindrivenarchitecture.activity-pub-poc.owl :as owl] [org.domaindrivenarchitecture.activity-pub-poc.core :as core])) ; TODO: We could do these with multispec, but that is too much for a POC (def objectAndLinkTypes #{; Object Types "Article" "Audio" "Collection" "Document" "Event" "Image" "Note" "Object" "OrderedCollection" "Page" "Place" "Profile" "Relationship" "Tombstone" "Video" "Link" ; Link Types "Mention"}) (defn match-type [type] #(= (:type %) type)) (s/def ::Object (s/or :uri core/uri-string? :map (s/and (s/keys :req-un [::id ::type] :opt-un [::attributedTo ::und-mehr]) (match-type "Object")))) ;http://www.w3.org/ns/activitystreams#id ;TODO: how do we translate this? rdfs:domain [a owl:Class ; owl:unionOf (as:Link as:Object)] ;TODO evtl sind ::owl/FunctionalProperty, ::owl/DatatypeProperty, ::owl/DeprecatedProperty nur meta informationen? (s/def ::id (s/and ::owl/FunctionalProperty ::owl/DatatypeProperty ::owl/DeprecatedProperty core/uri-string?)) ;TODO: we will need such a predicate ... ;(defn-spec isFunctional? bool? ; [spec keyword?] ; (search-in-meta spec)) ; TODO: type can have multiple values!! Affects also the fct match-type and all specs that uses it! (s/def ::type #(or (core/uri-string? %) (contains? objectAndLinkTypes %))) (s/def ::Link (s/and (s/keys :req-un [::type] :opt-un [::attributedTo ::und-mehr]) (match-type "Link"))) (s/def ::Relationship (s/keys :req-un [::object ::und-mehr])) ; #### Collection #### (s/def ::Collection (s/and ::Object (s/keys :opt-un [::totalItems ::current ::first ::last ; FUNCTIONAL properties! ::items]) ;"items" is not a FUNCTIONAL property! (match-type "Collection"))) ; Side note: A property marked as FUNCTIONAL does not mean that this property is required for the respective Object. ; Example: The property "replies" is FUNCTIONAL for "Object" but is an optional property for "Object". (s/def ::OrderedCollection (s/and ::Collection (match-type "OrderedCollection"))) ; #### NOTE #### ; Specialities of mastodon statuses: https://docs.joinmastodon.org/spec/activitypub/#status (s/def ::Note (s/and ::Object ;(match-type "Note") (s/keys :opt-un [::likes]))) (s/def ::likes (s/or :collection ::Collection :ordered-collection ::OrderedCollection)) ; #### ACTIVITY #### (s/def ::Activity (s/and ::Object (s/keys :req-un [::actor ::object] :opt-un [::result ::target ::origin ::instrument ::verb]))) ; "IntransitiveActivity" erbt von Activity, aber ohne ::object (s/def ::Property (s/or :object ::Object :link ::Link :collection (s/coll-of (s/or :object ::Object :link ::Link)))) (s/def ::attributedTo ::Property) (s/def ::actor ::attributedTo) (s/def ::object ::Property) (s/def ::result ::Property) (s/def ::target ::Property) (s/def ::origin ::Property) (s/def ::instrument ::Property) (s/def ::verb core/uri-string?) ; #### LIKE #### (s/def ::Like (s/and ::Activity (match-type "Like"))) ; Was beim Type Activity optional und required ist, ist abhängig vom Aktivitätstyp. ; Bspw brauch ein Like einen actor und den type "Like" und (xor) target/object. ; Aber die "IntransitiveActivity" (die alles von Activity erbt außer "object") vom Type "Question" besitzt keinen "actor". (def maybeLike? {:id "https://social.bla/alyssa#likes/RANDOMHASH", :type "Like", :actor "https://social.bla/alyssa", :object "https://chatty.bla/ben/posts/234s23-2g34234-2hhj536"}) (def testLink {:context "https://www.w3.org/ns/activitystreams", :type "Link", :href "http://example.org/abc", :hreflang "en", :mediaType "text/html", :name "An example link"}) (def testObject {:context "https://www.w3.org/ns/activitystreams", :type "Note", :id "https://social.bla/alyssa", :href "http://example.org/abc", :hreflang "en", :mediaType "text/html", :name "An example object"})