[ADD/MOD] XMPP->Matrix media bridge, small cleanup

This commit is contained in:
LDA 2024-06-23 15:34:51 +02:00
commit 42d69226f0
14 changed files with 327 additions and 54 deletions

View file

@ -33,6 +33,95 @@ ParseeDMHandler(char *room, char *from, XMLElement *data, const ParseeConfig *c)
);
}
static bool
MessageStanza(ParseeData *args, XMLElement *stanza)
{
XMPPComponent *jabber = args->jabber;
XMLElement *body = NULL;
XMLElement *data = NULL;
XMLElement *stanza_id = NULL;
char *to, *room, *from, *from_matrix;
char *chat_id, *mroom_id;
size_t i;
body = XMLookForUnique(stanza, "body");
if (!body)
{
XMLFreeElement(stanza);
return false;
}
stanza_id = XMLookForUnique(stanza, "stanza-id");
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
from = HashMapGet(stanza->attrs, "from");
from_matrix = ParseeEncodeJID(args->config, from, true);
room = ParseeFindDMRoom(args, to, from);
data = ArrayGet(body->children, 0);
/* TODO: Consider having rich messages. */
chat_id = ParseeGetFromMUCID(args, from);
mroom_id = ParseeGetRoomID(args, chat_id);
if (room)
{
ParseeDMHandler(room, from_matrix, data, args->config);
}
if (mroom_id && !XMPPIsParseeStanza(stanza))
{
char *res = ParseeGetResource(from);
char *encoded = ParseeEncodeJID(args->config, from, false);
char *s_id_str = HashMapGet(stanza_id->attrs, "id");
/* TODO: Create smarter puppet names */
if (ParseeVerifyStanza(args, chat_id, s_id_str))
{
XMLElement *oob, *oob_data;
ASRegisterUser(args->config, encoded);
ASSetName(args->config, encoded, res);
ASJoin(args->config, mroom_id, encoded);
/* Check if it is a media link */
oob = XMLookForTKV(stanza, "x", "xmlns", "jabber:x:oob");
if (oob)
{
char *mxc, *mime = NULL;
HashMap *content = NULL;
oob_data = XMLookForUnique(oob, "url");
oob_data = ArrayGet(oob_data->children, 0);
mxc = ASReupload(args->config, oob_data->data, &mime);
content = MatrixCreateMedia(mxc, data->data, mime);
ASSend(
args->config, mroom_id, encoded,
"m.room.message", content
);
Free(mime);
Free(mxc);
}
else
{
ASSend(
args->config, mroom_id, encoded,
"m.room.message", MatrixCreateMessage(data->data)
);
}
ParseePushStanza(args, chat_id, s_id_str);
}
Free(res);
Free(encoded);
}
Free(chat_id);
Free(mroom_id);
Free(from_matrix);
Free(room);
Free(to);
return true;
}
void *
ParseeXMPPThread(void *argp)
{
@ -41,9 +130,6 @@ ParseeXMPPThread(void *argp)
XMLElement *stanza = NULL;
while (true)
{
XMLElement *body = NULL;
XMLElement *data = NULL;
XMLElement *stanza_id = NULL;
char *to, *room, *from, *from_matrix;
char *chat_id, *mroom_id;
@ -55,6 +141,7 @@ ParseeXMPPThread(void *argp)
if (StrEquals(stanza->name, "presence"))
{
/* TODO: Manage presence */
XMLFreeElement(stanza);
continue;
}
@ -80,56 +167,18 @@ ParseeXMPPThread(void *argp)
continue;
}
}
body = XMLookForUnique(stanza, "body");
if (!body)
if (!MessageStanza(args, stanza))
{
XMLFreeElement(stanza);
continue;
}
stanza_id = XMLookForUnique(stanza, "stanza-id");
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
from = HashMapGet(stanza->attrs, "from");
from_matrix = ParseeEncodeJID(args->config, from, true);
room = ParseeFindDMRoom(args, to, from);
data = ArrayGet(body->children, 0);
/* TODO: Consider having rich messages, and move that out
* to separate functions */
chat_id = ParseeGetFromMUCID(args, from);
mroom_id = ParseeGetRoomID(args, chat_id);
if (room)
{
ParseeDMHandler(room, from_matrix, data, args->config);
}
if (mroom_id && !XMPPIsParseeStanza(stanza))
{
char *res = ParseeGetResource(from);
char *encoded = ParseeEncodeJID(args->config, from, false);
char *s_id_str = HashMapGet(stanza_id->attrs, "id");
/* TODO: Create smarter puppet names, and send presence
* in every room at Parsee's bootup. */
if (ParseeVerifyStanza(args, chat_id, s_id_str))
{
ASRegisterUser(args->config, encoded);
ASSetName(args->config, encoded, res);
ASJoin(args->config, mroom_id, encoded);
ASSend(
args->config, mroom_id, encoded,
"m.room.message", MatrixCreateMessage(data->data)
);
ParseePushStanza(args, chat_id, s_id_str);
}
Free(res);
Free(encoded);
}
Free(chat_id);
Free(mroom_id);
Free(from_matrix);
Free(room);
Free(to);
}
else if (StrEquals(stanza->name, "iq"))
{
/* TODO: Ought to manage info/query requests */
Log(LOG_WARNING, "Unimplemented 'iq' stanza.");
Log(LOG_WARNING, "Odds are, this is the programmer's fault");
Log(LOG_WARNING, "and this needs to be implemented later on.");
}
else
{