mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 12:15:12 +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);
|
||||
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 *
|
||||
ASGetName(const ParseeConfig *c, char *room, char *user)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <Routes.h>
|
||||
#include <AS.h>
|
||||
|
||||
ParseeData *
|
||||
ParseeInitData(XMPPComponent *comp)
|
||||
|
|
@ -82,7 +83,7 @@ ParseeCleanup(void *datp)
|
|||
uint64_t age = JsonValueAsInteger(HashMapGet(obj, "age"));
|
||||
uint64_t dur = ts - age;
|
||||
|
||||
if ((dur > (5 MINUTES)))
|
||||
if ((dur > (30 MINUTES)))
|
||||
{
|
||||
ArrayAdd(to_delete, StrDuplicate(stanza));
|
||||
}
|
||||
|
|
@ -134,18 +135,44 @@ ParseeFindDatastart(char *data)
|
|||
}
|
||||
|
||||
#include <StringStream.h>
|
||||
|
||||
typedef struct XMPPFlags {
|
||||
bool quote;
|
||||
} XMPPFlags;
|
||||
static char *
|
||||
XMPPifyElement(XMLElement *elem)
|
||||
XMPPifyElement(HashMap *event, XMLElement *elem, XMPPFlags flags)
|
||||
{
|
||||
char *xepd = NULL, *tmp = NULL;
|
||||
|
||||
size_t i;
|
||||
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;
|
||||
#define Concat(strp) tmp = xepd; \
|
||||
xepd = StrConcat(2, xepd, strp); \
|
||||
Free(tmp)
|
||||
#define Concat(strp) do \
|
||||
{ \
|
||||
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)
|
||||
{
|
||||
case XML_ELEMENT_DATA:
|
||||
|
|
@ -158,7 +185,7 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
|
|
@ -171,7 +198,7 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
|
|
@ -184,24 +211,45 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
}
|
||||
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"))
|
||||
{
|
||||
Concat(">");
|
||||
flags.quote = true;
|
||||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
}
|
||||
flags.quote = false;
|
||||
Concat("\n");
|
||||
}
|
||||
else if (StrEquals(elem->name, "br"))
|
||||
|
|
@ -211,11 +259,12 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
}
|
||||
Concat("\n");
|
||||
}
|
||||
else if (StrEquals(elem->name, "a"))
|
||||
{
|
||||
|
|
@ -224,7 +273,7 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
|
|
@ -238,7 +287,7 @@ XMPPifyElement(XMLElement *elem)
|
|||
for (i = 0; i < ArraySize(elem->children); i++)
|
||||
{
|
||||
child = ArrayGet(elem->children, i);
|
||||
subxep = XMPPifyElement(child);
|
||||
subxep = XMPPifyElement(event, child, flags);
|
||||
|
||||
Concat(subxep);
|
||||
Free(subxep);
|
||||
|
|
@ -254,6 +303,8 @@ ParseeXMPPify(HashMap *event)
|
|||
char *cntr, *type, *format, *html;
|
||||
char *xepd = NULL, *tmp;
|
||||
XMLElement *elem;
|
||||
|
||||
XMPPFlags flags;
|
||||
if (!event)
|
||||
{
|
||||
return NULL;
|
||||
|
|
@ -276,9 +327,10 @@ ParseeXMPPify(HashMap *event)
|
|||
|
||||
html = JsonValueAsString(JsonGet(event, 2, "content", "formatted_body"));
|
||||
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);
|
||||
Free(html);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <string.h>
|
||||
|
||||
XMLElement *
|
||||
XMLDecode(Stream *stream, bool autofree)
|
||||
XMLCDecode(Stream *stream, bool autofree, bool html)
|
||||
{
|
||||
#define push(x) ArrayAdd(stack, x)
|
||||
#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 */
|
||||
ret = top;
|
||||
}
|
||||
push(top);
|
||||
|
||||
/* HACK!!! */
|
||||
if (!StrEquals(event->element, "br") || !html)
|
||||
{
|
||||
push(top);
|
||||
}
|
||||
break;
|
||||
case XML_LEXER_ELEM:
|
||||
/* Create a new element that will populated. */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ extern void ASPing(const ParseeConfig *);
|
|||
* as. */
|
||||
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.
|
||||
* Said body is freed during the function's execution. */
|
||||
extern char * ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ typedef struct XMLElement {
|
|||
} XMLElement;
|
||||
|
||||
/* 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 * XMLCreateText(char *data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue