Documentation
This commit is contained in:
parent
b2ff133e4a
commit
ed7d4e22f1
|
@ -1,5 +1,6 @@
|
|||
# Using ActivityPub
|
||||
|
||||
```clojure
|
||||
user=> (require '[clj-activitypub.core :as activitypub])
|
||||
nil
|
||||
user=> (require '[clj-activitypub.webfinger :as webfinger])
|
||||
|
@ -108,3 +109,4 @@ user=> (pprint sb)
|
|||
:name "Home Page",
|
||||
:value
|
||||
"<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]}
|
||||
```
|
||||
|
|
83
doc/intro.md
83
doc/intro.md
|
@ -1,3 +1,82 @@
|
|||
# Introduction to dog-and-duck
|
||||
# The Old Dog and Duck
|
||||
|
||||
TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
|
||||
A Clojure library designed to implement the ActivityPub protocol, obviously.
|
||||
|
||||
## Introduction
|
||||
|
||||
The Old Dog and Duck is clearly a pub, and it's a pub related to an activity; to whit, hunting ducks with dogs. Yes, of course one could also hunt dogs with ducks, but in practice that doesn't work so well. The point isn't whether or not I approve of hunting ducks with dogs (or vice versa); to be clear, I don't. The point is that it's a pub related to an activity, and is therefore an [ActivityPub](https://www.w3.org/TR/activitypub/).
|
||||
|
||||
Are we clear?
|
||||
|
||||
Good.
|
||||
|
||||
Let us proceed.
|
||||
|
||||
**The Old Dog and Duck** is intended to be a set of libraries to enable people to build stuff which interacts with ActivityPub. It isn't intended to be a replacement for, or clone of, Mastodon. I do think I might implement my own ActivityPub server on top of The Old Dog and Duck, that specifically might allow for user-pluggable feed-sorting algorithms and with my own user interface/user experience take, but that project is not (yet, at any rate) this project.
|
||||
|
||||
## Status
|
||||
|
||||
This is a long way pre-alpha. Everything will change. Feel free to play, but do so at your own risk. Contributions welcome.
|
||||
|
||||
## Architecture
|
||||
|
||||
There are a number of separate concerns required to implement ActivityPub. They include
|
||||
|
||||
1. Parsing ActivityStreams messages received from peers and from clients;
|
||||
2. Persisting ActivityStreams objects;
|
||||
3. Delivering ActivityStreams objects to peers;
|
||||
4. Delivering ActivityStreams objects to clients.
|
||||
|
||||
**NOTE THAT** what Mastodon delivers to clients is not actually in ActivityStreams format; this seems to be an ad-hoc hack that's just never been fixed and has therefore become a de-facto standard for communication between ActivityPub hosts and their clients.
|
||||
|
||||
My proposal would be to deliver exactly the same ActivityStreams format to my client as to other servers. There may be a valid reason for not doing this, but if there is I will discover it in due course.
|
||||
|
||||
## Proposed dog-and-duck libraries
|
||||
|
||||
**NOTE THAT** at the present stage all the proposed libraries are in one package, namely this package, but that it is proposed that in future they will form separate libraries in separate packages.
|
||||
|
||||
### Bar
|
||||
|
||||
Where conversations happen. Handle interactions with clients.
|
||||
|
||||
### Cellar
|
||||
|
||||
Where things are stored. Persistance for ActivityStreams objects; I may at least initially simply copy the Mastodon postgres schema, but equally I may not.
|
||||
|
||||
### Pantry
|
||||
|
||||
Where deliveries are ordered and arrive; and from where deliveries onwards are despatched. Handle interactions with peers.
|
||||
|
||||
### Quack
|
||||
|
||||
Duck-typing for ActivityStreams objects.
|
||||
|
||||
As of version 0.1.0, this is substantially the only part that is yet at all useful, and it is still a long way from finished or robust.
|
||||
|
||||
### Scratch
|
||||
|
||||
What the dog does when bored. Essentially, a place where I can learn how to make this stuff work, but perhaps eventually an ActivityPub server in its own right.
|
||||
|
||||
## Usage
|
||||
|
||||
At present, only the duck-typing functions work. To play with them, use
|
||||
|
||||
```clojure
|
||||
(require '[dog-and-duck.quack.quack :as q])
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Prior to testing, you should clone [activitystreams-test-documents](https://github.com/w3c-social/activitystreams-test-documents) into the `resources` directory. You can then test with
|
||||
|
||||
```bash
|
||||
lein test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Simon Brooke, 2022.
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
|
449
docs/cloverage/clj_activitypub/core.clj.html
Normal file
449
docs/cloverage/clj_activitypub/core.clj.html
Normal file
|
@ -0,0 +1,449 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> clj_activitypub/core.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns clj-activitypub.core
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clj-activitypub.internal.crypto :as crypto]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [clj-activitypub.internal.thread-cache :as thread-cache]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clj-activitypub.internal.http-util :as http]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [clj-http.client :as client]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [clojure.string :as str]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
008 (defn config
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 "Creates hash of computed data relevant for most ActivityPub utilities."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [{:keys [domain username username-route public-key private-key]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 :or {username-route "/users/"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 public-key nil
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 private-key nil}}]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
014 (let [base-url (str "https://" domain)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
015 {:domain domain
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
016 :base-url base-url
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
017 :username username
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
018 :user-id (str base-url username-route username)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
019 :public-key public-key
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
020 :private-key (when private-key
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
021 (crypto/private-key private-key))}))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
022
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 (defn parse-account
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 "Given an ActivityPub handle (e.g. @jahfer@mastodon.social), produces
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 a map containing {:domain ... :username ...}."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 [handle]
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
027 (let [[username domain] (filter #(not (str/blank? %))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
028 (str/split handle #"@"))]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
029 {:domain domain :username username}))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
030
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
031 (def ^:private user-cache (thread-cache/make))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
032 (defn fetch-user
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 "Fetches the customer account details located at user-id from a remote
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 server. Will return cached results if they exist in memory."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 [user-id]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
036 ((:get-v user-cache)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
037 user-id
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
038 #(:body
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
039 (client/get user-id {:as :json-string-keys
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 :throw-exceptions false
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 :ignore-unknown-host? true
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
042 :headers {"Accept" "application/activity+json"}}))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
044 (defn actor
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 "Accepts a config, and returns a map in the form expected by the ActivityPub
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 spec. See https://www.w3.org/TR/activitypub/#actor-objects for reference."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 [{:keys [user-id username public-key]}]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
048 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 "https://w3id.org/security/v1"]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
050 :id user-id
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 :type "Person"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
052 :preferredUsername username
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
053 :inbox (str user-id "/inbox")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
054 :outbox (str user-id "/outbox")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
055 :publicKey {:id (str user-id "#main-key")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
056 :owner user-id
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
057 :publicKeyPem (or public-key "")}})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
058
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
059 (def signature-headers ["(request-target)" "host" "date" "digest"])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
060
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
061 (defn- str-for-signature [headers]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
062 (let [headers-xf (reduce-kv
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
063 (fn [m k v]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
064 (assoc m (str/lower-case k) v)) {} headers)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
065 (->> signature-headers
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
066 (select-keys headers-xf)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
067 (reduce-kv (fn [coll k v] (conj coll (str k ": " v))) [])
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
068 (interpose "\n")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
069 (apply str))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
070
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
071 (defn gen-signature-header
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 "Generates a HTTP Signature string based on the provided map of headers."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 [config headers]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
074 (let [{:keys [user-id private-key]} config
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
075 string-to-sign (str-for-signature headers)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
076 signature (crypto/base64-encode (crypto/sign string-to-sign private-key))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
077 sig-header-keys {"keyId" user-id
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
078 "headers" (str/join " " signature-headers)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
079 "signature" signature}]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
080 (->> sig-header-keys
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
081 (reduce-kv (fn [m k v]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
082 (conj m (str k "=" "\"" v "\""))) [])
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
083 (interpose ",")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
084 (apply str))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
085
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
086 (defn auth-headers
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 "Given a config and request map of {:body ... :headers ...}, returns the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 original set of headers with Signature and Digest attributes appended."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 [config {:keys [body headers]}]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
090 (let [digest (http/digest body)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
091 h (-> headers
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
092 (assoc "Digest" digest)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
093 (assoc "(request-target)" "post /inbox"))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
094 (assoc headers
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
095 "Signature" (gen-signature-header config h)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
096 "Digest" digest)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
097
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
098 (defmulti obj
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 "Produces a map representing an ActivityPub object which can be serialized
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 4 forms covered">
|
||||
102 (fn [_config object-data] (:type object-data)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
103
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
104 (defmethod obj :note
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
105 [{:keys [user-id]}
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
106 {:keys [id published inReplyTo content to]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
107 :or {published (http/date)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
108 inReplyTo ""
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 to "https://www.w3.org/ns/activitystreams#Public"}}]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
110 {"id" (str user-id "/notes/" id)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 "type" "Note"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
112 "published" published
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
113 "attributedTo" user-id
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
114 "inReplyTo" inReplyTo
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
115 "content" content
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
116 "to" to})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
117
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
118 (defmulti activity
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119 "Produces a map representing an ActivityPub activity which can be serialized
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
120 directly to JSON in the form expected by the ActivityStreams 2.0 spec.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
121 See https://www.w3.org/TR/activitystreams-vocabulary/ for reference."
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 2 forms covered">
|
||||
122 (fn [_config activity-type _data] activity-type))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
123
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
124 (defmethod activity :create [{:keys [user-id]} _ data]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
125 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
126 "https://w3id.org/security/v1"]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 "type" "Create"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
128 "actor" user-id
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
129 "object" data})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
130
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
131 (defmethod activity :delete [{:keys [user-id]} _ data]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
132 {"@context" ["https://www.w3.org/ns/activitystreams"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 "https://w3id.org/security/v1"]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
134 "type" "Delete"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
135 "actor" user-id
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
136 "object" data})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
137
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
138 (defn with-config
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 "Returns curried forms of the #activity and #obj multimethods in the form
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 {:activity ... :obj ...}, with the initial parameter set to config."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 [config]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
142 (let [f (juxt
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
143 #(partial activity %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
144 #(partial obj %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
145 [activity-fn obj-fn] (f config)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
146 {:activity activity-fn
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
147 :obj obj-fn}))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
116
docs/cloverage/clj_activitypub/internal/crypto.clj.html
Normal file
116
docs/cloverage/clj_activitypub/internal/crypto.clj.html
Normal file
|
@ -0,0 +1,116 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/crypto.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns clj-activitypub.internal.crypto
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clojure.java.io :as io])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:import (java.util Base64)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 (java.security MessageDigest SecureRandom Signature)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
006 (java.security.Security/addProvider
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
007 (org.bouncycastle.jce.provider.BouncyCastleProvider.))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
008
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
009 (defn- keydata [reader]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
010 (->> reader
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
011 (org.bouncycastle.openssl.PEMParser.)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 (.readObject)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
013
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
014 (defn- pem-string->key-pair [string]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
015 (let [kd (keydata (io/reader (.getBytes string)))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
016 (.getKeyPair (org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.) kd)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
018 (defn private-key [private-pem-str]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
019 (-> private-pem-str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
020 (pem-string->key-pair)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 (.getPrivate)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
022
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 (defn base64-encode [bytes]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
024 (.encodeToString (Base64/getEncoder) bytes))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
025
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
026 (defn sha256-base64 [data]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
027 (let [digest (.digest (MessageDigest/getInstance "SHA-256") (.getBytes data))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
028 (base64-encode digest)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
030 (defn sign [data private-key]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
031 (let [bytes (.getBytes data)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
032 signer (doto (Signature/getInstance "SHA256withRSA")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
033 (.initSign private-key (SecureRandom.))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
034 (.update bytes))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
035 (.sign signer)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
036
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
83
docs/cloverage/clj_activitypub/internal/http_util.clj.html
Normal file
83
docs/cloverage/clj_activitypub/internal/http_util.clj.html
Normal file
|
@ -0,0 +1,83 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/http_util.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns clj-activitypub.internal.http-util
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clj-activitypub.internal.crypto :as crypto])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:import (java.net URLEncoder)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 (java.time OffsetDateTime ZoneOffset)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 (java.time.format DateTimeFormatter)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
006
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
007 (defn encode-url-params [params]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
008 (->> params
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
009 (reduce-kv
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
010 (fn [coll k v]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
011 (conj coll
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
012 (str (URLEncoder/encode (name k)) "=" (URLEncoder/encode (str v)))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
013 [])
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
014 (interpose "&")
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
015 (apply str)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
016
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
017 (defn date []
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
018 (-> (OffsetDateTime/now (ZoneOffset/UTC))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
019 (.format DateTimeFormatter/RFC_1123_DATE_TIME)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
020
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
021 (defn digest
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 "Accepts body from HTTP request and generates string
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 for use in HTTP `Digest` request header."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 [body]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
025 (str "sha-256=" (crypto/sha256-base64 body)))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
140
docs/cloverage/clj_activitypub/internal/thread_cache.clj.html
Normal file
140
docs/cloverage/clj_activitypub/internal/thread_cache.clj.html
Normal file
|
@ -0,0 +1,140 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> clj_activitypub/internal/thread_cache.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns clj-activitypub.internal.thread-cache)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
002
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
003 (defn- current-time
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 "Returns current time using UNIX epoch."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 []
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
006 (System/currentTimeMillis))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
008 (defn- update-read-at [store k v]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
009 (dosync
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
010 (commute store assoc k
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
011 (merge v {:read-at (current-time)}))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
012
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
013 (defn make
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 "Creates a thread-local cache."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
015 ([] (make false))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ([cache-if-nil]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
017 (let [store (ref {})]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
018 (letfn [(cache-kv ([k v]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
019 (dosync
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
020 (commute store assoc k
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
021 {:write-at (current-time)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
022 :read-at (current-time)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 :value v})
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
024 v)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 (get-v ([k]
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
026 (when-let [data (get @store k)]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
027 (update-read-at store k data)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
028 (:value data)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ([k compute-fn]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
030 (let [storage @store]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
031 (if (contains? storage k)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
032 (get-v k)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
033 (let [v (compute-fn)]
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
034 (when (or (not (nil? v)) cache-if-nil)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
035 (cache-kv k v)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
036 (get-v k)))))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 (lru ([]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
038 (mapv
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
039 (fn [[k v]] [k (:value v)])
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
040 (sort-by #(-> % val :read-at) < @store))))]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
041 {:cache-kv cache-kv
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
042 :get-v get-v
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
043 :cache-if-nil cache-if-nil
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
044 :lru lru}))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
104
docs/cloverage/clj_activitypub/webfinger.clj.html
Normal file
104
docs/cloverage/clj_activitypub/webfinger.clj.html
Normal file
|
@ -0,0 +1,104 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> clj_activitypub/webfinger.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns clj-activitypub.webfinger
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clj-http.client :as client]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [clj-activitypub.internal.http-util :as http]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clj-activitypub.internal.thread-cache :as thread-cache]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
006 (def remote-uri-path "/.well-known/webfinger")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
008 (defn- resource-str [domain username]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
009 (str "acct:" username "@" domain))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
011 (defn resource-url
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 "Builds a URL pointing to the user's account on the remote server."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 [domain username & [params]]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
014 (let [resource (resource-str domain username)
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
015 query-str (http/encode-url-params (merge params {:resource resource}))]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
016 (str "https://" domain remote-uri-path "?" query-str)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
018 (def ^:private user-id-cache
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
019 (thread-cache/make))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
020
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
021 (defn fetch-user-id
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 "Follows the webfinger request to a remote domain, retrieving the ID of the requested
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 account. Typically returns a string in the form of a URL."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 [domain username]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
025 ((:get-v user-id-cache)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
026 (str domain "@" username) ;; cache key
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
027 (fn []
|
||||
</span><br/>
|
||||
<span class="partial" title="15 out of 16 forms covered">
|
||||
028 (let [response (some-> (resource-url domain username {:rel "self"})
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
029 (client/get {:as :json :throw-exceptions false :ignore-unknown-host? true}))]
|
||||
</span><br/>
|
||||
<span class="partial" title="27 out of 31 forms covered">
|
||||
030 (some->> response :body :links
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
031 (some #(when (= (:type %) "application/activity+json") %))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 :href)))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
54
docs/cloverage/codecov.json
Normal file
54
docs/cloverage/codecov.json
Normal file
|
@ -0,0 +1,54 @@
|
|||
{"coverage":
|
||||
{"dog_and_duck/quack/quack.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, 1, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
17, null, 1, null, null, null, null, null, true, 5, null, null, 1,
|
||||
null, 1, null, null, null, null, 1, null, null, null, null, null, 1,
|
||||
null, null, 4, null, 1, null, null, null, null, 1, null, null, null,
|
||||
null, 1, null, null, 4, null, 1, null, null, null, null, 1, null,
|
||||
null, null, null, null, null, true, 10, 9, true, 2, null, null,
|
||||
null, true, 2, null, 1, null, null, true, 2, 2, 0, 0, 0, null, null,
|
||||
1, null, null, 0, 0, 0, 0, 0, 0, 0, null, null, null, 1, null, null,
|
||||
0, 0, 0, null, null, 1, null, null, null, null, null, 0, 0, 0, null,
|
||||
null, 1, null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
null, null, 0, 0, null, 1, null, null, 0, null, 1, null, null, 0,
|
||||
null, 1, null, null, 0, null, 1, null, null, 0, null, null],
|
||||
"clj_activitypub/internal/http_util.clj":
|
||||
[null, 1, null, null, null, null, null, 1, 1, 1, 1, 2, 2, 1, 1, 1,
|
||||
null, 1, 0, 0, null, 1, null, null, null, 0],
|
||||
"clj_activitypub/internal/thread_cache.clj":
|
||||
[null, 1, null, 1, null, null, 8, null, 1, 4, 4, 4, null, 1, null, 2,
|
||||
null, 2, 2, 2, 2, 2, 2, 2, 2, null, 4, 4, 4, null, 4, 4, 2, 2, true,
|
||||
2, 2, null, 0, 0, 0, 2, 2, 2, 2],
|
||||
"dog_and_duck/scratch/parser.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, 1, null, null, null, 7, 7, 7, 7, 7, true, 0, null, 1, null, 1,
|
||||
0, 0, 0, 0, 0, 0, 1],
|
||||
"clj_activitypub/core.clj":
|
||||
[null, 1, null, null, null, null, null, null, 1, null, null, null,
|
||||
null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, 6, 2,
|
||||
2, null, 1, 1, null, null, null, 1, 1, 1, 1, null, null, 1, null, 1,
|
||||
null, null, null, 0, null, 0, null, 0, 0, 0, 0, 0, 0, null, 1, null,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null, null, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, null, 1, null, null, null, 0, 0, 0, 0, 0, 0, 0, null, 1,
|
||||
null, null, null, true, null, 1, null, null, null, null, null, 0,
|
||||
null, 0, 0, 0, 0, 0, null, 1, null, null, null, true, null, 1, 0,
|
||||
null, null, 0, 0, null, 1, 0, null, null, 0, 0, null, 1, null, null,
|
||||
null, 0, 0, 0, 0, 0, 0],
|
||||
"clj_activitypub/internal/crypto.clj":
|
||||
[null, 1, null, null, null, null, 1, 1, null, 1, 0, 0, null, null, 1,
|
||||
0, 0, null, 1, 0, 0, null, null, 1, 0, null, 1, 0, 0, null, 1, 0, 0,
|
||||
0, 0, 0, null],
|
||||
"dog_and_duck/scratch/core.clj":[null, 1, null, 1, null, null, 0],
|
||||
"clj_activitypub/webfinger.clj":
|
||||
[null, 1, null, null, null, null, 1, null, 1, 1, null, 1, null, null,
|
||||
1, 1, 1, null, 1, 1, null, 1, null, null, null, 3, 3, 3, true, 1,
|
||||
true, 2, null],
|
||||
"dog_and_duck/scratch/scratch.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, 1, null, 1, 1, 1, null, null, null,
|
||||
null, 1, null, 1, 1, 1, 1, null, null, 1, null, null, 1, 1, null,
|
||||
null, null, null, 1, 1, 1, 1, 1, 1, null]}}
|
40
docs/cloverage/coverage.css
Normal file
40
docs/cloverage/coverage.css
Normal file
|
@ -0,0 +1,40 @@
|
|||
.covered {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
background-color: #558B55;
|
||||
}
|
||||
|
||||
.not-covered {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.partial {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
.not-tracked {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
}
|
||||
|
||||
.blank {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
}
|
||||
|
||||
td {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
td.with-bar {
|
||||
width: 250px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td.with-number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.ns-name {
|
||||
min-width: 150px;
|
||||
padding-right: 25px;
|
||||
}
|
1
docs/cloverage/coverage.xml
Normal file
1
docs/cloverage/coverage.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="9"/><methods value="1223"/><srcfiles value="9"/><srclines value="284"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="52% (631/1223)"/><coverage type="line, %" value="54% (153/284)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (75/75)"/><coverage type="line, %" value="100% (19/19)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="44% (199/448)"/><coverage type="line, %" value="46% (31/68)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (34/68)"/><coverage type="line, %" value="56% (10/18)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report>
|
569
docs/cloverage/dog_and_duck/quack/quack.clj.html
Normal file
569
docs/cloverage/dog_and_duck/quack/quack.clj.html
Normal file
|
@ -0,0 +1,569 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/quack/quack.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.quack
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Validator for ActivityPub objects: if it walks like a duck, and it quacks like a duck..."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 ;;(:require [clojure.spec.alpha as s])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 (:import [java.net URI URISyntaxException]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
012
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
021
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
022 (defn object?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 "Returns `true` iff `x` is recognisably an ActivityStreams object.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 **NOTE THAT** The ActivityStreams spec
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 [says](https://www.w3.org/TR/activitystreams-core/#object):
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 > All properties are optional (including the id and type)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 But we are *just not having that*, because otherwise we're flying blind.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 tolerable because they represent transient objects, which we expect to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 handle."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="15 out of 15 forms covered">
|
||||
035 (and (map? x) (:type x) true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
036
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
037 (defn persistent-object?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 "`true` iff `x` is a persistent object.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
039
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 Transient objects in ActivityPub are not required to have an `id` key, but persistent
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ones must have a key, and it must be an IRI (but normally a URI)."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 [x]
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 2 forms covered">
|
||||
043 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
044 (and (object? x) (uri? (URI. (:id x))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 (catch URISyntaxException _ false)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
047 (persistent-object? {:type "test" :id "https://mastodon.scot/@barfilfarm"})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
049 (def ^:const actor-types
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 "The set of types we will accept as actors.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 There's an [explicit set of allowed actor types]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 (https://www.w3.org/TR/activitystreams-vocabulary/#actor-types)."
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
054 #{"Application"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 "Group"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 "Organization"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 "Person"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 "Service"})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
059
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
060 (defn actor-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 ;; TODO: better as a macro
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
063 (if (actor-types x) true false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
065 (def ^:const verb-types
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "The set of types we will accept as verbs.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 There's an [explicit set of allowed verb types]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 (https://www.w3.org/TR/activitystreams-vocabulary/#activity-types)."
|
||||
</span><br/>
|
||||
<span class="covered" title="29 out of 29 forms covered">
|
||||
070 #{"Accept" "Add" "Announce" "Arrive" "Block" "Create" "Delete" "Dislike"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 "Flag" "Follow" "Ignore" "Invite" "Join" "Leave" "Like" "Listen" "Move"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 "Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 "TentativeReject" "Travel" "Undo" "Update" "View"})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
074
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 (defn verb-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 ;; TODO: better as a macro
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
078 (if (verb-types x) true false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
079
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
080 (def ^:const activitystreams-context-uri
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 "The URI of the context of an ActivityStreams object is expected to be this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 literal string."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 "https://www.w3.org/ns/activitystreams")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
084
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 (defn context?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 "Returns `true` iff `x` quacks like an ActivityStreams context, else false.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 A context is either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 1. the URI (actually an IRI) `activitystreams-context-uri`, or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 2. a collection comprising that URI and a map."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 [x]
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 6 forms covered">
|
||||
092 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
093 (nil? x) false
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
094 (string? x) (and (= x activitystreams-context-uri) true)
|
||||
</span><br/>
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
095 (coll? x) (and (context? (first (remove map? x)))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
096 (= (count x) 2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 :else false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
099
|
||||
</span><br/>
|
||||
<span class="partial" title="40 out of 42 forms covered">
|
||||
100 (defmacro has-context? [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
101 `(context? ((keyword "@context") ~x)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
102
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
103 (defn actor?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
104 "Returns `true` if `x` quacks like an actor, else false."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
105 [x]
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 21 forms covered">
|
||||
106 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
107 (object? x)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
108 (has-context? x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
109 (uri? (URI. (:inbox x)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
110 (uri? (URI. (:outbox x)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
111 (actor-type? (:type x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
113
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
114 (defn activity?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 "`true` iff `x` quacks like an activity, else false."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
117 (try
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 28 forms covered">
|
||||
118 (and (object? x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
119 (has-context? x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
120 (string? (:summary x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
121 (actor? (:actor x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
122 (verb-type? (:type x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
123 (or (object? (:object x)) (uri? (URI. (:object x))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
124 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
125 (catch URISyntaxException _ false)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
126
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
127 (defn link?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 "`true` iff `x` quacks like a link, else false."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
130 (and (object? x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
131 (= (:type x) "Link")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
132 (uri? (URI. (:href x)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
134
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
135 (defn link-or-uri?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
136 "`true` iff `x` is either a URI or a link, else false.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
138 There are several points in the specification where e.g. the `:image`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 property (if present) may be either a link or a URI."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
141 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
142 (cond (string? x) (uri? (URI. x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
143 :else (link? x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
144 true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
145
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
146 (defn collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 "`true` iff `x` quacks like a collection of type `type`, else `false`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
148
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 With one argument, will recognise plain collections and ordered collections,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 but (currently) not collection pages."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
151 ([x type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
152 (let [items (or (:items x) (:orderedItems x))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 25 forms covered">
|
||||
153 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
154 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
155 (:items x) (nil? (:orderedItems x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
156 (:orderedItems x) (nil? (:items x))) ;; can't have both properties
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
157 (object? x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
158 (= (:type x) type)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
159 (coll? items)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
160 (every? object? items)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
161 (integer? (:totalItems x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
162 true)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
163 ([x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
164 (or (collection? x "Collection")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
165 (collection? x "OrderedCollection"))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
166
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
167 (defn unordered-collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
168 "`true` iff `x` quacks like an unordered collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
169 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
170 (collection? x "Collection"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
171
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
172 (defn ordered-collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
173 "`true` iff `x` quacks like an ordered collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
174 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
175 (collection? x "OrderedCollection"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
176
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
177 (defn collection-page?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
178 "`true` iff `x` quacks like a page in a paged collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
179 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
180 (collection? x "CollectionPage"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
181
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
182 (defn ordered-collection-page?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
183 "`true` iff `x` quacks like a page in an ordered paged collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
184 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
185 (collection? x "OrderedCollectionPage"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
186
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
187
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
26
docs/cloverage/dog_and_duck/scratch/core.clj.html
Normal file
26
docs/cloverage/dog_and_duck/scratch/core.clj.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/core.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.scratch.core)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
002
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
003 (defn foo
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 "I don't do a whole lot."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
006 (println x "Hello, World!"))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
143
docs/cloverage/dog_and_duck/scratch/parser.clj.html
Normal file
143
docs/cloverage/dog_and_duck/scratch/parser.clj.html
Normal file
|
@ -0,0 +1,143 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/parser.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.scratch.parser
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clojure.java.io :refer [file]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [clojure.string :refer [ends-with?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clojure.walk :refer [keywordize-keys]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [clojure.data.json :as json]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [dog-and-duck.quack.quack :as q]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
014
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
024 (defn clean
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 "Take this `json` input, and return a sequence of ActivityPub objects
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 represented by it."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [json]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
028 (let [feed (json/read-str json)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
029 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
030 keywordize-keys
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
031 (filter
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
032 q/object?
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 11 forms covered">
|
||||
033 (cond (map? feed) (list (keywordize-keys feed))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
034 (coll? feed) (map keywordize-keys feed))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
035
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
036 (clean (slurp "resources/activitystreams-test-documents/core-ex1-jsonld.json"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
038 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
039 #(when
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
040 (ends-with? (str %) ".json")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
041 (let [objects (clean (slurp %))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
042 (list (str %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
043 (count objects)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
044 (map :type objects))))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
045 (file-seq (file "resources/activitystreams-test-documents")))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
188
docs/cloverage/dog_and_duck/scratch/scratch.clj.html
Normal file
188
docs/cloverage/dog_and_duck/scratch/scratch.clj.html
Normal file
|
@ -0,0 +1,188 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> dog_and_duck/scratch/scratch.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.scratch.scratch
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Scratchpad where I try to understand how to do this stuff."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [clj-activitypub.core :as activitypub]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clj-activitypub.webfinger :as webfinger]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [clj-pgp.core :as pgp]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [clj-pgp.keyring :as keyring]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [clj-pgp.generate :as pgp-gen]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [clojure.walk :refer [keywordize-keys]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 [clojure.pprint :refer [pprint]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
012
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
026
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;; Use any ActivityPub account handle you like - for example, your own
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
028 (def account-handle "@simon_brooke@mastodon.scot")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
030 (def handle (activitypub/parse-account account-handle))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
031 (webfinger/fetch-user-id "mastodon.scot" "simon_brooke")
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
032 (apply webfinger/fetch-user-id (map handle [:domain :username]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
033
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; Retrieve the account details from its home server
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;; (`keywordize-keys` is not necessary here but produces a more idiomatic clojure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; data structure)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
037 (def account
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 "Fetch my account to mess with"
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
039 (let [handle (activitypub/parse-account account-handle)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
040 (keywordize-keys
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
041 (activitypub/fetch-user
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
042 (apply webfinger/fetch-user-id (map handle [:domain :username]))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;;; examine what you got back!
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
045 (:outbox account)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
047
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
048 (def rsa (pgp-gen/rsa-keypair-generator 2048))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
049 (def kp (pgp-gen/generate-keypair rsa :rsa-general))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
050
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 ;; how we make a public/private key pair. But this key pair is not the one
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 ;; known to mastodon.scot as my key pair, so that doesn't get us very far...
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 ;; I think.
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
054 (let [rsa (pgp-gen/rsa-keypair-generator 2048)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
055 kp (pgp-gen/generate-keypair rsa :rsa-general)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
056 public (-> kp .getPublicKey .getEncoded)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
057 private (-> kp .getPrivateKey .getPrivateKeyDataPacket .getEncoded)]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
058 (println (str "Public key: " public))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
059 (println (str "Private key: " private))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 )
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
164
docs/cloverage/index.html
Normal file
164
docs/cloverage/index.html
Normal file
|
@ -0,0 +1,164 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="./coverage.css"/>
|
||||
<title>Coverage Summary</title>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead><tr>
|
||||
<td class="ns-name"> Namespace </td>
|
||||
<td class="with-bar"> Forms </td>
|
||||
<td class="with-number">Forms %</td>
|
||||
<td class="with-bar"> Lines </td>
|
||||
<td class="with-number">Lines %</td>
|
||||
<td class="with-number">Total</td><td class="with-number">Blank</td><td class="with-number">Instrumented</td>
|
||||
</tr></thead>
|
||||
<tr>
|
||||
<td><a href="clj_activitypub/core.clj.html">clj-activitypub.core</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:23.588039867109636%;
|
||||
float:left;"> 71 </div><div class="not-covered"
|
||||
style="width:76.41196013289037%;
|
||||
float:left;"> 230 </div></td>
|
||||
<td class="with-number">23.59 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:27.906976744186046%;
|
||||
float:left;"> 24 </div><div class="partial"
|
||||
style="width:2.3255813953488373%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:69.76744186046511%;
|
||||
float:left;"> 60 </div></td>
|
||||
<td class="with-number">30.23 %</td>
|
||||
<td class="with-number">147</td><td class="with-number">14</td><td class="with-number">86</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="clj_activitypub/internal/crypto.clj.html">clj-activitypub.internal.crypto</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:18.75%;
|
||||
float:left;"> 9 </div><div class="not-covered"
|
||||
style="width:81.25%;
|
||||
float:left;"> 39 </div></td>
|
||||
<td class="with-number">18.75 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:39.130434782608695%;
|
||||
float:left;"> 9 </div><div class="not-covered"
|
||||
style="width:60.869565217391305%;
|
||||
float:left;"> 14 </div></td>
|
||||
<td class="with-number">39.13 %</td>
|
||||
<td class="with-number">36</td><td class="with-number">8</td><td class="with-number">23</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="clj_activitypub/internal/http_util.clj.html">clj-activitypub.internal.http-util</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:74.35897435897436%;
|
||||
float:left;"> 29 </div><div class="not-covered"
|
||||
style="width:25.641025641025642%;
|
||||
float:left;"> 10 </div></td>
|
||||
<td class="with-number">74.36 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:80.0%;
|
||||
float:left;"> 12 </div><div class="not-covered"
|
||||
style="width:20.0%;
|
||||
float:left;"> 3 </div></td>
|
||||
<td class="with-number">80.00 %</td>
|
||||
<td class="with-number">25</td><td class="with-number">3</td><td class="with-number">15</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="clj_activitypub/internal/thread_cache.clj.html">clj-activitypub.internal.thread-cache</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:83.33333333333333%;
|
||||
float:left;"> 105 </div><div class="not-covered"
|
||||
style="width:16.666666666666668%;
|
||||
float:left;"> 21 </div></td>
|
||||
<td class="with-number">83.33 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:88.23529411764706%;
|
||||
float:left;"> 30 </div><div class="partial"
|
||||
style="width:2.9411764705882355%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:8.823529411764707%;
|
||||
float:left;"> 3 </div></td>
|
||||
<td class="with-number">91.18 %</td>
|
||||
<td class="with-number">44</td><td class="with-number">3</td><td class="with-number">34</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="clj_activitypub/webfinger.clj.html">clj-activitypub.webfinger</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:95.53571428571429%;
|
||||
float:left;"> 107 </div><div class="not-covered"
|
||||
style="width:4.464285714285714%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">95.54 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:88.88888888888889%;
|
||||
float:left;"> 16 </div><div class="partial"
|
||||
style="width:11.11111111111111%;
|
||||
float:left;"> 2 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">32</td><td class="with-number">5</td><td class="with-number">18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/quack.clj.html">dog-and-duck.quack.quack</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:44.419642857142854%;
|
||||
float:left;"> 199 </div><div class="not-covered"
|
||||
style="width:55.580357142857146%;
|
||||
float:left;"> 249 </div></td>
|
||||
<td class="with-number">44.42 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:45.588235294117645%;
|
||||
float:left;"> 31 </div><div class="partial"
|
||||
style="width:7.352941176470588%;
|
||||
float:left;"> 5 </div><div class="not-covered"
|
||||
style="width:47.05882352941177%;
|
||||
float:left;"> 32 </div></td>
|
||||
<td class="with-number">52.94 %</td>
|
||||
<td class="with-number">187</td><td class="with-number">26</td><td class="with-number">68</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/core.clj.html">dog-and-duck.scratch.core</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:33.333333333333336%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:66.66666666666667%;
|
||||
float:left;"> 4 </div></td>
|
||||
<td class="with-number">33.33 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:66.66666666666667%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:33.333333333333336%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">66.67 %</td>
|
||||
<td class="with-number">6</td><td class="with-number">1</td><td class="with-number">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/parser.clj.html">dog-and-duck.scratch.parser</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:50.0%;
|
||||
float:left;"> 34 </div><div class="not-covered"
|
||||
style="width:50.0%;
|
||||
float:left;"> 34 </div></td>
|
||||
<td class="with-number">50.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:55.55555555555556%;
|
||||
float:left;"> 10 </div><div class="partial"
|
||||
style="width:5.555555555555555%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:38.888888888888886%;
|
||||
float:left;"> 7 </div></td>
|
||||
<td class="with-number">61.11 %</td>
|
||||
<td class="with-number">45</td><td class="with-number">7</td><td class="with-number">18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/scratch.clj.html">dog-and-duck.scratch.scratch</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 75 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 19 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">60</td><td class="with-number">9</td><td class="with-number">19</td>
|
||||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">51.59 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">57.75 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
112
docs/codox/Using_ActivityPub.html
Normal file
112
docs/codox/Using_ActivityPub.html
Normal file
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Using ActivityPub</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#using-activitypub" name="using-activitypub"></a>Using ActivityPub</h1>
|
||||
<pre><code class="clojure">user=> (require '[clj-activitypub.core :as activitypub])
|
||||
nil
|
||||
user=> (require '[clj-activitypub.webfinger :as webfinger])
|
||||
nil
|
||||
user=> (require '[clojure.walk :refer [keywordize-keys]])
|
||||
nil
|
||||
user=> (require '[clojure.pprint :refer [pprint]])
|
||||
nil
|
||||
user=> (def base-domain "mastodon.scot")
|
||||
#'user/base-domain
|
||||
user=> (def account-handle "@simon_brooke@mastodon.scot")
|
||||
#'user/account-handle
|
||||
user=> (in-ns 'user)
|
||||
#object[clojure.lang.Namespace 0x525575 "user"]
|
||||
user=> (activitypub/parse-account account-handle )
|
||||
{:domain "mastodon.scot", :username "simon_brooke"}
|
||||
user=> (map *1 [:domain :username])
|
||||
("mastodon.scot" "simon_brooke")
|
||||
user=> (apply webfinger/fetch-user-id *1)
|
||||
"https://mastodon.scot/users/simon_brooke"
|
||||
user=> (activitypub/fetch-user *1)
|
||||
{"followers" "https://mastodon.scot/users/simon_brooke/followers", "inbox" "https://mastodon.scot/users/simon_brooke/inbox", "url" "https://mastodon.scot/@simon_brooke", "@context" ["https://www.w3.org/ns/activitystreams" "https://w3id.org/security/v1" {"identityKey" {"@type" "@id", "@id" "toot:identityKey"}, "EncryptedMessage" "toot:EncryptedMessage", "Ed25519Key" "toot:Ed25519Key", "devices" {"@type" "@id", "@id" "toot:devices"}, "manuallyApprovesFollowers" "as:manuallyApprovesFollowers", "schema" "http://schema.org#", "PropertyValue" "schema:PropertyValue", "Curve25519Key" "toot:Curve25519Key", "claim" {"@type" "@id", "@id" "toot:claim"}, "value" "schema:value", "Hashtag" "as:Hashtag", "movedTo" {"@id" "as:movedTo", "@type" "@id"}, "discoverable" "toot:discoverable", "messageType" "toot:messageType", "messageFranking" "toot:messageFranking", "cipherText" "toot:cipherText", "toot" "http://joinmastodon.org/ns#", "alsoKnownAs" {"@id" "as:alsoKnownAs", "@type" "@id"}, "featured" {"@id" "toot:featured", "@type" "@id"}, "featuredTags" {"@id" "toot:featuredTags", "@type" "@id"}, "Ed25519Signature" "toot:Ed25519Signature", "focalPoint" {"@container" "@list", "@id" "toot:focalPoint"}, "fingerprintKey" {"@type" "@id", "@id" "toot:fingerprintKey"}, "Device" "toot:Device", "publicKeyBase64" "toot:publicKeyBase64", "deviceId" "toot:deviceId", "suspended" "toot:suspended"}], "devices" "https://mastodon.scot/users/simon_brooke/collections/devices", "manuallyApprovesFollowers" false, "image" {"type" "Image", "mediaType" "image/jpeg", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"}, "endpoints" {"sharedInbox" "https://mastodon.scot/inbox"}, "id" "https://mastodon.scot/users/simon_brooke", "publicKey" {"id" "https://mastodon.scot/users/simon_brooke#main-key", "owner" "https://mastodon.scot/users/simon_brooke", "publicKeyPem" "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"}, "summary" "<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics &amp; environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>", "attachment" [{"type" "PropertyValue", "name" "Home Page", "value" "<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}], "name" "Simon Brooke", "tag" [{"type" "Hashtag", "href" "https://mastodon.scot/tags/landreform", "name" "#landreform"}], "published" "2022-10-29T00:00:00Z", "preferredUsername" "simon_brooke", "discoverable" true, "alsoKnownAs" ["https://mastodon.social/users/simon_brooke"], "featured" "https://mastodon.scot/users/simon_brooke/collections/featured", "featuredTags" "https://mastodon.scot/users/simon_brooke/collections/tags", "type" "Person", "outbox" "https://mastodon.scot/users/simon_brooke/outbox", "following" "https://mastodon.scot/users/simon_brooke/following", "icon" {"type" "Image", "mediaType" "image/png", "url" "https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"}}
|
||||
user=> (def sb (keywordize-keys *1))
|
||||
#'user/sb
|
||||
user=> (:outbox sb)
|
||||
"https://mastodon.scot/users/simon_brooke/outbox"
|
||||
user=> (require '[clojure.data.json :as json])
|
||||
nil
|
||||
user=> (slurp (:outbox sb))
|
||||
Execution error (IOException) at sun.net.www.protocol.http.HttpURLConnection/getInputStream0 (HttpURLConnection.java:1894).
|
||||
Server returned HTTP response code: 403 for URL: https://mastodon.scot/users/simon_brooke/outbox
|
||||
user=> (pprint sb)
|
||||
{:inbox "https://mastodon.scot/users/simon_brooke/inbox",
|
||||
:name "Simon Brooke",
|
||||
:@context
|
||||
["https://www.w3.org/ns/activitystreams"
|
||||
"https://w3id.org/security/v1"
|
||||
{:schema "http://schema.org#",
|
||||
:messageType "toot:messageType",
|
||||
:messageFranking "toot:messageFranking",
|
||||
:identityKey {:@type "@id", :@id "toot:identityKey"},
|
||||
:Hashtag "as:Hashtag",
|
||||
:deviceId "toot:deviceId",
|
||||
:publicKeyBase64 "toot:publicKeyBase64",
|
||||
:value "schema:value",
|
||||
:Ed25519Key "toot:Ed25519Key",
|
||||
:featured {:@id "toot:featured", :@type "@id"},
|
||||
:Curve25519Key "toot:Curve25519Key",
|
||||
:discoverable "toot:discoverable",
|
||||
:focalPoint {:@container "@list", :@id "toot:focalPoint"},
|
||||
:suspended "toot:suspended",
|
||||
:fingerprintKey {:@type "@id", :@id "toot:fingerprintKey"},
|
||||
:Ed25519Signature "toot:Ed25519Signature",
|
||||
:cipherText "toot:cipherText",
|
||||
:EncryptedMessage "toot:EncryptedMessage",
|
||||
:alsoKnownAs {:@id "as:alsoKnownAs", :@type "@id"},
|
||||
:featuredTags {:@id "toot:featuredTags", :@type "@id"},
|
||||
:devices {:@type "@id", :@id "toot:devices"},
|
||||
:toot "http://joinmastodon.org/ns#",
|
||||
:movedTo {:@id "as:movedTo", :@type "@id"},
|
||||
:Device "toot:Device",
|
||||
:PropertyValue "schema:PropertyValue",
|
||||
:manuallyApprovesFollowers "as:manuallyApprovesFollowers",
|
||||
:claim {:@type "@id", :@id "toot:claim"}}],
|
||||
:featured
|
||||
"https://mastodon.scot/users/simon_brooke/collections/featured",
|
||||
:type "Person",
|
||||
:discoverable true,
|
||||
:icon
|
||||
{:type "Image",
|
||||
:mediaType "image/png",
|
||||
:url
|
||||
"https://media.mastodon.scot/mastodon-scot-public/accounts/avatars/109/252/274/874/045/781/original/172e8f7530627e87.png"},
|
||||
:following "https://mastodon.scot/users/simon_brooke/following",
|
||||
:summary
|
||||
"<p>Anarcho-syndicalist, autistic, crofter, cyclist, depressive, entrepreneur, geek, Zapatista. Politics &amp; environment, especially <a href=\"https://mastodon.scot/tags/LandReform\" class=\"mention hashtag\" rel=\"tag\">#<span>LandReform</span></a>. he/him.</p><p>Twitter: <span class=\"h-card\"><a href=\"https://mastodon.scot/@simon_brooke\" class=\"u-url mention\">@<span>simon_brooke</span></a></span><br />GitHub: simon-brooke<br />FetLife: Simon_Brooke</p><p>Credo: Life is harsh. What we can do - and what we should do - is strive to make it less harsh for the people around us.</p>",
|
||||
:publicKey
|
||||
{:id "https://mastodon.scot/users/simon_brooke#main-key",
|
||||
:owner "https://mastodon.scot/users/simon_brooke",
|
||||
:publicKeyPem
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/6GgLJgJlPhhqFm1tUQ\noSLnWxhDwq4HlZIHrBsVjkSvUAnHKqq42Q/hta+fkWB8rmTFpmjLXDj/Fi0uejvT\nBc+KrLwfX/yR8+G87afGCRS3CaumoLJ7zkBIlsFzIKMoIke1D3QuHX95yGGXs+hp\nmyxt/+CXRyZjK7u9NG7SMRUlpwvOlpD12Aei35Nb8NSr03JvY8/WVMIbWrecyI0b\nAlwj6axxHx7J15Yo+aEtKzZ2OFKXf+sh0QF9BEnYcmVKYlR6kiOglLFHKdCBUSYi\ni9Flv00TydqlGvR5fpShBqORiy0M/FVtNXlz2sNBEsGB2meipkjh+cRLzTbYo4KL\nJwIDAQAB\n-----END PUBLIC KEY-----\n"},
|
||||
:endpoints {:sharedInbox "https://mastodon.scot/inbox"},
|
||||
:preferredUsername "simon_brooke",
|
||||
:id "https://mastodon.scot/users/simon_brooke",
|
||||
:alsoKnownAs ["https://mastodon.social/users/simon_brooke"],
|
||||
:outbox "https://mastodon.scot/users/simon_brooke/outbox",
|
||||
:url "https://mastodon.scot/@simon_brooke",
|
||||
:featuredTags
|
||||
"https://mastodon.scot/users/simon_brooke/collections/tags",
|
||||
:devices
|
||||
"https://mastodon.scot/users/simon_brooke/collections/devices",
|
||||
:image
|
||||
{:type "Image",
|
||||
:mediaType "image/jpeg",
|
||||
:url
|
||||
"https://media.mastodon.scot/mastodon-scot-public/accounts/headers/109/252/274/874/045/781/original/e1f1823c4361fa27.jpg"},
|
||||
:tag
|
||||
[{:type "Hashtag",
|
||||
:href "https://mastodon.scot/tags/landreform",
|
||||
:name "#landreform"}],
|
||||
:followers "https://mastodon.scot/users/simon_brooke/followers",
|
||||
:published "2022-10-29T00:00:00Z",
|
||||
:manuallyApprovesFollowers false,
|
||||
:attachment
|
||||
[{:type "PropertyValue",
|
||||
:name "Home Page",
|
||||
:value
|
||||
"<a href=\"https://www.journeyman.cc/~simon/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">journeyman.cc/~simon/</span><span class=\"invisible\"></span></a>"}]}
|
||||
</code></pre></div></div></div></body></html>
|
3
docs/codox/clj-activitypub.core.html
Normal file
3
docs/codox/clj-activitypub.core.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/clj-activitypub.internal.crypto.html
Normal file
3
docs/codox/clj-activitypub.internal.crypto.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/clj-activitypub.internal.http-util.html
Normal file
3
docs/codox/clj-activitypub.internal.http-util.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/clj-activitypub.internal.thread-cache.html
Normal file
3
docs/codox/clj-activitypub.internal.thread-cache.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/clj-activitypub.webfinger.html
Normal file
3
docs/codox/clj-activitypub.webfinger.html
Normal file
File diff suppressed because one or more lines are too long
551
docs/codox/css/default.css
Normal file
551
docs/codox/css/default.css
Normal file
|
@ -0,0 +1,551 @@
|
|||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
|
||||
font-size: 9pt;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 29px;
|
||||
margin: 10px 0 2px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
h5.license {
|
||||
margin: 9px 0 22px 0;
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.document h1, .namespace-index h1 {
|
||||
font-size: 32px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
#header, #content, .sidebar {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#header {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 22px;
|
||||
color: #f5f5f5;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
#content {
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
padding: 0 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sidebar.primary {
|
||||
background: #e2e2e2;
|
||||
border-right: solid 1px #cccccc;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.sidebar.secondary {
|
||||
background: #f2f2f2;
|
||||
border-right: solid 1px #d7d7d7;
|
||||
left: 251px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#content.namespace-index, #content.document {
|
||||
left: 251px;
|
||||
}
|
||||
|
||||
#content.namespace-docs {
|
||||
left: 452px;
|
||||
}
|
||||
|
||||
#content.document {
|
||||
padding-bottom: 10%;
|
||||
}
|
||||
|
||||
#header {
|
||||
background: #3f3f3f;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 18px;
|
||||
font-weight: lighter;
|
||||
text-shadow: -1px -1px 0px #333;
|
||||
}
|
||||
|
||||
#header h1 .project-version {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-version {
|
||||
padding-left: 0.15em;
|
||||
}
|
||||
|
||||
#header a, .sidebar a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
float: right;
|
||||
font-size: 9pt;
|
||||
font-weight: normal;
|
||||
margin: 4px 3px;
|
||||
padding: 0;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
#header h2 a {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar h3 {
|
||||
margin: 0;
|
||||
padding: 10px 13px 0 13px;
|
||||
font-size: 19px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.sidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.sidebar h3.no-link {
|
||||
color: #636363;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
padding: 7px 0 6px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar ul.index-link {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .no-link {
|
||||
border-left: 3px solid transparent;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar li .no-link {
|
||||
display: block;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sidebar li .inner {
|
||||
display: inline-block;
|
||||
padding-top: 7px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .tree {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.depth-1 .inner { padding-left: 2px; }
|
||||
.depth-2 .inner { padding-left: 6px; }
|
||||
.depth-3 .inner { padding-left: 20px; }
|
||||
.depth-4 .inner { padding-left: 34px; }
|
||||
.depth-5 .inner { padding-left: 48px; }
|
||||
.depth-6 .inner { padding-left: 62px; }
|
||||
|
||||
.sidebar li .tree {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
margin: 0 4px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li.depth-1 .tree {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top, .sidebar li .tree .bottom {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top {
|
||||
border-left: 1px solid #aaa;
|
||||
border-bottom: 1px solid #aaa;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .bottom {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.sidebar li.branch .tree .bottom {
|
||||
border-left: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.sidebar.primary li.current a {
|
||||
border-left: 3px solid #a33;
|
||||
color: #a33;
|
||||
}
|
||||
|
||||
.sidebar.secondary li.current a {
|
||||
border-left: 3px solid #33a;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
.namespace-index h2 {
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index h3 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics {
|
||||
padding-left: 30px;
|
||||
margin: 11px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.namespace-docs h3 {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.public h3 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.usage {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public {
|
||||
margin: 0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.public:last-child {
|
||||
margin-bottom: 20%;
|
||||
}
|
||||
|
||||
.members .public:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.members {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.members h4 {
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
font-variant: small-caps;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.members .inner {
|
||||
padding-top: 5px;
|
||||
padding-left: 12px;
|
||||
margin-top: 2px;
|
||||
margin-left: 7px;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
||||
|
||||
#content .members .inner h3 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.members .public {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.members .public:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h4.type,
|
||||
h4.dynamic,
|
||||
h4.added,
|
||||
h4.deprecated {
|
||||
float: left;
|
||||
margin: 3px 10px 15px 0;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.public h4.type,
|
||||
.public h4.dynamic,
|
||||
.public h4.added,
|
||||
.public h4.deprecated {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 3px 0 0 10px;
|
||||
}
|
||||
|
||||
.members h4.type,
|
||||
.members h4.added,
|
||||
.members h4.deprecated {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
h4.type {
|
||||
color: #717171;
|
||||
}
|
||||
|
||||
h4.dynamic {
|
||||
color: #9933aa;
|
||||
}
|
||||
|
||||
h4.added {
|
||||
color: #508820;
|
||||
}
|
||||
|
||||
h4.deprecated {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.namespace:last-child {
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
|
||||
.index {
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
margin: 15px 0;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.index * {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.index p {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.index li {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.index ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.type-sig {
|
||||
clear: both;
|
||||
color: #088;
|
||||
}
|
||||
|
||||
.type-sig pre {
|
||||
padding-top: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.usage code {
|
||||
display: block;
|
||||
color: #008;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.usage code:first-child {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.public p:first-child, .public pre.plaintext {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.doc {
|
||||
margin: 0 0 26px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public .doc {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.namespace-index .doc {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.namespace-index .namespace .doc {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-weight: normal;
|
||||
font-size: 20px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 15px;
|
||||
margin: 22px 0 -4px 0;
|
||||
}
|
||||
|
||||
.doc, .public, .namespace .index {
|
||||
max-width: 680px;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.markdown pre > code {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.markdown pre > code, .src-link a {
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.markdown code:not(.hljs), .src-link a {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
pre.deps {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 2px;
|
||||
padding: 10px;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border-style: solid;
|
||||
border-top: none;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.doc ul, .doc ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.doc table {
|
||||
border-collapse: collapse;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.doc table td, .doc table th {
|
||||
border: 1px solid #dddddd;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.doc table th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
.doc dl {
|
||||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
|
||||
.doc dl dt {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 3px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.doc dl dd {
|
||||
padding: 5px 0;
|
||||
margin: 0 0 5px 10px;
|
||||
}
|
||||
|
||||
.doc abbr {
|
||||
border-bottom: 1px dotted #333;
|
||||
font-variant: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.src-link {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.src-link a {
|
||||
font-size: 70%;
|
||||
padding: 1px 4px;
|
||||
text-decoration: none;
|
||||
color: #5555bb;
|
||||
}
|
97
docs/codox/css/highlight.css
Normal file
97
docs/codox/css/highlight.css
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
14
docs/codox/dog-and-duck.quack.quack.html
Normal file
14
docs/codox/dog-and-duck.quack.quack.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/dog-and-duck.scratch.core.html
Normal file
3
docs/codox/dog-and-duck.scratch.core.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>dog-and-duck.scratch.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch current"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="dog-and-duck.scratch.core.html#var-foo"><div class="inner"><span>foo</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">dog-and-duck.scratch.core</h1><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="public anchor" id="var-foo"><h3>foo</h3><div class="usage"><code>(foo x)</code></div><div class="doc"><div class="markdown"><p>I don’t do a whole lot.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/dog-and-duck/blob/master/src/dog_and_duck/scratch/core.clj#L3">view source</a></div></div></div></body></html>
|
3
docs/codox/dog-and-duck.scratch.parser.html
Normal file
3
docs/codox/dog-and-duck.scratch.parser.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/dog-and-duck.scratch.scratch.html
Normal file
3
docs/codox/dog-and-duck.scratch.scratch.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/index.html
Normal file
3
docs/codox/index.html
Normal file
File diff suppressed because one or more lines are too long
46
docs/codox/intro.html
Normal file
46
docs/codox/intro.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>The Old Dog and Duck</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Dog-and-duck</span> <span class="project-version">0.1.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Using_ActivityPub.html"><div class="inner"><span>Using ActivityPub</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>The Old Dog and Duck</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clj-activitypub</span></div></div></li><li class="depth-2 branch"><a href="clj-activitypub.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>internal</span></div></div></li><li class="depth-3 branch"><a href="clj-activitypub.internal.crypto.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>crypto</span></div></a></li><li class="depth-3 branch"><a href="clj-activitypub.internal.http-util.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>http-util</span></div></a></li><li class="depth-3"><a href="clj-activitypub.internal.thread-cache.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>thread-cache</span></div></a></li><li class="depth-2"><a href="clj-activitypub.webfinger.html"><div class="inner"><span class="tree" style="top: -114px;"><span class="top" style="height: 123px;"></span><span class="bottom"></span></span><span>webfinger</span></div></a></li><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree" style="top: -207px;"><span class="top" style="height: 216px;"></span><span class="bottom"></span></span><span>dog-and-duck</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></div></li><li class="depth-3"><a href="dog-and-duck.quack.quack.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>quack</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree" style="top: -52px;"><span class="top" style="height: 61px;"></span><span class="bottom"></span></span><span>scratch</span></div></div></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-3 branch"><a href="dog-and-duck.scratch.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="dog-and-duck.scratch.scratch.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#the-old-dog-and-duck" name="the-old-dog-and-duck"></a>The Old Dog and Duck</h1>
|
||||
<p>A Clojure library designed to implement the ActivityPub protocol, obviously.</p>
|
||||
<h2><a href="#introduction" name="introduction"></a>Introduction</h2>
|
||||
<p>The Old Dog and Duck is clearly a pub, and it’s a pub related to an activity; to whit, hunting ducks with dogs. Yes, of course one could also hunt dogs with ducks, but in practice that doesn’t work so well. The point isn’t whether or not I approve of hunting ducks with dogs (or vice versa); to be clear, I don’t. The point is that it’s a pub related to an activity, and is therefore an <a href="https://www.w3.org/TR/activitypub/">ActivityPub</a>.</p>
|
||||
<p>Are we clear?</p>
|
||||
<p>Good.</p>
|
||||
<p>Let us proceed.</p>
|
||||
<p><strong>The Old Dog and Duck</strong> is intended to be a set of libraries to enable people to build stuff which interacts with ActivityPub. It isn’t intended to be a replacement for, or clone of, Mastodon. I do think I might implement my own ActivityPub server on top of The Old Dog and Duck, that specifically might allow for user-pluggable feed-sorting algorithms and with my own user interface/user experience take, but that project is not (yet, at any rate) this project.</p>
|
||||
<h2><a href="#status" name="status"></a>Status</h2>
|
||||
<p>This is a long way pre-alpha. Everything will change. Feel free to play, but do so at your own risk. Contributions welcome.</p>
|
||||
<h2><a href="#architecture" name="architecture"></a>Architecture</h2>
|
||||
<p>There are a number of separate concerns required to implement ActivityPub. They include</p>
|
||||
<ol>
|
||||
<li>Parsing ActivityStreams messages received from peers and from clients;</li>
|
||||
<li>Persisting ActivityStreams objects;</li>
|
||||
<li>Delivering ActivityStreams objects to peers;</li>
|
||||
<li>Delivering ActivityStreams objects to clients.</li>
|
||||
</ol>
|
||||
<p><strong>NOTE THAT</strong> what Mastodon delivers to clients is not actually in ActivityStreams format; this seems to be an ad-hoc hack that’s just never been fixed and has therefore become a de-facto standard for communication between ActivityPub hosts and their clients.</p>
|
||||
<p>My proposal would be to deliver exactly the same ActivityStreams format to my client as to other servers. There may be a valid reason for not doing this, but if there is I will discover it in due course.</p>
|
||||
<h2><a href="#proposed-dog-and-duck-libraries" name="proposed-dog-and-duck-libraries"></a>Proposed dog-and-duck libraries</h2>
|
||||
<p><strong>NOTE THAT</strong> at the present stage all the proposed libraries are in one package, namely this package, but that it is proposed that in future they will form separate libraries in separate packages.</p>
|
||||
<h3><a href="#bar" name="bar"></a>Bar</h3>
|
||||
<p>Where conversations happen. Handle interactions with clients.</p>
|
||||
<h3><a href="#cellar" name="cellar"></a>Cellar</h3>
|
||||
<p>Where things are stored. Persistance for ActivityStreams objects; I may at least initially simply copy the Mastodon postgres schema, but equally I may not.</p>
|
||||
<h3><a href="#pantry" name="pantry"></a>Pantry</h3>
|
||||
<p>Where deliveries are ordered and arrive; and from where deliveries onwards are despatched. Handle interactions with peers.</p>
|
||||
<h3><a href="#quack" name="quack"></a>Quack</h3>
|
||||
<p>Duck-typing for ActivityStreams objects.</p>
|
||||
<p>As of version 0.1.0, this is substantially the only part that is yet at all useful, and it is still a long way from finished or robust.</p>
|
||||
<h3><a href="#scratch" name="scratch"></a>Scratch</h3>
|
||||
<p>What the dog does when bored. Essentially, a place where I can learn how to make this stuff work, but perhaps eventually an ActivityPub server in its own right.</p>
|
||||
<h2><a href="#usage" name="usage"></a>Usage</h2>
|
||||
<p>At present, only the duck-typing functions work. To play with them, use</p>
|
||||
<pre><code class="clojure">(require '[dog-and-duck.quack.quack :as q])
|
||||
</code></pre>
|
||||
<h2><a href="#testing" name="testing"></a>Testing</h2>
|
||||
<p>Prior to testing, you should clone <a href="https://github.com/w3c-social/activitystreams-test-documents">activitystreams-test-documents</a> into the <code>resources</code> directory. You can then test with</p>
|
||||
<pre><code class="bash">lein test
|
||||
</code></pre>
|
||||
<h2><a href="#license" name="license"></a>License</h2>
|
||||
<p>Copyright © Simon Brooke, 2022.</p>
|
||||
<p>This program and the accompanying materials are made available under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.</p></div></div></div></body></html>
|
2
docs/codox/js/highlight.min.js
vendored
Normal file
2
docs/codox/js/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
docs/codox/js/jquery.min.js
vendored
Normal file
4
docs/codox/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
112
docs/codox/js/page_effects.js
Normal file
112
docs/codox/js/page_effects.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
function visibleInParent(element) {
|
||||
var position = $(element).position().top
|
||||
return position > -50 && position < ($(element).offsetParent().height() - 50)
|
||||
}
|
||||
|
||||
function hasFragment(link, fragment) {
|
||||
return $(link).attr("href").indexOf("#" + fragment) != -1
|
||||
}
|
||||
|
||||
function findLinkByFragment(elements, fragment) {
|
||||
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
|
||||
}
|
||||
|
||||
function scrollToCurrentVarLink(elements) {
|
||||
var elements = $(elements);
|
||||
var parent = elements.offsetParent();
|
||||
|
||||
if (elements.length == 0) return;
|
||||
|
||||
var top = elements.first().position().top;
|
||||
var bottom = elements.last().position().top + elements.last().height();
|
||||
|
||||
if (top >= 0 && bottom <= parent.height()) return;
|
||||
|
||||
if (top < 0) {
|
||||
parent.scrollTop(parent.scrollTop() + top);
|
||||
}
|
||||
else if (bottom > parent.height()) {
|
||||
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentVarLink() {
|
||||
$('.secondary a').parent().removeClass('current')
|
||||
$('.anchor').
|
||||
filter(function(index) { return visibleInParent(this) }).
|
||||
each(function(index, element) {
|
||||
findLinkByFragment(".secondary a", element.id).
|
||||
parent().
|
||||
addClass('current')
|
||||
});
|
||||
scrollToCurrentVarLink('.secondary .current');
|
||||
}
|
||||
|
||||
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
|
||||
|
||||
function scrollPositionId(element) {
|
||||
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
|
||||
return 'scroll::' + $(element).attr('id') + '::' + directory
|
||||
}
|
||||
|
||||
function storeScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
|
||||
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
|
||||
}
|
||||
|
||||
function recallScrollPosition(element) {
|
||||
if (!hasStorage) return;
|
||||
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
|
||||
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
|
||||
}
|
||||
|
||||
function persistScrollPosition(element) {
|
||||
recallScrollPosition(element)
|
||||
$(element).scroll(function() { storeScrollPosition(element) })
|
||||
}
|
||||
|
||||
function sidebarContentWidth(element) {
|
||||
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
|
||||
return Math.max.apply(Math, widths)
|
||||
}
|
||||
|
||||
function calculateSize(width, snap, margin, minimum) {
|
||||
if (width == 0) {
|
||||
return 0
|
||||
}
|
||||
else {
|
||||
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
|
||||
}
|
||||
}
|
||||
|
||||
function resizeSidebars() {
|
||||
var primaryWidth = sidebarContentWidth('.primary')
|
||||
var secondaryWidth = 0
|
||||
|
||||
if ($('.secondary').length != 0) {
|
||||
secondaryWidth = sidebarContentWidth('.secondary')
|
||||
}
|
||||
|
||||
// snap to grid
|
||||
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
|
||||
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
|
||||
|
||||
$('.primary').css('width', primaryWidth)
|
||||
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
|
||||
|
||||
if (secondaryWidth > 0) {
|
||||
$('#content').css('left', primaryWidth + secondaryWidth + 2)
|
||||
}
|
||||
else {
|
||||
$('#content').css('left', primaryWidth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
$(window).ready(resizeSidebars)
|
||||
$(window).ready(setCurrentVarLink)
|
||||
$(window).ready(function() { persistScrollPosition('.primary')})
|
||||
$(window).ready(function() {
|
||||
$('#content').scroll(setCurrentVarLink)
|
||||
$(window).resize(setCurrentVarLink)
|
||||
})
|
14
docs/index.html
Normal file
14
docs/index.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>The Old Dog and Duck: Documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="codox/css/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>The Old Dog and Duck: Documentation</h1>
|
||||
<ul>
|
||||
<li><a href="codox/index.html">Primary documentaion</a></li>
|
||||
<li><a href="cloverage/index.html">Test coverage</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
22
project.clj
22
project.clj
|
@ -1,9 +1,14 @@
|
|||
(defproject dog-and-duck "0.1.0-SNAPSHOT"
|
||||
:description "FIXME: write description"
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||
:url "https://www.eclipse.org/legal/epl-2.0/"}
|
||||
:dependencies [[org.clojure/clojure "1.10.3"]
|
||||
:cloverage {:output "docs/cloverage"
|
||||
:codecov? true
|
||||
:emma-xml? true}
|
||||
:codox {:metadata {:doc "**TODO**: write docs"
|
||||
:doc/format :markdown}
|
||||
:output-path "docs/codox"
|
||||
:source-uri "https://github.com/simon-brooke/dog-and-duck/blob/master/{filepath}#L{line}"}
|
||||
|
||||
:description "A Clojure library designed to implement the ActivityPub protocol."
|
||||
:dependencies [[org.clojure/clojure "1.11.1"]
|
||||
[org.clojure/data.json "2.4.0"]
|
||||
[org.clojure/math.numeric-tower "0.0.5"]
|
||||
[org.clojure/spec.alpha "0.3.218"]
|
||||
|
@ -12,4 +17,9 @@
|
|||
[clj-http "3.12.3"] ;; required by clj-activitypub
|
||||
[cheshire "5.11.0"] ;; if this is not present, clj-http/client errors with 'json-enabled?'
|
||||
]
|
||||
:repl-options {:init-ns dog-and-duck.scratch.core})
|
||||
:license {:name "GPL-2.0-or-later"
|
||||
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
||||
:plugins [[lein-cloverage "1.2.2"]
|
||||
[lein-codox "0.10.7"]]
|
||||
:repl-options {:init-ns dog-and-duck.scratch.core}
|
||||
:url "http://example.com/FIXME")
|
||||
|
|
BIN
resources/public/images/Dog_and_Duck_tavern.jpg
Normal file
BIN
resources/public/images/Dog_and_Duck_tavern.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -1,4 +1,7 @@
|
|||
(ns clj-activitypub.internal.crypto
|
||||
"copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||
If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||
dependency on that library will be added to the project."
|
||||
(:require [clojure.java.io :as io])
|
||||
(:import (java.util Base64)
|
||||
(java.security MessageDigest SecureRandom Signature)))
|
||||
|
@ -30,7 +33,7 @@
|
|||
(defn sign [data private-key]
|
||||
(let [bytes (.getBytes data)
|
||||
signer (doto (Signature/getInstance "SHA256withRSA")
|
||||
(.initSign private-key (SecureRandom.))
|
||||
(.update bytes))]
|
||||
(.initSign private-key (SecureRandom.))
|
||||
(.update bytes))]
|
||||
(.sign signer)))
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
(ns clj-activitypub.internal.http-util
|
||||
"copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||
If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||
dependency on that library will be added to the project."
|
||||
(:require [clj-activitypub.internal.crypto :as crypto])
|
||||
(:import (java.net URLEncoder)
|
||||
(java.time OffsetDateTime ZoneOffset)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
(ns clj-activitypub.internal.thread-cache)
|
||||
(ns clj-activitypub.internal.thread-cache
|
||||
"copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub).
|
||||
If and when Jahfer issues a release of that library, this directory will be deleted and a
|
||||
dependency on that library will be added to the project.")
|
||||
|
||||
(defn- current-time
|
||||
"Returns current time using UNIX epoch."
|
||||
|
@ -26,14 +29,14 @@
|
|||
(when-let [data (get @store k)]
|
||||
(update-read-at store k data)
|
||||
(:value data)))
|
||||
([k compute-fn]
|
||||
(let [storage @store]
|
||||
(if (contains? storage k)
|
||||
(get-v k)
|
||||
(let [v (compute-fn)]
|
||||
(when (or (not (nil? v)) cache-if-nil)
|
||||
(cache-kv k v)
|
||||
(get-v k)))))))
|
||||
([k compute-fn]
|
||||
(let [storage @store]
|
||||
(if (contains? storage k)
|
||||
(get-v k)
|
||||
(let [v (compute-fn)]
|
||||
(when (or (not (nil? v)) cache-if-nil)
|
||||
(cache-kv k v)
|
||||
(get-v k)))))))
|
||||
(lru ([]
|
||||
(mapv
|
||||
(fn [[k v]] [k (:value v)])
|
||||
|
|
Loading…
Reference in a new issue