mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 15:05:11 +00:00
[MOD] Mess a bit with rich replies, add XEPS-TBD
This should be a nice list of future XEPs to be implemented, so that I can keep track of these without having to keep all of these in my head.
This commit is contained in:
parent
ae740878c8
commit
628a55fbca
6 changed files with 127 additions and 18 deletions
17
XEPS-TBD.TXT
Normal file
17
XEPS-TBD.TXT
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
XEPs current supported are in src/XMPPThread.c, at the IQ disco advertising.
|
||||||
|
|
||||||
|
For future XEPs:
|
||||||
|
- https://xmpp.org/extensions/xep-0444.html
|
||||||
|
This allows reactions, which Matrix also has support to. The two
|
||||||
|
systems don't seem *too* restrictive on one-another (unlike some
|
||||||
|
IM platforms I won't mention), so this doesn't sound too bad.
|
||||||
|
- https://xmpp.org/extensions/xep-0118.html
|
||||||
|
Informations on what a user is listening to. Matrix doesn't have
|
||||||
|
good support for status, to be frank. Clients (including KappaChat)
|
||||||
|
should consider having more support for those, rather than it being
|
||||||
|
stuck as a FluffyChat/Nheko feature.
|
||||||
|
If any client devs hear this, please consider adding these,
|
||||||
|
(especially if you're a smElement employee!)
|
||||||
|
- https://xmpp.org/extensions/xep-0084.html
|
||||||
|
Avatar support would be extremely useful, if just a QoL improvment.
|
||||||
|
Matrix and XMPP both have support for these.
|
||||||
31
src/AS.c
31
src/AS.c
|
|
@ -289,6 +289,37 @@ ASSetName(const ParseeConfig *conf, char *user, char *name)
|
||||||
JsonFree(json);
|
JsonFree(json);
|
||||||
Free(user);
|
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->homeserver_host);
|
||||||
|
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 *
|
char *
|
||||||
ASGetName(const ParseeConfig *c, char *room, char *user)
|
ASGetName(const ParseeConfig *c, char *room, char *user)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Routes.h>
|
#include <Routes.h>
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
ParseeData *
|
ParseeData *
|
||||||
ParseeInitData(XMPPComponent *comp)
|
ParseeInitData(XMPPComponent *comp)
|
||||||
|
|
@ -82,7 +83,7 @@ ParseeCleanup(void *datp)
|
||||||
uint64_t age = JsonValueAsInteger(HashMapGet(obj, "age"));
|
uint64_t age = JsonValueAsInteger(HashMapGet(obj, "age"));
|
||||||
uint64_t dur = ts - age;
|
uint64_t dur = ts - age;
|
||||||
|
|
||||||
if ((dur > (5 MINUTES)))
|
if ((dur > (30 MINUTES)))
|
||||||
{
|
{
|
||||||
ArrayAdd(to_delete, StrDuplicate(stanza));
|
ArrayAdd(to_delete, StrDuplicate(stanza));
|
||||||
}
|
}
|
||||||
|
|
@ -134,18 +135,44 @@ ParseeFindDatastart(char *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <StringStream.h>
|
#include <StringStream.h>
|
||||||
|
typedef struct XMPPFlags {
|
||||||
|
bool quote;
|
||||||
|
} XMPPFlags;
|
||||||
static char *
|
static char *
|
||||||
XMPPifyElement(XMLElement *elem)
|
XMPPifyElement(HashMap *event, XMLElement *elem, XMPPFlags flags)
|
||||||
{
|
{
|
||||||
char *xepd = NULL, *tmp = NULL;
|
char *xepd = NULL, *tmp = NULL;
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
XMLElement *child;
|
XMLElement *child;
|
||||||
|
char *reply_id = JsonValueAsString(
|
||||||
|
JsonGet(event, 4,
|
||||||
|
"content", "m.relates_to", "m.in_reply_to", "event_id"
|
||||||
|
));
|
||||||
|
char *room_id = JsonValueAsString(HashMapGet(event, "room_id"));
|
||||||
|
HashMap *referenced;
|
||||||
char *subxep;
|
char *subxep;
|
||||||
#define Concat(strp) tmp = xepd; \
|
#define Concat(strp) do \
|
||||||
xepd = StrConcat(2, xepd, strp); \
|
{ \
|
||||||
Free(tmp)
|
size_t cidx; \
|
||||||
|
for (cidx = 0; cidx < strlen(strp); cidx++) \
|
||||||
|
{ \
|
||||||
|
char cch[2] = { strp[cidx], 0 }; \
|
||||||
|
char nch = *cch ? strp[cidx+1] : '\0'; \
|
||||||
|
bool c = *cch == '\n' && nch != '>'; \
|
||||||
|
if (c && flags.quote) \
|
||||||
|
{ \
|
||||||
|
tmp = xepd; \
|
||||||
|
xepd = StrConcat(2, xepd, "\n>"); \
|
||||||
|
Free(tmp); \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
tmp = xepd; \
|
||||||
|
xepd = StrConcat(2, xepd, cch); \
|
||||||
|
Free(tmp); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
switch (elem->type)
|
switch (elem->type)
|
||||||
{
|
{
|
||||||
case XML_ELEMENT_DATA:
|
case XML_ELEMENT_DATA:
|
||||||
|
|
@ -158,7 +185,7 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
|
|
@ -171,7 +198,7 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
|
|
@ -184,24 +211,45 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
}
|
}
|
||||||
Concat("`");
|
Concat("`");
|
||||||
}
|
}
|
||||||
|
else if (StrEquals(elem->name, "mx-reply"))
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
referenced = ASFind(ParseeConfigGet(), room_id, reply_id);
|
||||||
|
str = JsonValueAsString(
|
||||||
|
JsonGet(referenced, 2, "content", "body")
|
||||||
|
);
|
||||||
|
if (!str)
|
||||||
|
{
|
||||||
|
JsonFree(referenced);
|
||||||
|
return xepd;
|
||||||
|
}
|
||||||
|
Concat(">");
|
||||||
|
flags.quote = true;
|
||||||
|
Concat(str);
|
||||||
|
flags.quote = false;
|
||||||
|
Concat("\n");
|
||||||
|
JsonFree(referenced);
|
||||||
|
}
|
||||||
else if (StrEquals(elem->name, "blockquote"))
|
else if (StrEquals(elem->name, "blockquote"))
|
||||||
{
|
{
|
||||||
Concat(">");
|
Concat(">");
|
||||||
|
flags.quote = true;
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
}
|
}
|
||||||
|
flags.quote = false;
|
||||||
Concat("\n");
|
Concat("\n");
|
||||||
}
|
}
|
||||||
else if (StrEquals(elem->name, "br"))
|
else if (StrEquals(elem->name, "br"))
|
||||||
|
|
@ -211,11 +259,12 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
}
|
}
|
||||||
|
Concat("\n");
|
||||||
}
|
}
|
||||||
else if (StrEquals(elem->name, "a"))
|
else if (StrEquals(elem->name, "a"))
|
||||||
{
|
{
|
||||||
|
|
@ -224,7 +273,7 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
|
|
@ -238,7 +287,7 @@ XMPPifyElement(XMLElement *elem)
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
{
|
{
|
||||||
child = ArrayGet(elem->children, i);
|
child = ArrayGet(elem->children, i);
|
||||||
subxep = XMPPifyElement(child);
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
Concat(subxep);
|
Concat(subxep);
|
||||||
Free(subxep);
|
Free(subxep);
|
||||||
|
|
@ -254,6 +303,8 @@ ParseeXMPPify(HashMap *event)
|
||||||
char *cntr, *type, *format, *html;
|
char *cntr, *type, *format, *html;
|
||||||
char *xepd = NULL, *tmp;
|
char *xepd = NULL, *tmp;
|
||||||
XMLElement *elem;
|
XMLElement *elem;
|
||||||
|
|
||||||
|
XMPPFlags flags;
|
||||||
if (!event)
|
if (!event)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -276,9 +327,10 @@ ParseeXMPPify(HashMap *event)
|
||||||
|
|
||||||
html = JsonValueAsString(JsonGet(event, 2, "content", "formatted_body"));
|
html = JsonValueAsString(JsonGet(event, 2, "content", "formatted_body"));
|
||||||
html = StrConcat(3, "<html>", html, "</html>");
|
html = StrConcat(3, "<html>", html, "</html>");
|
||||||
elem = XMLDecode(StrStreamReader(html), true);
|
elem = XMLCDecode(StrStreamReader(html), true, true);
|
||||||
|
|
||||||
xepd = XMPPifyElement(elem);
|
flags.quote = false;
|
||||||
|
xepd = XMPPifyElement(event, elem, flags);
|
||||||
|
|
||||||
XMLFreeElement(elem);
|
XMLFreeElement(elem);
|
||||||
Free(html);
|
Free(html);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
XMLElement *
|
XMLElement *
|
||||||
XMLDecode(Stream *stream, bool autofree)
|
XMLCDecode(Stream *stream, bool autofree, bool html)
|
||||||
{
|
{
|
||||||
#define push(x) ArrayAdd(stack, x)
|
#define push(x) ArrayAdd(stack, x)
|
||||||
#define pop(x) ArrayDelete(stack, ArraySize(stack) - 1)
|
#define pop(x) ArrayDelete(stack, ArraySize(stack) - 1)
|
||||||
|
|
@ -45,7 +45,12 @@ XMLDecode(Stream *stream, bool autofree)
|
||||||
* going to be our top of the stack */
|
* going to be our top of the stack */
|
||||||
ret = top;
|
ret = top;
|
||||||
}
|
}
|
||||||
push(top);
|
|
||||||
|
/* HACK!!! */
|
||||||
|
if (!StrEquals(event->element, "br") || !html)
|
||||||
|
{
|
||||||
|
push(top);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XML_LEXER_ELEM:
|
case XML_LEXER_ELEM:
|
||||||
/* Create a new element that will populated. */
|
/* Create a new element that will populated. */
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ extern void ASPing(const ParseeConfig *);
|
||||||
* as. */
|
* as. */
|
||||||
extern void ASJoin(const ParseeConfig *, char *, char *);
|
extern void ASJoin(const ParseeConfig *, char *, char *);
|
||||||
|
|
||||||
|
/* Finds an event from a room ID and event ID */
|
||||||
|
extern HashMap * ASFind(const ParseeConfig *, char *, char *);
|
||||||
|
|
||||||
/* Sends a message event with a specific type and body.
|
/* Sends a message event with a specific type and body.
|
||||||
* Said body is freed during the function's execution. */
|
* Said body is freed during the function's execution. */
|
||||||
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@ typedef struct XMLElement {
|
||||||
} XMLElement;
|
} XMLElement;
|
||||||
|
|
||||||
/* Decodes 1 element off a stream. */
|
/* Decodes 1 element off a stream. */
|
||||||
extern XMLElement * XMLDecode(Stream *stream, bool autofree);
|
extern XMLElement * XMLCDecode(Stream *stream, bool autofree, bool html);
|
||||||
|
#define XMLDecode(stream, autofree) XMLCDecode(stream, autofree, false)
|
||||||
|
|
||||||
extern XMLElement * XMLCreateTag(char *name);
|
extern XMLElement * XMLCreateTag(char *name);
|
||||||
extern XMLElement * XMLCreateText(char *data);
|
extern XMLElement * XMLCreateText(char *data);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue