M HOWTO.org +70 -2
@@ 44,7 44,6 @@ GET http://127.0.0.1:4280/health
#+RESULTS:
: OK
-
** Put trust values for an ID
Put trust values as CSV for a given ID. OTHERID and all the other IDs
@@ 292,7 291,76 @@ data=saved
Using a PUT, because saving data without change in between does not
change the data.
-** Data structures
+** Subscription handling
+
+Subscriptions allow guiding information retrieval and communication
+between many different services.
+
+Get subscriptions to check for updates, separated by empty lines. The
+ID as first line of each block, furthers data in format key: value,
+one per line.
+
+#+begin_src http :pretty :exports both
+GET http://127.0.0.1:4280/subscriptions/SOMEID
+#+end_src
+
+#+RESULTS:
+
+
+When a subscription yields an update, put it with metadata; wispwot
+will keep track of it and provide it when the subscription comes up
+again. First get your ID key, then PUT the ID.
+
+#+begin_src http :pretty :exports both
+GET http://127.0.0.1:4280/key/SOMEID
+#+end_src
+
+#+RESULTS:
+: 0000
+
+Then put to the otherid (not key: the key is ownly needed for your
+own ID to keep the URL sane). The metadata must be URL-encoded as
+usual for form-data.
+
+There is no result, the success-code is 204 (no data).
+
+#+begin_src http :pretty :exports both
+PUT http://127.0.0.1:4280/subscription-updated/ownkey/0000/otherid/SOMEONEELSE
+Content-type: application/x-www-form-urlencoded
+
+link=http://example.org
+#+end_src
+
+#+RESULTS:
+
+Save trust-relevant information as usual (from which ID you found the
+ID). If there is no trust yet, wispwot will record trust 0 from your
+ownkey.
+
+Add one more update, then see the subscriptions:
+
+#+begin_src http :pretty :exports both
+PUT http://127.0.0.1:4280/subscription-updated/ownkey/0000/otherid/STRANGER
+Content-type: application/x-www-form-urlencoded
+
+link=http://example.com
+#+end_src
+
+#+RESULTS:
+
+
+#+begin_src http :pretty :exports both
+GET http://127.0.0.1:4280/subscriptions/SOMEID
+#+end_src
+
+#+RESULTS:
+: SOMEONEELSE
+:
+: STRANGER
+
+
+
+* Data structures
- =store/known-identities= contains the list of IDs.
- =store/trust/ab/cd= contains the trust values given by the ID with index abcd (base 16 formatted number).
M wispwot/server.w +120 -12
@@ 421,6 421,22 @@ define-handler 'GET "/id/" : get-id-hand
. #:code 404
. "404 not found"
+define : get-score wotstate ownkey otherkey
+ define ownidx : key->index ownkey
+ define ownid : index->identity wotstate ownidx
+ define wotstate-with-cache : add-wotcache wotstate ownidx ownid
+ define scores
+ wotcache-scores
+ update-wotcache-from-wotstate! wotstate-with-cache ownid
+ define otherindex : key->index otherkey
+ cond
+ : equal? ownkey otherkey
+ . "100" ;; trust of own ID is always 100
+ {otherindex >= (vector-length scores)}
+ . #f
+ else
+ and=> (vector-ref scores otherindex) number->string
+
define-handler 'GET "/score/ownkey/" : get-score-handler request body wotstate
. "Get the score for a given key as seen from the ownkey.
@@ 430,18 446,8 @@ define-handler 'GET "/score/ownkey/" : g
=> 50"
define path : split-and-decode-uri-path : uri-path : request-uri request
define ownkey : third path
- define ownidx : key->index ownkey
- define ownid : index->identity wotstate ownidx
- define wotstate-with-cache : add-wotcache wotstate ownidx ownid
- define scores
- wotcache-scores
- update-wotcache-from-wotstate! wotstate-with-cache ownid
define otherkey : fifth path
- define otherindex : key->index otherkey
- define score
- if : equal? ownkey otherkey
- . "100" ;; trust of own ID is always 100
- and=> (vector-ref scores otherindex) number->string
+ define score : get-score wotstate ownkey otherkey
define code : if score 200 204 ;; 200 ok or 204 no content
values
build-response
@@ 551,10 557,112 @@ define-handler 'POST "/addtrust/" : post
check-pruning-stale-ids wotstate ownids
values
build-response
- . #:headers `((content-type . (text/html)))
+ . #:headers `((content-type . (text/plain)))
. someid
+
+
+;; subscription handling
+;; subscriptions to IDs
+;; ((ownid1 otherid1 otherid2 ...) (ownid2 otherid3 otherid4 ...))
+define rank1-subscriptions '()
+define rank2-subscriptions-most-recent '()
+define rank2-subscriptions-random '()
+define rank3+-subscriptions-most-recent '()
+define rank3+-subscriptions-random '()
+define subscriptions-updated '()
+define : add-for-ownid! subs ownid id
+ define index
+ list-index : λ (x) : equal? ownid : first x
+ . subs
+ define entry : list-ref subs index
+ define updated
+ cons (car entry) : cons id : cdr entry
+ list-set! subs index updated
+define-syntax-rule : add-to-subscription! subs ownid id
+ begin
+ unless : assoc ownid subs
+ set! subs
+ alist-cons ownid '() subs
+ add-for-ownid! subs ownid id
+define : get-subscriptions ownid
+ ;; TODO: update subscription-lists from wot and retrieve the
+ ;; defined IDs.
+ or : assoc-ref subscriptions-updated ownid
+ . '()
+
+
+;; alist of hash-tables (one per ownid) with ids as key and alists of metadata as value
+;; ((ownid . #<hash:((id: ((key . value) (key . value))) ...)>
+define id-metadata '()
+define : set-metadata! ownid id metadata
+ unless : assoc ownid id-metadata
+ let : : table : make-hash-table 8
+ set! id-metadata
+ alist-cons ownid table id-metadata
+ let : : table : assoc-ref id-metadata ownid
+ hash-set! table id metadata
+define : get-metadata ownid id
+ unless : assoc ownid id-metadata
+ let : : table : make-hash-table 8
+ set! id-metadata
+ alist-cons ownid table id-metadata
+ let : : table : assoc-ref id-metadata ownid
+ or (hash-ref table id) '()
+
+define-handler 'PUT "/subscription-updated/ownkey/" : put-subscription-updated-handler request body wotstate
+ . "Endpoint: /subscription-updated/ownkey/OWN/otherid/ID
+
+ Add metadata needed to check the ID as form-data.
+ "
+ define path : split-and-decode-uri-path : uri-path : request-uri request
+ define ownkey : third path
+ define ownidx : key->index ownkey
+ define ownid : index->identity wotstate ownidx
+ define path-rest : drop path 4
+ define otherid : string-join path-rest "/" ;; ID can contain /
+ define otherkey : id->key wotstate otherid
+ ;; Ensure that there is at least one trust relationship to the
+ ;; other ID, so it is in the WoT.
+ unless : and otherkey : get-score wotstate ownkey otherkey
+ add-trust-edge wotstate ownid otherid 0
+ let : : body-string : bytevector->string body "UTF-8"
+ define body-decoded : uri-decode body-string
+ define metadata
+ map (cut string-split <> #\=) : string-split body-decoded #\&
+ set-metadata! ownid otherid metadata
+ add-to-subscription! subscriptions-updated ownid otherid
+ define code 204 ;; 204 no content
+ values
+ build-response
+ . #:headers `((content-type . (text/plain)))
+ . ""
+
+
+define-handler 'GET "/subscriptions/" : get-subscriptions-handler request body wotstate
+ . "Endpoint: /subscriptions/ownid
+
+ Returns a list of IDs to check for updates, separated by empty lines."
+ define path-raw : uri-path : request-uri request
+ define path : string-join (split-and-decode-uri-path path-raw) "/"
+ define ownid : string-drop path : string-length "subscriptions/"
+ ;; TODO: get subscriptions for ownid
+ define subscriptions : get-subscriptions ownid
+ define : metadata-strings ownid id
+ define metadata : get-metadata ownid id
+ map : lambda (cel) : string-join (list (first cel) (second cel)) ": "
+ . metadata
+ define with-metadata
+ map : lambda (id) : string-join (cons id (metadata-strings ownid id)) "\n"
+ . subscriptions
+ values
+ build-response
+ . #:headers `((content-type . (text/plain)))
+ string-join with-metadata "\n\n"
+
+
+;; persistence handling
define store-directory #f
define-handler 'PUT "/store/state" : put-state-handler request body wotstate
. "Endpoint: /store/state