Initial AP objects implementation
This commit is contained in:
50
source/ap/activity_stream.d
Normal file
50
source/ap/activity_stream.d
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
module ap.activity_stream;
|
||||||
|
|
||||||
|
import std.json;
|
||||||
|
|
||||||
|
import util;
|
||||||
|
|
||||||
|
/++
|
||||||
|
* Basic ActivityStream Object
|
||||||
|
* https://www.w3.org/TR/activitypub/#obj
|
||||||
|
+/
|
||||||
|
class ASObject {
|
||||||
|
string context; /// Must be activitystream context
|
||||||
|
string id; /// AP requirement for unique identifier
|
||||||
|
string type; /// AP requirement for type of object
|
||||||
|
|
||||||
|
JSONValue raw;
|
||||||
|
|
||||||
|
/++
|
||||||
|
+ Constructs the object according to json source
|
||||||
|
+ Params:
|
||||||
|
+ json = the source json
|
||||||
|
+ Returns: Object
|
||||||
|
+/
|
||||||
|
this(JSONValue json) {
|
||||||
|
with (this) {
|
||||||
|
const(JSONValue)* ascontext = "@context" in json;
|
||||||
|
|
||||||
|
if (ascontext == null)
|
||||||
|
throw new Exception("No context in ActivityStream Object");
|
||||||
|
|
||||||
|
switch ((*ascontext).type) {
|
||||||
|
case JSONType.ARRAY:
|
||||||
|
context = (*ascontext)[0].str;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSONType.STRING:
|
||||||
|
context = (*ascontext).str;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid @context type for ActivityStream Object");
|
||||||
|
}
|
||||||
|
|
||||||
|
id = json.requiredKey!"id".str;
|
||||||
|
type = json.requiredKey!"type".str;
|
||||||
|
|
||||||
|
raw = json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
source/ap/actor.d
Normal file
77
source/ap/actor.d
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
module ap.actor;
|
||||||
|
|
||||||
|
import std.json;
|
||||||
|
|
||||||
|
import ap.activity_stream;
|
||||||
|
import util;
|
||||||
|
|
||||||
|
/++
|
||||||
|
* Represents an ActivityPub Actor
|
||||||
|
* https://www.w3.org/TR/activitypub/#actors
|
||||||
|
+/
|
||||||
|
class Actor : ASObject {
|
||||||
|
/* Required fields */
|
||||||
|
string inbox; /// Link to messages received by this actor. Required
|
||||||
|
string outbox; /// Link to messages produced by this actor. Required
|
||||||
|
string following; /// Link to a collection of the actors that this actor is following. Required
|
||||||
|
string followers; /// Link to a collection of the actors that follow this actor. Required
|
||||||
|
|
||||||
|
/* Optional fields */
|
||||||
|
string liked; /// Link to a collection of objects this actor has liked
|
||||||
|
string streams; /// Supplementary list of Collections of interest
|
||||||
|
string preferredUsername; /// A short username for referencing this actor
|
||||||
|
ActorEndpoints endpoints; /// Useful endpoints for this actor
|
||||||
|
|
||||||
|
JSONValue raw;
|
||||||
|
|
||||||
|
/++
|
||||||
|
+ Creates an Actor object based on its json representation
|
||||||
|
+ Params:
|
||||||
|
+ json = ActivityPub actor JSON representation
|
||||||
|
+/
|
||||||
|
this(JSONValue json) {
|
||||||
|
super(json);
|
||||||
|
|
||||||
|
with (this) {
|
||||||
|
inbox = json.requiredKey!"inbox".str;
|
||||||
|
outbox = json.requiredKey!"outbox".str;
|
||||||
|
following = json.requiredKey!"following".str;
|
||||||
|
followers = json.requiredKey!"followers".str;
|
||||||
|
|
||||||
|
liked = json.checkKey!string("liked");
|
||||||
|
streams = json.checkKey!string("streams");
|
||||||
|
preferredUsername = json.checkKey!string("preferredUsername");
|
||||||
|
|
||||||
|
if (JSONValue* j = "endpoints" in json)
|
||||||
|
endpoints = ActorEndpoints.fromJson(*j);
|
||||||
|
else
|
||||||
|
endpoints = ActorEndpoints();
|
||||||
|
|
||||||
|
raw = json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ActorEndpoints {
|
||||||
|
string proxyUrl;
|
||||||
|
string oauthAuthorizationEndpoint;
|
||||||
|
string oauthTokenEndpoint;
|
||||||
|
string provideClientKey;
|
||||||
|
string signClientKey;
|
||||||
|
string sharedInbox;
|
||||||
|
|
||||||
|
static ActorEndpoints fromJson(JSONValue json) {
|
||||||
|
ActorEndpoints endpoints = ActorEndpoints();
|
||||||
|
|
||||||
|
with (endpoints) {
|
||||||
|
proxyUrl = json.checkKey!string("proxyUrl");
|
||||||
|
oauthAuthorizationEndpoint = json.checkKey!string("oauthAuthorizationEndpoint");
|
||||||
|
oauthTokenEndpoint = json.checkKey!string("oauthTokenEndpoint");
|
||||||
|
provideClientKey = json.checkKey!string("provideClientKey");
|
||||||
|
signClientKey = json.checkKey!string("signClientKey");
|
||||||
|
sharedInbox = json.checkKey!string("sharedInbox");
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
source/ap/errors.d
Normal file
10
source/ap/errors.d
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module ap.errors;
|
||||||
|
|
||||||
|
/++
|
||||||
|
* Base exception for ActivityPub
|
||||||
|
+/
|
||||||
|
class APException : Exception {
|
||||||
|
this(string msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
source/util.d
Normal file
20
source/util.d
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module util;
|
||||||
|
|
||||||
|
import std.format;
|
||||||
|
import std.json;
|
||||||
|
|
||||||
|
JSONValue requiredKey(string key)(JSONValue val) {
|
||||||
|
const(JSONValue)* j = key in val;
|
||||||
|
|
||||||
|
if (j)
|
||||||
|
return *j;
|
||||||
|
|
||||||
|
throw new Exception(format("Key %s not found in json", key));
|
||||||
|
}
|
||||||
|
|
||||||
|
T checkKey(T)(JSONValue val, string key) {
|
||||||
|
if (JSONValue* j = key in val)
|
||||||
|
return (*j).get!T;
|
||||||
|
|
||||||
|
return T.init;
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ PRequest buildRequest(string uri, string[string] params) {
|
|||||||
PRequest rq = PRequest();
|
PRequest rq = PRequest();
|
||||||
|
|
||||||
rq.method = "GET";
|
rq.method = "GET";
|
||||||
rq.url = format("http://%s/.well-known/webfinger", uri);
|
rq.url = format("https://%s/.well-known/webfinger", uri);
|
||||||
rq.headers["Accept"] = AcceptedWebfingerContentType;
|
rq.headers["Accept"] = AcceptedWebfingerContentType;
|
||||||
|
|
||||||
QueryParam[] p;
|
QueryParam[] p;
|
||||||
@@ -49,3 +49,12 @@ JSONValue requestAcct(string uri, string acct) {
|
|||||||
|
|
||||||
return parseJSON(rs.responseBody().toString());
|
return parseJSON(rs.responseBody().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSONValue requestAcct(string handle) {
|
||||||
|
string uri, acct;
|
||||||
|
|
||||||
|
uri = handle.split("@")[$ - 1];
|
||||||
|
acct = handle.split("@")[$ - 2];
|
||||||
|
|
||||||
|
return requestAcct(uri, acct);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user