Initial commit; nothing works yet
This commit is contained in:
commit
a599d133f4
20 changed files with 954 additions and 0 deletions
63
src/dog_and_duck/quack/quack.clj
Normal file
63
src/dog_and_duck/quack/quack.clj
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(ns dog-and-duck.quack.quack
|
||||
"Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck..."
|
||||
;;(:require [clojure.spec.alpha as s])
|
||||
(:import [java.net URI URISyntaxException]))
|
||||
|
||||
(defn object?
|
||||
"Return `true` iff `x` is recognisably an ActivityStreams object.
|
||||
|
||||
**NOTE THAT** The ActivityStreams spec
|
||||
[says](https://www.w3.org/TR/activitystreams-core/#object):
|
||||
|
||||
> All properties are optional (including the id and type)
|
||||
|
||||
But we are *just not having that*, because otherwise we're flying blind.
|
||||
We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
||||
tolerable because they represent transient objects, which we expect to
|
||||
handle."
|
||||
[x]
|
||||
(and (map? x) (:type x) true))
|
||||
|
||||
(object? nil)
|
||||
(object? {:type "test"})
|
||||
|
||||
(defn persistent-object?
|
||||
"`true` iff `x` is a persistent object.
|
||||
|
||||
Transient objects in ActivityPub are not required to have an `id` key, but persistent
|
||||
ones must have a key, and it must be an IRI (but normally a URI)."
|
||||
[x]
|
||||
(try
|
||||
(and (object? x) (uri? (URI. (:id x))))
|
||||
(catch URISyntaxException _ false)))
|
||||
|
||||
(persistent-object? {:type "test" :id "https://mastodon.scot/@barfilfarm"})
|
||||
|
||||
(defn actor?
|
||||
"TODO!"
|
||||
[x]
|
||||
true)
|
||||
|
||||
(def verb?
|
||||
"The set of types we will accept as verbs.
|
||||
|
||||
There's an [explicit set of allowed verbs]
|
||||
(https://www.w3.org/TR/activitystreams-vocabulary/#activity-types)."
|
||||
#{"Accept" "Add" "Announce" "Arrive" "Block" "Create" "Delete" "Dislike"
|
||||
"Flag" "Follow" "Ignore" "Invite" "Join" "Leave" "Like" "Listen" "Move"
|
||||
"Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept"
|
||||
"TentativeReject" "Travel" "Undo" "Update" "View"})
|
||||
|
||||
(defn activity?
|
||||
"`true` iff `x` is an activity, else false.
|
||||
|
||||
see "
|
||||
[x]
|
||||
(try
|
||||
(and (object? x)
|
||||
(uri? (URI. ((keyword "@context") x)))
|
||||
(string? (:summary x))
|
||||
(actor? (:actor x))
|
||||
(verb? (:type x))
|
||||
(or (object? (:object x)) (uri? (URI. x))))
|
||||
(catch URISyntaxException _ false)))
|
||||
6
src/dog_and_duck/scratch/core.clj
Normal file
6
src/dog_and_duck/scratch/core.clj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(ns dog-and-duck.scratch.core)
|
||||
|
||||
(defn foo
|
||||
"I don't do a whole lot."
|
||||
[x]
|
||||
(println x "Hello, World!"))
|
||||
20
src/dog_and_duck/scratch/parser.clj
Normal file
20
src/dog_and_duck/scratch/parser.clj
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
(ns dog-and-duck.scratch.parser
|
||||
(:require [clojure.walk :refer [keywordize-keys]]
|
||||
[clojure.data.json :as json]
|
||||
[dog-and-duck.quack.quack :as q]))
|
||||
|
||||
(defn clean
|
||||
"Take this `json` input, and return a sequence of ActivityPub objects
|
||||
represented by it."
|
||||
[json]
|
||||
(let [feed (json/read-str json)]
|
||||
(filter
|
||||
q/object?
|
||||
(cond (map? feed) (list (keywordize-keys feed))
|
||||
(coll? feed) (map keywordize-keys feed)))))
|
||||
|
||||
(map :type (map keywordize-keys (json/read-str (slurp "resources/feed.json"))))
|
||||
|
||||
(keys (first (map keywordize-keys (json/read-str (slurp "resources/feed.json")))))
|
||||
|
||||
(q/object? (first (map keywordize-keys (json/read-str (slurp "resources/feed.json")))))
|
||||
44
src/dog_and_duck/scratch/scratch.clj
Normal file
44
src/dog_and_duck/scratch/scratch.clj
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
(ns dog-and-duck.scratch.scratch
|
||||
"Scratchpad where I try to understand how to do this stuff."
|
||||
(:require [clj-activitypub.core :as activitypub]
|
||||
[clj-activitypub.webfinger :as webfinger]
|
||||
[clj-pgp.core :as pgp]
|
||||
[clj-pgp.keyring :as keyring]
|
||||
[clj-pgp.generate :as pgp-gen]
|
||||
[clojure.walk :refer [keywordize-keys]]
|
||||
[clojure.pprint :refer [pprint]]))
|
||||
|
||||
;;; Use any ActivityPub account handle you like - for example, your own
|
||||
(def account-handle "@simon_brooke@mastodon.scot")
|
||||
|
||||
(def handle (activitypub/parse-account account-handle))
|
||||
(webfinger/fetch-user-id "mastodon.scot" "simon_brooke")
|
||||
(apply webfinger/fetch-user-id (map handle [:domain :username]))
|
||||
|
||||
;;; Retrieve the account details from its home server
|
||||
;;; (`keywordize-keys` is not necessary here but produces a more idiomatic clojure
|
||||
;;; data structure)
|
||||
(def account
|
||||
"Fetch my account to mess with"
|
||||
(let [handle (activitypub/parse-account account-handle)]
|
||||
(keywordize-keys
|
||||
(activitypub/fetch-user
|
||||
(apply webfinger/fetch-user-id (map handle [:domain :username]))))))
|
||||
|
||||
;;; examine what you got back!
|
||||
(:outbox account)
|
||||
|
||||
|
||||
(def rsa (pgp-gen/rsa-keypair-generator 2048))
|
||||
(def kp (pgp-gen/generate-keypair rsa :rsa-general))
|
||||
|
||||
;; how we make a public/private key pair. But this key pair is not the one
|
||||
;; known to mastodon.scot as my key pair, so that doesn't get us very far...
|
||||
;; I think.
|
||||
(let [rsa (pgp-gen/rsa-keypair-generator 2048)
|
||||
kp (pgp-gen/generate-keypair rsa :rsa-general)
|
||||
public (-> kp .getPublicKey .getEncoded)
|
||||
private (-> kp .getPrivateKey .getPrivateKeyDataPacket .getEncoded)]
|
||||
(println (str "Public key: " public))
|
||||
(println (str "Private key: " private))
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue