mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 21:25:11 +00:00
[MOD/ADD] Separate AS code, XMPP reactions removal
This commit is contained in:
parent
1b62072a3a
commit
fb511b4df0
16 changed files with 1183 additions and 1029 deletions
4
Makefile
4
Makefile
|
|
@ -26,8 +26,8 @@ AYAS=ayaya
|
||||||
ETC=etc
|
ETC=etc
|
||||||
INCLUDES=src/include
|
INCLUDES=src/include
|
||||||
CC=cc
|
CC=cc
|
||||||
CFLAGS=-I$(SOURCE) -I$(INCLUDES) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -DREPOSITORY=\"$(REPOSITORY)\" -DCODE=\"$(CODE)\" -O3 -s -Wall -Werror
|
CFLAGS=-I$(SOURCE) -I$(INCLUDES) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -DREPOSITORY=\"$(REPOSITORY)\" -DCODE=\"$(CODE)\" -O3 -g -Wall -Werror
|
||||||
LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -O3 -s
|
LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -O3 -g
|
||||||
AFLAGS=-C "$(ETC)/ayadoc/style.css" -p "$(NAME)"
|
AFLAGS=-C "$(ETC)/ayadoc/style.css" -p "$(NAME)"
|
||||||
BINARY=parsee
|
BINARY=parsee
|
||||||
# ============================ Compilation =================================
|
# ============================ Compilation =================================
|
||||||
|
|
|
||||||
971
src/AS.c
971
src/AS.c
|
|
@ -55,976 +55,5 @@ ASAuthenticateRequest(const ParseeConfig *data, HttpClientContext *ctx)
|
||||||
HttpRequestHeader(ctx, "Authorization", bearer);
|
HttpRequestHeader(ctx, "Authorization", bearer);
|
||||||
Free(bearer);
|
Free(bearer);
|
||||||
}
|
}
|
||||||
bool
|
|
||||||
ASRegisterUser(const ParseeConfig *conf, char *user)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
HttpStatus status;
|
|
||||||
if (!conf || !user)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create user. We don't actually care about the value as we can
|
|
||||||
* masquerade, as long as it exists. */
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, "/_matrix/client/v3/register"
|
|
||||||
);
|
|
||||||
json = HashMapCreate();
|
|
||||||
|
|
||||||
HashMapSet(json,"type",JsonValueString("m.login.application_service"));
|
|
||||||
|
|
||||||
user = ParseeGetLocal(user);
|
|
||||||
HashMapSet(json,"username",JsonValueString(user));
|
|
||||||
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
status = ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
Free(user);
|
|
||||||
|
|
||||||
return status == HTTP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ASPing(const ParseeConfig *conf)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path;
|
|
||||||
if (!conf)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = StrConcat(3,
|
|
||||||
"/_matrix/client/v1/appservice/",
|
|
||||||
"Parsee%20XMPP",
|
|
||||||
"/ping"
|
|
||||||
);
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASInvite(const ParseeConfig *conf, char *id, char *invited)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *bridge;
|
|
||||||
if (!conf || !id || !invited)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge = StrConcat(4,
|
|
||||||
"@", conf->sender_localpart,
|
|
||||||
":", conf->server_base
|
|
||||||
);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/rooms/", id, "/invite",
|
|
||||||
"?user_id=", bridge
|
|
||||||
);
|
|
||||||
Free(bridge);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "user_id", JsonValueString(invited));
|
|
||||||
HashMapSet(json, "reason", JsonValueString("Pass over."));
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASBan(const ParseeConfig *conf, char *id, char *banned)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *bridge;
|
|
||||||
if (!conf || !id || !banned)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge = StrConcat(4,
|
|
||||||
"@", conf->sender_localpart,
|
|
||||||
":", conf->server_base
|
|
||||||
);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/rooms/", id, "/ban",
|
|
||||||
"?user_id=", bridge
|
|
||||||
);
|
|
||||||
Free(bridge);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "user_id", JsonValueString(banned));
|
|
||||||
HashMapSet(json, "reason", JsonValueString("Parsee felt jealous."));
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASKick(const ParseeConfig *conf, char *id, char *banned)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *bridge;
|
|
||||||
if (!conf || !id || !banned)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge = StrConcat(4,
|
|
||||||
"@", conf->sender_localpart,
|
|
||||||
":", conf->server_base
|
|
||||||
);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/rooms/", id, "/kick",
|
|
||||||
"?user_id=", bridge
|
|
||||||
);
|
|
||||||
Free(bridge);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "user_id", JsonValueString(banned));
|
|
||||||
HashMapSet(json, "reason", JsonValueString("Parsee felt jealous."));
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *ret;
|
|
||||||
if (!conf || !id)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!masquerade)
|
|
||||||
{
|
|
||||||
char *raw = StrConcat(4,
|
|
||||||
"@", conf->sender_localpart,
|
|
||||||
":", conf->server_base
|
|
||||||
);
|
|
||||||
masquerade = HttpUrlEncode(raw);
|
|
||||||
Free(raw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
masquerade = HttpUrlEncode(masquerade);
|
|
||||||
}
|
|
||||||
id = HttpUrlEncode(id);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/join/", id, "?",
|
|
||||||
"user_id=", masquerade
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
json = JsonDecode(HttpClientStream(ctx));
|
|
||||||
ret = StrDuplicate(GrabString(json, 1, "room_id"));
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(masquerade);
|
|
||||||
Free(id);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASLeave(const ParseeConfig *conf, char *id, char *masquerade)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path;
|
|
||||||
if (!conf || !id)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!masquerade)
|
|
||||||
{
|
|
||||||
char *raw = StrConcat(4,
|
|
||||||
"@", conf->sender_localpart,
|
|
||||||
":", conf->server_base
|
|
||||||
);
|
|
||||||
masquerade = HttpUrlEncode(raw);
|
|
||||||
Free(raw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
masquerade = HttpUrlEncode(masquerade);
|
|
||||||
}
|
|
||||||
id = HttpUrlEncode(id);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/rooms/", id, "/leave?",
|
|
||||||
"user_id=", masquerade
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(masquerade);
|
|
||||||
Free(id);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *state)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
char *path;
|
|
||||||
if (!conf || !id || !type || !mask || !state)
|
|
||||||
{
|
|
||||||
JsonFree(state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = StrConcat(9,
|
|
||||||
"/_matrix/client/v3/rooms/", id, "/state/",
|
|
||||||
type, "/", key, "?", "user_id=", mask
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, state);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(state);
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASSend(const ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
char *path;
|
|
||||||
char *txn, *ret;
|
|
||||||
HashMap *reply;
|
|
||||||
if (!conf || !id || !type || !user || !c)
|
|
||||||
{
|
|
||||||
JsonFree(c);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
txn = StrRandom(16);
|
|
||||||
path = StrConcat(9,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
|
||||||
id, "/send/", type, "/", txn, "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
Free(txn);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, c);
|
|
||||||
|
|
||||||
reply = JsonDecode(HttpClientStream(ctx));
|
|
||||||
ret = StrDuplicate(JsonValueAsString(HashMapGet(reply, "event_id")));
|
|
||||||
JsonFree(reply);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(c);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASCreateRoom(const ParseeConfig *conf, char *by, char *alias)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *id;
|
|
||||||
if (!conf || !by)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = StrConcat(3,
|
|
||||||
"/_matrix/client/v3/createRoom",
|
|
||||||
"?user_id=", by
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
if (alias)
|
|
||||||
{
|
|
||||||
char *trimmed = StrDuplicate(alias);
|
|
||||||
if (*alias == '#')
|
|
||||||
{
|
|
||||||
char *tmp, cb[2] = { 0 };
|
|
||||||
alias++;
|
|
||||||
Free(trimmed);
|
|
||||||
trimmed = NULL;
|
|
||||||
|
|
||||||
while (*alias && *alias != ':')
|
|
||||||
{
|
|
||||||
cb[0] = *alias;
|
|
||||||
tmp = trimmed;
|
|
||||||
trimmed = StrConcat(2, trimmed, cb);
|
|
||||||
Free(tmp);
|
|
||||||
alias ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HashMapSet(json, "room_alias_name", JsonValueString(trimmed));
|
|
||||||
Free(trimmed);
|
|
||||||
}
|
|
||||||
HashMapSet(json, "visibility", JsonValueString("public"));
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
JsonFree(json);
|
|
||||||
json = JsonDecode(HttpClientStream(ctx));
|
|
||||||
id = StrDuplicate(JsonValueAsString(HashMapGet(json, "room_id")));
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASCreateDM(const ParseeConfig *conf, char *by, char *with)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json = NULL;
|
|
||||||
char *path, *id;
|
|
||||||
if (!conf || !by || !with)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = StrConcat(3,
|
|
||||||
"/_matrix/client/v3/createRoom",
|
|
||||||
"?user_id=", by
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(
|
|
||||||
conf,
|
|
||||||
HTTP_POST, path
|
|
||||||
);
|
|
||||||
Free(path);
|
|
||||||
json = HashMapCreate();
|
|
||||||
{
|
|
||||||
Array *invitees = ArrayCreate();
|
|
||||||
|
|
||||||
ArrayAdd(invitees, JsonValueString(with));
|
|
||||||
HashMapSet(json, "invite", JsonValueArray(invitees));
|
|
||||||
HashMapSet(json, "is_direct", JsonValueBoolean(true));
|
|
||||||
}
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
JsonFree(json);
|
|
||||||
json = JsonDecode(HttpClientStream(ctx));
|
|
||||||
id = StrDuplicate(JsonValueAsString(HashMapGet(json, "room_id")));
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetAvatar(const ParseeConfig *conf, char *user, char *mxc)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path;
|
|
||||||
if (!conf || !user || !mxc)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
path = StrConcat(6,
|
|
||||||
"/_matrix/client/v3/profile/",
|
|
||||||
user, "/avatar_url", "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "avatar_url", JsonValueString(mxc));
|
|
||||||
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
Free(user);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetName(const ParseeConfig *conf, char *user, char *name)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path;
|
|
||||||
if (!conf || !user || !name)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
path = StrConcat(6,
|
|
||||||
"/_matrix/client/v3/profile/",
|
|
||||||
user, "/displayname", "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "displayname", JsonValueString(name));
|
|
||||||
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(json);
|
|
||||||
Free(user);
|
|
||||||
}
|
|
||||||
HashMap *
|
|
||||||
ASFind(const ParseeConfig *c, char *room, char *event)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path, *user;
|
|
||||||
if (!c || !room || !event)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = StrConcat(4, "@", c->sender_localpart, ":", c->server_base);
|
|
||||||
path = StrConcat(7,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
|
||||||
room, "/event/", event, "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
json = JsonDecode(HttpClientStream(ctx));
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASGetName(const ParseeConfig *c, char *room, char *user)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx;
|
|
||||||
HashMap *reply;
|
|
||||||
char *path, *ret;
|
|
||||||
char *u2 = user;
|
|
||||||
if (!c || !user)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!room)
|
|
||||||
{
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
path = StrConcat(3,
|
|
||||||
"/_matrix/client/v3/profile/", user, "/displayname"
|
|
||||||
);
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
|
||||||
Free(user);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
reply = JsonDecode(HttpClientStream(ctx));
|
|
||||||
|
|
||||||
ret = StrDuplicate(
|
|
||||||
JsonValueAsString(HashMapGet(reply, "displayname"))
|
|
||||||
);
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(reply);
|
|
||||||
Free(path);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
ret = StrDuplicate(u2);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
room = HttpUrlEncode(room);
|
|
||||||
path = StrConcat(4,
|
|
||||||
"/_matrix/client/v3/rooms/", room,
|
|
||||||
"/state/m.room.member/", user
|
|
||||||
);
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
|
||||||
Free(user);
|
|
||||||
Free(room);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
reply = JsonDecode(HttpClientStream(ctx));
|
|
||||||
|
|
||||||
ret = StrDuplicate(
|
|
||||||
JsonValueAsString(HashMapGet(reply, "displayname"))
|
|
||||||
);
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(reply);
|
|
||||||
Free(path);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
ret = StrDuplicate(u2);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
HashMap *
|
|
||||||
ASGetPL(const ParseeConfig *c, char *room)
|
|
||||||
{
|
|
||||||
char *path;
|
|
||||||
HttpClientContext *ctx;
|
|
||||||
HashMap *reply;
|
|
||||||
if (!c || !room)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
room = HttpUrlEncode(room);
|
|
||||||
path = StrConcat(4,
|
|
||||||
"/_matrix/client/v3/rooms/", room,
|
|
||||||
"/state/m.room.power_levels/", ""
|
|
||||||
);
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
|
||||||
Free(room);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
reply = JsonDecode(HttpClientStream(ctx));
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(path);
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetPL(const ParseeConfig *conf, char *id, HashMap *m)
|
|
||||||
{
|
|
||||||
char *user;
|
|
||||||
if (!conf || !id || !m)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
user = StrConcat(4,
|
|
||||||
"@",conf->sender_localpart,
|
|
||||||
":",conf->server_base
|
|
||||||
);
|
|
||||||
ASSetState(conf, id, "m.room.power_levels", "", user, m);
|
|
||||||
Free(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime)
|
|
||||||
{
|
|
||||||
char *size_str, *path, *ret, *user;
|
|
||||||
int i;
|
|
||||||
HttpClientContext *ctx;
|
|
||||||
HashMap *reply;
|
|
||||||
if (!c || !from)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_str = StrInt(size);
|
|
||||||
user = StrConcat(4, "@",c->sender_localpart,":",c->server_base);
|
|
||||||
path = StrConcat(2,
|
|
||||||
"/_matrix/media/v3/upload?user_id=", user
|
|
||||||
);
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_POST, path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
if (size)
|
|
||||||
{
|
|
||||||
HttpRequestHeader(ctx, "Content-Length", size_str);
|
|
||||||
}
|
|
||||||
if (mime)
|
|
||||||
{
|
|
||||||
HttpRequestHeader(ctx, "Content-Type", mime);
|
|
||||||
}
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
int ch = StreamGetc(from);
|
|
||||||
if (ch == EOF)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
StreamPutc(HttpClientStream(ctx), ch);
|
|
||||||
}
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
reply = JsonDecode(HttpClientStream(ctx));
|
|
||||||
ret = StrDuplicate(
|
|
||||||
JsonValueAsString(HashMapGet(reply, "content_uri"))
|
|
||||||
);
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
JsonEncode(reply, StreamStdout(), JSON_PRETTY);
|
|
||||||
StreamFlush(StreamStdout());
|
|
||||||
}
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
JsonFree(reply);
|
|
||||||
Free(size_str);
|
|
||||||
Free(path);
|
|
||||||
Free(user);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ASReupload(const ParseeConfig *c, char *from, char **mime)
|
|
||||||
{
|
|
||||||
Uri *uri;
|
|
||||||
HttpClientContext *ctx;
|
|
||||||
unsigned short port;
|
|
||||||
int size = 0, flags = HTTP_FLAG_NONE;
|
|
||||||
char *ret, *content_len;
|
|
||||||
|
|
||||||
if (!c || !from)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uri = UriParse(from);
|
|
||||||
if (!uri)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (uri->port)
|
|
||||||
{
|
|
||||||
port = uri->port;
|
|
||||||
}
|
|
||||||
else if (StrEquals(uri->proto, "https"))
|
|
||||||
{
|
|
||||||
port = 443;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrEquals(uri->proto, "https"))
|
|
||||||
{
|
|
||||||
flags |= HTTP_FLAG_TLS;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = HttpRequest(
|
|
||||||
HTTP_GET, flags, port, uri->host, uri->path
|
|
||||||
);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
if (mime)
|
|
||||||
{
|
|
||||||
*mime = HashMapGet(HttpResponseHeaders(ctx), "content-type");
|
|
||||||
*mime = StrDuplicate(*mime);
|
|
||||||
}
|
|
||||||
|
|
||||||
content_len = HashMapGet(HttpResponseHeaders(ctx), "content-length");
|
|
||||||
if (content_len)
|
|
||||||
{
|
|
||||||
size = strtol(content_len, NULL, 10);
|
|
||||||
}
|
|
||||||
ret = ASUpload(c, HttpClientStream(ctx), size, mime ? *mime : NULL);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
UriFree(uri);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASType(const ParseeConfig *c, char *user, char *room, bool status)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path;
|
|
||||||
if (!c || !user || !room)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
path = StrConcat(6,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
|
||||||
room, "/typing/", user,
|
|
||||||
"?user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
json = HashMapCreate();
|
|
||||||
HashMapSet(json, "typing", JsonValueBoolean(status));
|
|
||||||
/* If someone types for 10 minutes straight, they got something weird man. */
|
|
||||||
HashMapSet(json, "timeout", JsonValueBoolean(10 MINUTES));
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ASPresence(const ParseeConfig *c, char *user, char *room, char *ev)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path;
|
|
||||||
if (!c || !user || !room || !ev)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
room = HttpUrlEncode(room);
|
|
||||||
ev = HttpUrlEncode(ev);
|
|
||||||
path = StrConcat(6,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
|
||||||
room, "/receipt/m.read/", ev,
|
|
||||||
"?user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
json = HashMapCreate();
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_POST, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, json);
|
|
||||||
JsonFree(json);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
Free(room);
|
|
||||||
Free(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap *
|
|
||||||
ASGetUserConfig(const ParseeConfig *c, char *user, char *key)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *json;
|
|
||||||
char *path;
|
|
||||||
if (!c || !key)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
char *raw = StrConcat(4,
|
|
||||||
"@", c->sender_localpart,
|
|
||||||
":", c->server_base
|
|
||||||
);
|
|
||||||
user = HttpUrlEncode(raw);
|
|
||||||
Free(raw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
}
|
|
||||||
path = StrConcat(7,
|
|
||||||
"/_matrix/client/v3/user/",
|
|
||||||
user, "/account_data/", key, "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
HttpRequestSendHeaders(ctx);
|
|
||||||
HttpRequestSend(ctx);
|
|
||||||
|
|
||||||
json = JsonDecode(HttpClientStream(ctx));
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetUserConfig(const ParseeConfig *c, char *user, char *key, HashMap *map)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
char *path;
|
|
||||||
if (!c || !key || !map)
|
|
||||||
{
|
|
||||||
JsonFree(map);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
char *raw = StrConcat(4,
|
|
||||||
"@", c->sender_localpart,
|
|
||||||
":", c->server_base
|
|
||||||
);
|
|
||||||
user = HttpUrlEncode(raw);
|
|
||||||
Free(raw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
path = StrConcat(7,
|
|
||||||
"/_matrix/client/v3/user/",
|
|
||||||
user, "/account_data/", key, "?",
|
|
||||||
"user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, map);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
JsonFree(map);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASRedact(const ParseeConfig *c, char *room, char *user, char *e_id)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *request;
|
|
||||||
char *path, *txn;
|
|
||||||
if (!c || !room || !e_id)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
char *raw = StrConcat(4,
|
|
||||||
"@", c->sender_localpart,
|
|
||||||
":", c->server_base
|
|
||||||
);
|
|
||||||
user = HttpUrlEncode(raw);
|
|
||||||
Free(raw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
}
|
|
||||||
room = HttpUrlEncode(room);
|
|
||||||
e_id = HttpUrlEncode(e_id);
|
|
||||||
txn = StrRandom(16);
|
|
||||||
|
|
||||||
path = StrConcat(9,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
|
||||||
room, "/redact/", e_id, "/", txn,
|
|
||||||
"?", "user_id=", user
|
|
||||||
);
|
|
||||||
|
|
||||||
request = HashMapCreate();
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
|
||||||
Free(path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, request);
|
|
||||||
JsonFree(request);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(user);
|
|
||||||
Free(room);
|
|
||||||
Free(e_id);
|
|
||||||
Free(txn);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg)
|
|
||||||
{
|
|
||||||
HttpClientContext *ctx = NULL;
|
|
||||||
HashMap *request;
|
|
||||||
char *path;
|
|
||||||
char *status_str = NULL;
|
|
||||||
if (!c || !user)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case USER_STATUS_ONLINE: status_str = "online"; break;
|
|
||||||
case USER_STATUS_OFFLINE: status_str = "offline"; break;
|
|
||||||
case USER_STATUS_UNAVAILABLE: status_str = "unavailable"; break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = HttpUrlEncode(user);
|
|
||||||
path = StrConcat(5,
|
|
||||||
"/_matrix/client/v3/presence/",user,"/status",
|
|
||||||
"?user_id=", user
|
|
||||||
);
|
|
||||||
Free(user);
|
|
||||||
|
|
||||||
request = HashMapCreate();
|
|
||||||
HashMapSet(request, "presence", JsonValueString(status_str));
|
|
||||||
if (msg)
|
|
||||||
{
|
|
||||||
HashMapSet(request, "status_msg", JsonValueString(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
|
||||||
ASAuthenticateRequest(c, ctx);
|
|
||||||
ParseeSetRequestJSON(ctx, request);
|
|
||||||
JsonFree(request);
|
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
|
||||||
Free(path);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
93
src/AS/Events.c
Normal file
93
src/AS/Events.c
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
HashMap *
|
||||||
|
ASFind(const ParseeConfig *c, char *room, char *event)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json;
|
||||||
|
char *path, *user;
|
||||||
|
if (!c || !room || !event)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = StrConcat(4, "@", c->sender_localpart, ":", c->server_base);
|
||||||
|
path = StrConcat(7,
|
||||||
|
"/_matrix/client/v3/rooms/",
|
||||||
|
room, "/event/", event, "?",
|
||||||
|
"user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
json = JsonDecode(HttpClientStream(ctx));
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(user);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ASRedact(const ParseeConfig *c, char *room, char *user, char *e_id)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *request;
|
||||||
|
char *path, *txn;
|
||||||
|
if (!c || !room || !e_id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
{
|
||||||
|
char *raw = StrConcat(4,
|
||||||
|
"@", c->sender_localpart,
|
||||||
|
":", c->server_base
|
||||||
|
);
|
||||||
|
user = HttpUrlEncode(raw);
|
||||||
|
Free(raw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
}
|
||||||
|
room = HttpUrlEncode(room);
|
||||||
|
e_id = HttpUrlEncode(e_id);
|
||||||
|
txn = StrRandom(16);
|
||||||
|
|
||||||
|
path = StrConcat(9,
|
||||||
|
"/_matrix/client/v3/rooms/",
|
||||||
|
room, "/redact/", e_id, "/", txn,
|
||||||
|
"?", "user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
request = HashMapCreate();
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, request);
|
||||||
|
JsonFree(request);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(user);
|
||||||
|
Free(room);
|
||||||
|
Free(e_id);
|
||||||
|
Free(txn);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
119
src/AS/Indicators.c
Normal file
119
src/AS/Indicators.c
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ASType(const ParseeConfig *c, char *user, char *room, bool status)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json;
|
||||||
|
char *path;
|
||||||
|
if (!c || !user || !room)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
path = StrConcat(6,
|
||||||
|
"/_matrix/client/v3/rooms/",
|
||||||
|
room, "/typing/", user,
|
||||||
|
"?user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "typing", JsonValueBoolean(status));
|
||||||
|
/* If someone types for 10 minutes straight, they got something weird man. */
|
||||||
|
HashMapSet(json, "timeout", JsonValueBoolean(10 MINUTES));
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ASPresence(const ParseeConfig *c, char *user, char *room, char *ev)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json;
|
||||||
|
char *path;
|
||||||
|
if (!c || !user || !room || !ev)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
room = HttpUrlEncode(room);
|
||||||
|
ev = HttpUrlEncode(ev);
|
||||||
|
path = StrConcat(6,
|
||||||
|
"/_matrix/client/v3/rooms/",
|
||||||
|
room, "/receipt/m.read/", ev,
|
||||||
|
"?user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
json = HashMapCreate();
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_POST, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(user);
|
||||||
|
Free(room);
|
||||||
|
Free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *request;
|
||||||
|
char *path;
|
||||||
|
char *status_str = NULL;
|
||||||
|
if (!c || !user)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case USER_STATUS_ONLINE: status_str = "online"; break;
|
||||||
|
case USER_STATUS_OFFLINE: status_str = "offline"; break;
|
||||||
|
case USER_STATUS_UNAVAILABLE: status_str = "unavailable"; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/presence/",user,"/status",
|
||||||
|
"?user_id=", user
|
||||||
|
);
|
||||||
|
Free(user);
|
||||||
|
|
||||||
|
request = HashMapCreate();
|
||||||
|
HashMapSet(request, "presence", JsonValueString(status_str));
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
HashMapSet(request, "status_msg", JsonValueString(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_PUT, path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, request);
|
||||||
|
JsonFree(request);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(path);
|
||||||
|
}
|
||||||
129
src/AS/Media.c
Normal file
129
src/AS/Media.c
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime)
|
||||||
|
{
|
||||||
|
char *size_str, *path, *ret, *user;
|
||||||
|
int i;
|
||||||
|
HttpClientContext *ctx;
|
||||||
|
HashMap *reply;
|
||||||
|
if (!c || !from)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_str = StrInt(size);
|
||||||
|
user = StrConcat(4, "@",c->sender_localpart,":",c->server_base);
|
||||||
|
path = StrConcat(2,
|
||||||
|
"/_matrix/media/v3/upload?user_id=", user
|
||||||
|
);
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_POST, path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
HttpRequestHeader(ctx, "Content-Length", size_str);
|
||||||
|
}
|
||||||
|
if (mime)
|
||||||
|
{
|
||||||
|
HttpRequestHeader(ctx, "Content-Type", mime);
|
||||||
|
}
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
int ch = StreamGetc(from);
|
||||||
|
if (ch == EOF)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
StreamPutc(HttpClientStream(ctx), ch);
|
||||||
|
}
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
reply = JsonDecode(HttpClientStream(ctx));
|
||||||
|
ret = StrDuplicate(
|
||||||
|
JsonValueAsString(HashMapGet(reply, "content_uri"))
|
||||||
|
);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
JsonEncode(reply, StreamStdout(), JSON_PRETTY);
|
||||||
|
StreamFlush(StreamStdout());
|
||||||
|
}
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(reply);
|
||||||
|
Free(size_str);
|
||||||
|
Free(path);
|
||||||
|
Free(user);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ASReupload(const ParseeConfig *c, char *from, char **mime)
|
||||||
|
{
|
||||||
|
Uri *uri;
|
||||||
|
HttpClientContext *ctx;
|
||||||
|
unsigned short port;
|
||||||
|
int size = 0, flags = HTTP_FLAG_NONE;
|
||||||
|
char *ret, *content_len;
|
||||||
|
|
||||||
|
if (!c || !from)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uri = UriParse(from);
|
||||||
|
if (!uri)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (uri->port)
|
||||||
|
{
|
||||||
|
port = uri->port;
|
||||||
|
}
|
||||||
|
else if (StrEquals(uri->proto, "https"))
|
||||||
|
{
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEquals(uri->proto, "https"))
|
||||||
|
{
|
||||||
|
flags |= HTTP_FLAG_TLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = HttpRequest(
|
||||||
|
HTTP_GET, flags, port, uri->host, uri->path
|
||||||
|
);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
if (mime)
|
||||||
|
{
|
||||||
|
*mime = HashMapGet(HttpResponseHeaders(ctx), "content-type");
|
||||||
|
*mime = StrDuplicate(*mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
content_len = HashMapGet(HttpResponseHeaders(ctx), "content-length");
|
||||||
|
if (content_len)
|
||||||
|
{
|
||||||
|
size = strtol(content_len, NULL, 10);
|
||||||
|
}
|
||||||
|
ret = ASUpload(c, HttpClientStream(ctx), size, mime ? *mime : NULL);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
UriFree(uri);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
39
src/AS/Ping.c
Normal file
39
src/AS/Ping.c
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ASPing(const ParseeConfig *conf)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path;
|
||||||
|
if (!conf)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = StrConcat(3,
|
||||||
|
"/_matrix/client/v1/appservice/",
|
||||||
|
"Parsee%20XMPP",
|
||||||
|
"/ping"
|
||||||
|
);
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
}
|
||||||
138
src/AS/Profile.c
Normal file
138
src/AS/Profile.c
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ASSetAvatar(const ParseeConfig *conf, char *user, char *mxc)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json;
|
||||||
|
char *path;
|
||||||
|
if (!conf || !user || !mxc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
path = StrConcat(6,
|
||||||
|
"/_matrix/client/v3/profile/",
|
||||||
|
user, "/avatar_url", "?",
|
||||||
|
"user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "avatar_url", JsonValueString(mxc));
|
||||||
|
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
Free(user);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ASSetName(const ParseeConfig *conf, char *user, char *name)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json;
|
||||||
|
char *path;
|
||||||
|
if (!conf || !user || !name)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
path = StrConcat(6,
|
||||||
|
"/_matrix/client/v3/profile/",
|
||||||
|
user, "/displayname", "?",
|
||||||
|
"user_id=", user
|
||||||
|
);
|
||||||
|
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "displayname", JsonValueString(name));
|
||||||
|
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
Free(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ASGetName(const ParseeConfig *c, char *room, char *user)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx;
|
||||||
|
HashMap *reply;
|
||||||
|
char *path, *ret;
|
||||||
|
char *u2 = user;
|
||||||
|
if (!c || !user)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!room)
|
||||||
|
{
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
path = StrConcat(3,
|
||||||
|
"/_matrix/client/v3/profile/", user, "/displayname"
|
||||||
|
);
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
||||||
|
Free(user);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
reply = JsonDecode(HttpClientStream(ctx));
|
||||||
|
|
||||||
|
ret = StrDuplicate(
|
||||||
|
JsonValueAsString(HashMapGet(reply, "displayname"))
|
||||||
|
);
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(reply);
|
||||||
|
Free(path);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
ret = StrDuplicate(u2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
user = HttpUrlEncode(user);
|
||||||
|
room = HttpUrlEncode(room);
|
||||||
|
path = StrConcat(4,
|
||||||
|
"/_matrix/client/v3/rooms/", room,
|
||||||
|
"/state/m.room.member/", user
|
||||||
|
);
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
||||||
|
Free(user);
|
||||||
|
Free(room);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
reply = JsonDecode(HttpClientStream(ctx));
|
||||||
|
|
||||||
|
ret = StrDuplicate(
|
||||||
|
JsonValueAsString(HashMapGet(reply, "displayname"))
|
||||||
|
);
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(reply);
|
||||||
|
Free(path);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
ret = StrDuplicate(u2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
46
src/AS/Register.c
Normal file
46
src/AS/Register.c
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
bool
|
||||||
|
ASRegisterUser(const ParseeConfig *conf, char *user)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
HttpStatus status;
|
||||||
|
if (!conf || !user)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create user. We don't actually care about the value as we can
|
||||||
|
* masquerade, as long as it exists. */
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, "/_matrix/client/v3/register"
|
||||||
|
);
|
||||||
|
json = HashMapCreate();
|
||||||
|
|
||||||
|
HashMapSet(json,"type",JsonValueString("m.login.application_service"));
|
||||||
|
|
||||||
|
user = ParseeGetLocal(user);
|
||||||
|
HashMapSet(json,"username",JsonValueString(user));
|
||||||
|
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
status = ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
Free(user);
|
||||||
|
|
||||||
|
return status == HTTP_OK;
|
||||||
|
}
|
||||||
81
src/AS/Relations.c
Normal file
81
src/AS/Relations.c
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
Array *
|
||||||
|
ASGetRelations(const ParseeConfig *c, size_t n, char *room, char *event, char *type)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
Array *ret, *chunk;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path;
|
||||||
|
char *user;
|
||||||
|
size_t i;
|
||||||
|
if (!c || !n || !room || !event)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = StrConcat(4, "@", c->sender_localpart, ":", c->server_base);
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
path = StrConcat(6,
|
||||||
|
"/_matrix/client/v1/rooms/", room,
|
||||||
|
"/relations/", event,
|
||||||
|
"?user_id=", user
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = StrConcat(4,
|
||||||
|
"/_matrix/client/v1/rooms/", room,
|
||||||
|
"/relations?user_id=", user
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Free(user);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
|
||||||
|
json = JsonDecode(HttpClientStream(ctx));
|
||||||
|
ret = ArrayCreate();
|
||||||
|
chunk = GrabArray(json, 1, "chunk");
|
||||||
|
for (i = 0; i < ArraySize(chunk); i++)
|
||||||
|
{
|
||||||
|
HashMap *obj = JsonValueAsObject(ArrayGet(chunk, i));
|
||||||
|
ArrayAdd(ret, JsonDuplicate(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ASFreeRelations(Array *relations)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
if (!relations)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ArraySize(relations); i++)
|
||||||
|
{
|
||||||
|
JsonFree(ArrayGet(relations, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayFree(relations);
|
||||||
|
}
|
||||||
352
src/AS/Room.c
Normal file
352
src/AS/Room.c
Normal file
|
|
@ -0,0 +1,352 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ASInvite(const ParseeConfig *conf, char *id, char *invited)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *bridge;
|
||||||
|
if (!conf || !id || !invited)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge = StrConcat(4,
|
||||||
|
"@", conf->sender_localpart,
|
||||||
|
":", conf->server_base
|
||||||
|
);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/rooms/", id, "/invite",
|
||||||
|
"?user_id=", bridge
|
||||||
|
);
|
||||||
|
Free(bridge);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "user_id", JsonValueString(invited));
|
||||||
|
HashMapSet(json, "reason", JsonValueString("Pass over."));
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ASBan(const ParseeConfig *conf, char *id, char *banned)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *bridge;
|
||||||
|
if (!conf || !id || !banned)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge = StrConcat(4,
|
||||||
|
"@", conf->sender_localpart,
|
||||||
|
":", conf->server_base
|
||||||
|
);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/rooms/", id, "/ban",
|
||||||
|
"?user_id=", bridge
|
||||||
|
);
|
||||||
|
Free(bridge);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "user_id", JsonValueString(banned));
|
||||||
|
HashMapSet(json, "reason", JsonValueString("Parsee felt jealous."));
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ASKick(const ParseeConfig *conf, char *id, char *banned)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *bridge;
|
||||||
|
if (!conf || !id || !banned)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge = StrConcat(4,
|
||||||
|
"@", conf->sender_localpart,
|
||||||
|
":", conf->server_base
|
||||||
|
);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/rooms/", id, "/kick",
|
||||||
|
"?user_id=", bridge
|
||||||
|
);
|
||||||
|
Free(bridge);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
HashMapSet(json, "user_id", JsonValueString(banned));
|
||||||
|
HashMapSet(json, "reason", JsonValueString("Parsee felt jealous."));
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *ret;
|
||||||
|
if (!conf || !id)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!masquerade)
|
||||||
|
{
|
||||||
|
char *raw = StrConcat(4,
|
||||||
|
"@", conf->sender_localpart,
|
||||||
|
":", conf->server_base
|
||||||
|
);
|
||||||
|
masquerade = HttpUrlEncode(raw);
|
||||||
|
Free(raw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
masquerade = HttpUrlEncode(masquerade);
|
||||||
|
}
|
||||||
|
id = HttpUrlEncode(id);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/join/", id, "?",
|
||||||
|
"user_id=", masquerade
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
json = JsonDecode(HttpClientStream(ctx));
|
||||||
|
ret = StrDuplicate(GrabString(json, 1, "room_id"));
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(masquerade);
|
||||||
|
Free(id);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ASLeave(const ParseeConfig *conf, char *id, char *masquerade)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path;
|
||||||
|
if (!conf || !id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!masquerade)
|
||||||
|
{
|
||||||
|
char *raw = StrConcat(4,
|
||||||
|
"@", conf->sender_localpart,
|
||||||
|
":", conf->server_base
|
||||||
|
);
|
||||||
|
masquerade = HttpUrlEncode(raw);
|
||||||
|
Free(raw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
masquerade = HttpUrlEncode(masquerade);
|
||||||
|
}
|
||||||
|
id = HttpUrlEncode(id);
|
||||||
|
path = StrConcat(5,
|
||||||
|
"/_matrix/client/v3/rooms/", id, "/leave?",
|
||||||
|
"user_id=", masquerade
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(masquerade);
|
||||||
|
Free(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ASCreateRoom(const ParseeConfig *conf, char *by, char *alias)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *id;
|
||||||
|
if (!conf || !by)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = StrConcat(3,
|
||||||
|
"/_matrix/client/v3/createRoom",
|
||||||
|
"?user_id=", by
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
if (alias)
|
||||||
|
{
|
||||||
|
char *trimmed = StrDuplicate(alias);
|
||||||
|
if (*alias == '#')
|
||||||
|
{
|
||||||
|
char *tmp, cb[2] = { 0 };
|
||||||
|
alias++;
|
||||||
|
Free(trimmed);
|
||||||
|
trimmed = NULL;
|
||||||
|
|
||||||
|
while (*alias && *alias != ':')
|
||||||
|
{
|
||||||
|
cb[0] = *alias;
|
||||||
|
tmp = trimmed;
|
||||||
|
trimmed = StrConcat(2, trimmed, cb);
|
||||||
|
Free(tmp);
|
||||||
|
alias ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HashMapSet(json, "room_alias_name", JsonValueString(trimmed));
|
||||||
|
Free(trimmed);
|
||||||
|
}
|
||||||
|
HashMapSet(json, "visibility", JsonValueString("public"));
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
JsonFree(json);
|
||||||
|
json = JsonDecode(HttpClientStream(ctx));
|
||||||
|
id = StrDuplicate(JsonValueAsString(HashMapGet(json, "room_id")));
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ASCreateDM(const ParseeConfig *conf, char *by, char *with)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
HashMap *json = NULL;
|
||||||
|
char *path, *id;
|
||||||
|
if (!conf || !by || !with)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = StrConcat(3,
|
||||||
|
"/_matrix/client/v3/createRoom",
|
||||||
|
"?user_id=", by
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(
|
||||||
|
conf,
|
||||||
|
HTTP_POST, path
|
||||||
|
);
|
||||||
|
Free(path);
|
||||||
|
json = HashMapCreate();
|
||||||
|
{
|
||||||
|
Array *invitees = ArrayCreate();
|
||||||
|
|
||||||
|
ArrayAdd(invitees, JsonValueString(with));
|
||||||
|
HashMapSet(json, "invite", JsonValueArray(invitees));
|
||||||
|
HashMapSet(json, "is_direct", JsonValueBoolean(true));
|
||||||
|
}
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, json);
|
||||||
|
|
||||||
|
JsonFree(json);
|
||||||
|
json = JsonDecode(HttpClientStream(ctx));
|
||||||
|
id = StrDuplicate(JsonValueAsString(HashMapGet(json, "room_id")));
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(json);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap *
|
||||||
|
ASGetPL(const ParseeConfig *c, char *room)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
HttpClientContext *ctx;
|
||||||
|
HashMap *reply;
|
||||||
|
if (!c || !room)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
room = HttpUrlEncode(room);
|
||||||
|
path = StrConcat(4,
|
||||||
|
"/_matrix/client/v3/rooms/", room,
|
||||||
|
"/state/m.room.power_levels/", ""
|
||||||
|
);
|
||||||
|
ctx = ParseeCreateRequest(c, HTTP_GET, path);
|
||||||
|
Free(room);
|
||||||
|
ASAuthenticateRequest(c, ctx);
|
||||||
|
HttpRequestSendHeaders(ctx);
|
||||||
|
HttpRequestSend(ctx);
|
||||||
|
|
||||||
|
reply = JsonDecode(HttpClientStream(ctx));
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
Free(path);
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
ASSetPL(const ParseeConfig *conf, char *id, HashMap *m)
|
||||||
|
{
|
||||||
|
char *user;
|
||||||
|
if (!conf || !id || !m)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
user = StrConcat(4,
|
||||||
|
"@",conf->sender_localpart,
|
||||||
|
":",conf->server_base
|
||||||
|
);
|
||||||
|
ASSetState(conf, id, "m.room.power_levels", "", user, m);
|
||||||
|
Free(user);
|
||||||
|
}
|
||||||
48
src/AS/Send.c
Normal file
48
src/AS/Send.c
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
ASSend(const ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
char *path;
|
||||||
|
char *txn, *ret;
|
||||||
|
HashMap *reply;
|
||||||
|
if (!conf || !id || !type || !user || !c)
|
||||||
|
{
|
||||||
|
JsonFree(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
txn = StrRandom(16);
|
||||||
|
path = StrConcat(9,
|
||||||
|
"/_matrix/client/v3/rooms/",
|
||||||
|
id, "/send/", type, "/", txn, "?",
|
||||||
|
"user_id=", user
|
||||||
|
);
|
||||||
|
Free(txn);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, c);
|
||||||
|
|
||||||
|
reply = JsonDecode(HttpClientStream(ctx));
|
||||||
|
ret = StrDuplicate(JsonValueAsString(HashMapGet(reply, "event_id")));
|
||||||
|
JsonFree(reply);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(c);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
37
src/AS/State.c
Normal file
37
src/AS/State.c
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *state)
|
||||||
|
{
|
||||||
|
HttpClientContext *ctx = NULL;
|
||||||
|
char *path;
|
||||||
|
if (!conf || !id || !type || !mask || !state)
|
||||||
|
{
|
||||||
|
JsonFree(state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = StrConcat(9,
|
||||||
|
"/_matrix/client/v3/rooms/", id, "/state/",
|
||||||
|
type, "/", key, "?", "user_id=", mask
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
||||||
|
Free(path);
|
||||||
|
ASAuthenticateRequest(conf, ctx);
|
||||||
|
ParseeSetRequestJSON(ctx, state);
|
||||||
|
|
||||||
|
HttpClientContextFree(ctx);
|
||||||
|
JsonFree(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -80,6 +80,13 @@ DecodeQuote(StringRect rect, size_t *skip)
|
||||||
ret = rect;
|
ret = rect;
|
||||||
ret.end_line--;
|
ret.end_line--;
|
||||||
|
|
||||||
|
/* TODO: You can easily craft strings that conceal data(
|
||||||
|
* > Please mind the whitespace
|
||||||
|
* > hidden we're concealing data to Matrix
|
||||||
|
* > star in Well, you can still stare at the body and XML
|
||||||
|
* > four but that's for Nerds
|
||||||
|
* > seasons See, Touhou reference!
|
||||||
|
* concealing!) */
|
||||||
while ((ch = StrGet(&rect, lines - 1, shift_by)) && isspace(ch))
|
while ((ch = StrGet(&rect, lines - 1, shift_by)) && isspace(ch))
|
||||||
{
|
{
|
||||||
shift_by++;
|
shift_by++;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ XMPPDispatcher(void *argp)
|
||||||
{
|
{
|
||||||
XMLElement *stanza = RetrieveStanza(thread);
|
XMLElement *stanza = RetrieveStanza(thread);
|
||||||
|
|
||||||
/* TODO: I've seen some spikes in some threads. */
|
|
||||||
if (!stanza)
|
if (!stanza)
|
||||||
{
|
{
|
||||||
UtilSleepMillis(5);
|
UtilSleepMillis(5);
|
||||||
|
|
@ -153,7 +152,6 @@ ParseeXMPPThread(void *argp)
|
||||||
pthread_mutex_init(&info.lock, NULL);
|
pthread_mutex_init(&info.lock, NULL);
|
||||||
|
|
||||||
/* ... and its readers. */
|
/* ... and its readers. */
|
||||||
/* TODO: Make that configurable. */
|
|
||||||
info.available_dispatchers = args->config->xmpp_threads;
|
info.available_dispatchers = args->config->xmpp_threads;
|
||||||
info.dispatchers = Malloc(
|
info.dispatchers = Malloc(
|
||||||
sizeof(*info.dispatchers) * info.available_dispatchers
|
sizeof(*info.dispatchers) * info.available_dispatchers
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,62 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
ProcessChatstates(ParseeData *args, XMLElement *stanza)
|
||||||
|
{
|
||||||
|
char *from_matrix, *mroom_id;
|
||||||
|
#define CHAT_STATES "http://jabber.org/protocol/chatstates"
|
||||||
|
if (XMLookForTKV(stanza, "composing", "xmlns", CHAT_STATES))
|
||||||
|
{
|
||||||
|
from_matrix = ParseeGetBridgedUser(args, stanza);
|
||||||
|
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
||||||
|
|
||||||
|
ASType(args->config, from_matrix, mroom_id, true);
|
||||||
|
|
||||||
|
Free(from_matrix);
|
||||||
|
Free(mroom_id);
|
||||||
|
mroom_id = NULL;
|
||||||
|
from_matrix = NULL;
|
||||||
|
}
|
||||||
|
if (XMLookForTKV(stanza, "active", "xmlns", CHAT_STATES))
|
||||||
|
{
|
||||||
|
char *latest = NULL;
|
||||||
|
from_matrix = ParseeGetBridgedUser(args, stanza);
|
||||||
|
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
||||||
|
|
||||||
|
latest = ParseeLookupHead(mroom_id);
|
||||||
|
|
||||||
|
ASType(args->config, from_matrix, mroom_id, false);
|
||||||
|
ASPresence(args->config, from_matrix, mroom_id, latest);
|
||||||
|
|
||||||
|
Free(from_matrix);
|
||||||
|
Free(latest);
|
||||||
|
Free(mroom_id);
|
||||||
|
mroom_id = NULL;
|
||||||
|
from_matrix = NULL;
|
||||||
|
}
|
||||||
|
if (XMLookForTKV(stanza, "paused", "xmlns", CHAT_STATES) ||
|
||||||
|
XMLookForTKV(stanza, "received", "xmlns", "urn:xmpp:receipts") ||
|
||||||
|
XMLookForTKV(stanza, "displayed", "xmlns", "urn:xmpp:chat-markers:0"))
|
||||||
|
{
|
||||||
|
/* TODO: Use stanza ID if possible */
|
||||||
|
char *latest = NULL;
|
||||||
|
from_matrix = ParseeGetBridgedUser(args, stanza);
|
||||||
|
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
||||||
|
|
||||||
|
latest = ParseeLookupHead(mroom_id);
|
||||||
|
|
||||||
|
ASPresence(args->config, from_matrix, mroom_id, latest);
|
||||||
|
|
||||||
|
Free(from_matrix);
|
||||||
|
Free(latest);
|
||||||
|
Free(mroom_id);
|
||||||
|
mroom_id = NULL;
|
||||||
|
from_matrix = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
#undef CHAT_STATES
|
||||||
|
}
|
||||||
bool
|
bool
|
||||||
MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
{
|
{
|
||||||
|
|
@ -107,57 +163,7 @@ end_error:
|
||||||
PEPManagerHandle(thr->info->pep_manager, stanza);
|
PEPManagerHandle(thr->info->pep_manager, stanza);
|
||||||
|
|
||||||
/* TODO: Separate the chatstate processing code. */
|
/* TODO: Separate the chatstate processing code. */
|
||||||
#define CHAT_STATES "http://jabber.org/protocol/chatstates"
|
ProcessChatstates(args, stanza);
|
||||||
if (XMLookForTKV(stanza, "composing", "xmlns", CHAT_STATES))
|
|
||||||
{
|
|
||||||
from_matrix = ParseeGetBridgedUser(args, stanza);
|
|
||||||
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
|
||||||
|
|
||||||
ASType(args->config, from_matrix, mroom_id, true);
|
|
||||||
|
|
||||||
Free(from_matrix);
|
|
||||||
Free(mroom_id);
|
|
||||||
mroom_id = NULL;
|
|
||||||
from_matrix = NULL;
|
|
||||||
}
|
|
||||||
if (XMLookForTKV(stanza, "active", "xmlns", CHAT_STATES))
|
|
||||||
{
|
|
||||||
char *latest = NULL;
|
|
||||||
from_matrix = ParseeGetBridgedUser(args, stanza);
|
|
||||||
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
|
||||||
|
|
||||||
latest = ParseeLookupHead(mroom_id);
|
|
||||||
|
|
||||||
ASType(args->config, from_matrix, mroom_id, false);
|
|
||||||
ASPresence(args->config, from_matrix, mroom_id, latest);
|
|
||||||
|
|
||||||
Free(from_matrix);
|
|
||||||
Free(latest);
|
|
||||||
Free(mroom_id);
|
|
||||||
mroom_id = NULL;
|
|
||||||
from_matrix = NULL;
|
|
||||||
}
|
|
||||||
if (XMLookForTKV(stanza, "paused", "xmlns", CHAT_STATES) ||
|
|
||||||
XMLookForTKV(stanza, "received", "xmlns", "urn:xmpp:receipts") ||
|
|
||||||
XMLookForTKV(stanza, "displayed", "xmlns", "urn:xmpp:chat-markers:0"))
|
|
||||||
{
|
|
||||||
/* TODO: Use stanza ID if possible */
|
|
||||||
char *latest = NULL;
|
|
||||||
from_matrix = ParseeGetBridgedUser(args, stanza);
|
|
||||||
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
|
||||||
|
|
||||||
latest = ParseeLookupHead(mroom_id);
|
|
||||||
|
|
||||||
ASPresence(args->config, from_matrix, mroom_id, latest);
|
|
||||||
|
|
||||||
Free(from_matrix);
|
|
||||||
Free(latest);
|
|
||||||
Free(mroom_id);
|
|
||||||
mroom_id = NULL;
|
|
||||||
from_matrix = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
#undef CHAT_STATES
|
|
||||||
|
|
||||||
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
||||||
decode_from = ParseeLookupJID(from);
|
decode_from = ParseeLookupJID(from);
|
||||||
|
|
@ -283,8 +289,28 @@ end_error:
|
||||||
else if (reactions)
|
else if (reactions)
|
||||||
{
|
{
|
||||||
Array *react_child = reactions->children;
|
Array *react_child = reactions->children;
|
||||||
|
Array *to_redact;
|
||||||
size_t reacts = ArraySize(react_child);
|
size_t reacts = ArraySize(react_child);
|
||||||
event_id = ParseeGetReactedEvent(args, stanza);
|
event_id = ParseeGetReactedEvent(args, stanza);
|
||||||
|
|
||||||
|
to_redact = ASGetRelations(
|
||||||
|
args->config, 30, mroom_id, event_id,
|
||||||
|
"m.reaction"
|
||||||
|
);
|
||||||
|
for (i = 0; i < ArraySize(to_redact); i++)
|
||||||
|
{
|
||||||
|
HashMap *e = ArrayGet(to_redact, i);
|
||||||
|
char *e_sender = GrabString(e, 1, "sender");
|
||||||
|
char *e_id = GrabString(e, 1, "event_id");
|
||||||
|
if (!StrEquals(e_sender, encoded))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASRedact(args->config, mroom_id, encoded, e_id);
|
||||||
|
}
|
||||||
|
ASFreeRelations(to_redact);
|
||||||
|
|
||||||
for (i = 0; i < reacts; i++)
|
for (i = 0; i < reacts; i++)
|
||||||
{
|
{
|
||||||
XMLElement *reaction, *react_data;
|
XMLElement *reaction, *react_data;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
/*-*
|
/*-*
|
||||||
* Functions used to communicate with a Matrix server and execute actions
|
* Functions used to communicate with a Matrix server and execute actions
|
||||||
* over HTTP(S)+JSON. This effectively serves as Parsee's Matrix SDK.
|
* over HTTP(S)+JSON. This effectively serves as Parsee's Matrix SDK.
|
||||||
* TODO: Write my own RanSDK for KappaChat.
|
* TODO: Write my own RumiaSDK for the KappaChat project(not the client
|
||||||
|
* itself).
|
||||||
* --------
|
* --------
|
||||||
* Writren-By: LDA */
|
* Writren-By: LDA */
|
||||||
|
|
||||||
|
|
@ -156,6 +157,17 @@ extern char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, c
|
||||||
* See-Also: ASUpload */
|
* See-Also: ASUpload */
|
||||||
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
||||||
|
|
||||||
extern HashMap * ASGetUserConfig(const ParseeConfig *c, char *user, char *key);
|
/** Gets up to {n} relations to an event(with a specific type, optionally).
|
||||||
extern void ASSetUserConfig(const ParseeConfig *c, char *u, char *key, HashMap *map);
|
* ----------
|
||||||
|
* Returns: A list of JSON objects[HEAP]
|
||||||
|
* Thrasher: ASFreeRelations
|
||||||
|
* See-Also: https://spec.matrix.org/v1.7/client-server-api/#get_matrixclientv1roomsroomidrelationseventid */
|
||||||
|
extern Array * ASGetRelations(const ParseeConfig *c, size_t n, char *room, char *event, char *type);
|
||||||
|
|
||||||
|
/** Destroys a relation list created by {ASGetRelations}
|
||||||
|
* ------------
|
||||||
|
* Returns: NOTHING
|
||||||
|
* Thrashes: {relations}
|
||||||
|
* See-Also: ASGetRelations */
|
||||||
|
extern void ASFreeRelations(Array *relations);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue