mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 17:05:11 +00:00
[MOD] Start separating Parsee functions more
This commit is contained in:
parent
4c158ea186
commit
1b62072a3a
12 changed files with 468 additions and 431 deletions
|
|
@ -4,7 +4,6 @@
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,9 @@
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <Routes.h>
|
#include <Routes.h>
|
||||||
#include <Glob.h>
|
|
||||||
#include <AS.h>
|
#include <AS.h>
|
||||||
|
|
||||||
ParseeData *
|
ParseeData *
|
||||||
|
|
@ -206,244 +204,7 @@ ParseeCleanup(void *datp)
|
||||||
DbListFree(chats);
|
DbListFree(chats);
|
||||||
Log(LOG_DEBUG, "Cleant up %d entries...", entries);
|
Log(LOG_DEBUG, "Cleant up %d entries...", entries);
|
||||||
}
|
}
|
||||||
int
|
|
||||||
ParseeFindDatastart(char *data)
|
|
||||||
{
|
|
||||||
char *startline;
|
|
||||||
bool found = false;
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
startline = data;
|
|
||||||
while (startline)
|
|
||||||
{
|
|
||||||
char *endline = strchr(startline, '\n');
|
|
||||||
|
|
||||||
if (*startline != '>')
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
startline = endline ? endline + 1 : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) (startline - data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <StringStream.h>
|
|
||||||
typedef struct XMPPFlags {
|
|
||||||
bool quote;
|
|
||||||
} XMPPFlags;
|
|
||||||
static char *
|
|
||||||
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) do \
|
|
||||||
{ \
|
|
||||||
size_t cidx; \
|
|
||||||
size_t len = strp ? strlen(strp) : 0; \
|
|
||||||
for (cidx = 0; cidx < len; 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:
|
|
||||||
Concat(elem->data);
|
|
||||||
break;
|
|
||||||
case XML_ELEMENT_TAG:
|
|
||||||
if (StrEquals(elem->name, "b") || StrEquals(elem->name, "strong"))
|
|
||||||
{
|
|
||||||
Concat("*");
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
subxep = XMPPifyElement(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
Concat("*");
|
|
||||||
}
|
|
||||||
else if (StrEquals(elem->name, "em"))
|
|
||||||
{
|
|
||||||
Concat("_");
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
subxep = XMPPifyElement(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
Concat("_");
|
|
||||||
}
|
|
||||||
else if (StrEquals(elem->name, "code"))
|
|
||||||
{
|
|
||||||
Concat("`");
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
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(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
flags.quote = false;
|
|
||||||
Concat("\n");
|
|
||||||
}
|
|
||||||
else if (StrEquals(elem->name, "br"))
|
|
||||||
{
|
|
||||||
Concat("\n");
|
|
||||||
/* HTML fucking SUCKS */
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
subxep = XMPPifyElement(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
Concat("\n");
|
|
||||||
}
|
|
||||||
else if (StrEquals(elem->name, "a"))
|
|
||||||
{
|
|
||||||
char *href = HashMapGet(elem->attrs, "href");
|
|
||||||
Concat("(");
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
subxep = XMPPifyElement(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
Concat(" points to ");
|
|
||||||
Concat(href);
|
|
||||||
Concat(" )");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < ArraySize(elem->children); i++)
|
|
||||||
{
|
|
||||||
child = ArrayGet(elem->children, i);
|
|
||||||
subxep = XMPPifyElement(event, child, flags);
|
|
||||||
|
|
||||||
Concat(subxep);
|
|
||||||
Free(subxep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return xepd;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ParseeXMPPify(HashMap *event)
|
|
||||||
{
|
|
||||||
char *type, *format, *html;
|
|
||||||
char *xepd = NULL;
|
|
||||||
XMLElement *elem;
|
|
||||||
|
|
||||||
XMPPFlags flags;
|
|
||||||
if (!event)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if it is a message event. */
|
|
||||||
type = JsonValueAsString(HashMapGet(event, "type"));
|
|
||||||
if (!StrEquals(type, "m.room.message"))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
format = JsonValueAsString(JsonGet(event, 2, "content", "format"));
|
|
||||||
if (!StrEquals(format, "org.matrix.custom.html"))
|
|
||||||
{
|
|
||||||
/* Settle for the raw body instead. */
|
|
||||||
char *body = JsonValueAsString(JsonGet(event, 2, "content", "body"));
|
|
||||||
return StrDuplicate(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
html = JsonValueAsString(JsonGet(event, 2, "content", "formatted_body"));
|
|
||||||
html = StrConcat(3, "<html>", html, "</html>");
|
|
||||||
elem = XMLCDecode(StrStreamReader(html), true, true);
|
|
||||||
|
|
||||||
flags.quote = false;
|
|
||||||
xepd = XMPPifyElement(event, elem, flags);
|
|
||||||
|
|
||||||
XMLFreeElement(elem);
|
|
||||||
Free(html);
|
|
||||||
|
|
||||||
return xepd;
|
|
||||||
}
|
|
||||||
void
|
void
|
||||||
ParseePushDMStanza(ParseeData *data, char *room_id, char *stanza_id, char *id, char *ev, char *sender)
|
ParseePushDMStanza(ParseeData *data, char *room_id, char *stanza_id, char *id, char *ev, char *sender)
|
||||||
{
|
{
|
||||||
|
|
@ -738,189 +499,3 @@ end:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
void
|
|
||||||
ParseeGlobalBan(ParseeData *data, char *glob, char *reason)
|
|
||||||
{
|
|
||||||
DbRef *ref;
|
|
||||||
HashMap *j, *obj;
|
|
||||||
if (!data || !glob)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref = DbLock(data->db, 1, "global_bans");
|
|
||||||
if (!ref)
|
|
||||||
{
|
|
||||||
ref = DbCreate(data->db, 1, "global_bans");
|
|
||||||
}
|
|
||||||
|
|
||||||
j = DbJson(ref);
|
|
||||||
|
|
||||||
obj = HashMapCreate();
|
|
||||||
if (reason)
|
|
||||||
{
|
|
||||||
HashMapSet(obj, "reason", JsonValueString(reason));
|
|
||||||
}
|
|
||||||
HashMapSet(obj, "date", JsonValueInteger(UtilTsMillis()));
|
|
||||||
JsonValueFree(HashMapSet(j, glob, JsonValueObject(obj)));
|
|
||||||
|
|
||||||
DbUnlock(data->db, ref);
|
|
||||||
}
|
|
||||||
bool
|
|
||||||
ParseeManageBan(ParseeData *data, char *user, char *room)
|
|
||||||
{
|
|
||||||
DbRef *ref;
|
|
||||||
HashMap *j;
|
|
||||||
char *key;
|
|
||||||
JsonValue *val;
|
|
||||||
bool banned = false , matches = false;
|
|
||||||
if (!data || !user)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref = DbLockIntent(data->db, DB_HINT_READONLY, 1, "global_bans");
|
|
||||||
j = DbJson(ref);
|
|
||||||
while (HashMapIterate(j, &key, (void **) &val))
|
|
||||||
{
|
|
||||||
HashMap *obj = JsonValueAsObject(val);
|
|
||||||
if (matches)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (GlobMatches(key, user))
|
|
||||||
{
|
|
||||||
banned = true;
|
|
||||||
matches = true;
|
|
||||||
if (room)
|
|
||||||
{
|
|
||||||
/* TODO: Use the object to set the reason */
|
|
||||||
ASBan(data->config, room, user);
|
|
||||||
(void) obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DbUnlock(data->db, ref);
|
|
||||||
|
|
||||||
return banned;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ParseeStringifyDate(uint64_t millis)
|
|
||||||
{
|
|
||||||
uint64_t rest = millis;
|
|
||||||
uint64_t hours, minutes, seconds;
|
|
||||||
char *hs, *ms, *ss, *out;
|
|
||||||
|
|
||||||
hours = rest / (1 HOURS);
|
|
||||||
rest = rest % (1 HOURS);
|
|
||||||
|
|
||||||
minutes = rest / (1 MINUTES);
|
|
||||||
rest = rest % (1 MINUTES);
|
|
||||||
|
|
||||||
seconds = rest / (1 SECONDS);
|
|
||||||
|
|
||||||
hs = StrInt(hours);
|
|
||||||
ms = StrInt(minutes);
|
|
||||||
ss = StrInt(seconds);
|
|
||||||
|
|
||||||
out = StrConcat(8,
|
|
||||||
hours ? hs : "",
|
|
||||||
hours ? " hours" : "",
|
|
||||||
(hours && minutes) ? ", " : "",
|
|
||||||
|
|
||||||
minutes ? ms : "",
|
|
||||||
minutes ? " minutes" : "",
|
|
||||||
(minutes && seconds) ? ", " : "",
|
|
||||||
|
|
||||||
seconds ? ss : "",
|
|
||||||
seconds ? " seconds" : ""
|
|
||||||
);
|
|
||||||
Free(hs);
|
|
||||||
Free(ms);
|
|
||||||
Free(ss);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ParseeAchievement(const char *func, const char *msg, bool die)
|
|
||||||
{
|
|
||||||
Log(LOG_ERR, "=========== Achievement GET! ===========");
|
|
||||||
Log(LOG_ERR, "%s: %s.", func, msg);
|
|
||||||
Log(LOG_ERR, "THIS IS, LET'S SAY, NOT GOOD, AND A SIGN OF ");
|
|
||||||
Log(LOG_ERR, "A PROGRAMMER ERROR. PLEASE KILLALL -9 PARSEE.");
|
|
||||||
Log(LOG_ERR, "");
|
|
||||||
Log(LOG_ERR, "YOU, HOWEVER, GET TO WIN AN AWARD FOR THIS.");
|
|
||||||
Log(LOG_ERR, "I AM SIMPLY JEALOUS OF YOU GETTING SUCH A ");
|
|
||||||
Log(LOG_ERR, "GOOD ERROR MESSAGE.");
|
|
||||||
Log(LOG_ERR, "=========== Achievement GET! ===========");
|
|
||||||
|
|
||||||
if (die)
|
|
||||||
{
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ParseeGenerateMTO(char *common_id)
|
|
||||||
{
|
|
||||||
char *matrix_to;
|
|
||||||
if (!common_id)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
common_id = HttpUrlEncode(common_id);
|
|
||||||
matrix_to = StrConcat(2, "https://matrix.to/#/", common_id);
|
|
||||||
Free(common_id);
|
|
||||||
|
|
||||||
return matrix_to;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ParseeGenerateHelp(const Argument *list)
|
|
||||||
{
|
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!list->end)
|
|
||||||
{
|
|
||||||
char *str = list->value_req ?
|
|
||||||
StrConcat(3, " [", list->value_descr, "]") :
|
|
||||||
StrDuplicate("");
|
|
||||||
Log(LOG_INFO, "-%c%s", list->argument, str);
|
|
||||||
LogConfigIndent(LogConfigGlobal());
|
|
||||||
Log(LOG_INFO, "%s", list->description);
|
|
||||||
LogConfigUnindent(LogConfigGlobal());
|
|
||||||
list++;
|
|
||||||
|
|
||||||
Free(str);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char *
|
|
||||||
ParseeGenerateGetopt(const Argument *list)
|
|
||||||
{
|
|
||||||
char *ret = NULL, *tmp = NULL;
|
|
||||||
if (!list)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!list->end)
|
|
||||||
{
|
|
||||||
char buffer[3] = {
|
|
||||||
list->argument, list->value_req ? ':' : '\0',
|
|
||||||
'\0'
|
|
||||||
};
|
|
||||||
|
|
||||||
tmp = ret;
|
|
||||||
ret = StrConcat(2, ret, buffer);
|
|
||||||
Free(tmp);
|
|
||||||
|
|
||||||
list++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <Cytoplasm/HashMap.h>
|
#include <Cytoplasm/HashMap.h>
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
static pthread_mutex_t nick_lock;
|
static pthread_mutex_t nick_lock;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
#include <Cytoplasm/Util.h>
|
#include <Cytoplasm/Util.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
||||||
26
src/Parsee/Utils/Achievement.c
Normal file
26
src/Parsee/Utils/Achievement.c
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseeAchievement(const char *func, const char *msg, bool die)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "=========== Achievement GET! ===========");
|
||||||
|
Log(LOG_ERR, "%s: %s.", func, msg);
|
||||||
|
Log(LOG_ERR, "THIS IS, LET'S SAY, NOT GOOD, AND A SIGN OF ");
|
||||||
|
Log(LOG_ERR, "A PROGRAMMER ERROR. PLEASE KILLALL -9 PARSEE.");
|
||||||
|
Log(LOG_ERR, "");
|
||||||
|
Log(LOG_ERR, "YOU, HOWEVER, GET TO WIN AN AWARD FOR THIS.");
|
||||||
|
Log(LOG_ERR, "I AM SIMPLY JEALOUS OF YOU GETTING SUCH A ");
|
||||||
|
Log(LOG_ERR, "GOOD ERROR MESSAGE.");
|
||||||
|
Log(LOG_ERR, "=========== Achievement GET! ===========");
|
||||||
|
|
||||||
|
if (die)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
53
src/Parsee/Utils/Arguments.c
Normal file
53
src/Parsee/Utils/Arguments.c
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseeGenerateHelp(const Argument *list)
|
||||||
|
{
|
||||||
|
if (!list)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!list->end)
|
||||||
|
{
|
||||||
|
char *str = list->value_req ?
|
||||||
|
StrConcat(3, " [", list->value_descr, "]") :
|
||||||
|
StrDuplicate("");
|
||||||
|
Log(LOG_INFO, "-%c%s", list->argument, str);
|
||||||
|
LogConfigIndent(LogConfigGlobal());
|
||||||
|
Log(LOG_INFO, "%s", list->description);
|
||||||
|
LogConfigUnindent(LogConfigGlobal());
|
||||||
|
list++;
|
||||||
|
|
||||||
|
Free(str);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ParseeGenerateGetopt(const Argument *list)
|
||||||
|
{
|
||||||
|
char *ret = NULL, *tmp = NULL;
|
||||||
|
if (!list)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!list->end)
|
||||||
|
{
|
||||||
|
char buffer[3] = {
|
||||||
|
list->argument, list->value_req ? ':' : '\0',
|
||||||
|
'\0'
|
||||||
|
};
|
||||||
|
|
||||||
|
tmp = ret;
|
||||||
|
ret = StrConcat(2, ret, buffer);
|
||||||
|
Free(tmp);
|
||||||
|
|
||||||
|
list++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
237
src/Parsee/Utils/Formatting.c
Normal file
237
src/Parsee/Utils/Formatting.c
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/HashMap.h>
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Http.h>
|
||||||
|
#include <Cytoplasm/Json.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <StringStream.h>
|
||||||
|
#include <XML.h>
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
typedef struct XMPPFlags {
|
||||||
|
bool quote;
|
||||||
|
} XMPPFlags;
|
||||||
|
static char *
|
||||||
|
XMPPifyElement(HashMap *event, XMLElement *elem, XMPPFlags flags)
|
||||||
|
{
|
||||||
|
char *xepd = NULL, *tmp = NULL;
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
XMLElement *child;
|
||||||
|
char *reply_id = GrabString(
|
||||||
|
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) do \
|
||||||
|
{ \
|
||||||
|
size_t cidx; \
|
||||||
|
size_t len = strp ? strlen(strp) : 0; \
|
||||||
|
for (cidx = 0; cidx < len; 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:
|
||||||
|
Concat(elem->data);
|
||||||
|
break;
|
||||||
|
case XML_ELEMENT_TAG:
|
||||||
|
if (StrEquals(elem->name, "b") || StrEquals(elem->name, "strong"))
|
||||||
|
{
|
||||||
|
Concat("*");
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
Concat("*");
|
||||||
|
}
|
||||||
|
else if (StrEquals(elem->name, "em"))
|
||||||
|
{
|
||||||
|
Concat("_");
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
Concat("_");
|
||||||
|
}
|
||||||
|
else if (StrEquals(elem->name, "code"))
|
||||||
|
{
|
||||||
|
Concat("`");
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
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(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
flags.quote = false;
|
||||||
|
Concat("\n");
|
||||||
|
}
|
||||||
|
else if (StrEquals(elem->name, "br"))
|
||||||
|
{
|
||||||
|
Concat("\n");
|
||||||
|
/* HTML fucking SUCKS */
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
Concat("\n");
|
||||||
|
}
|
||||||
|
else if (StrEquals(elem->name, "a"))
|
||||||
|
{
|
||||||
|
char *href = HashMapGet(elem->attrs, "href");
|
||||||
|
Concat("(");
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
Concat(" points to ");
|
||||||
|
Concat(href);
|
||||||
|
Concat(" )");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < ArraySize(elem->children); i++)
|
||||||
|
{
|
||||||
|
child = ArrayGet(elem->children, i);
|
||||||
|
subxep = XMPPifyElement(event, child, flags);
|
||||||
|
|
||||||
|
Concat(subxep);
|
||||||
|
Free(subxep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return xepd;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ParseeXMPPify(HashMap *event)
|
||||||
|
{
|
||||||
|
char *type, *format, *html;
|
||||||
|
char *xepd = NULL;
|
||||||
|
XMLElement *elem;
|
||||||
|
|
||||||
|
XMPPFlags flags;
|
||||||
|
if (!event)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if it is a message event. */
|
||||||
|
type = JsonValueAsString(HashMapGet(event, "type"));
|
||||||
|
if (!StrEquals(type, "m.room.message"))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
format = JsonValueAsString(JsonGet(event, 2, "content", "format"));
|
||||||
|
if (!StrEquals(format, "org.matrix.custom.html"))
|
||||||
|
{
|
||||||
|
/* Settle for the raw body instead. */
|
||||||
|
char *body = JsonValueAsString(JsonGet(event, 2, "content", "body"));
|
||||||
|
return StrDuplicate(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
html = JsonValueAsString(JsonGet(event, 2, "content", "formatted_body"));
|
||||||
|
html = StrConcat(3, "<html>", html, "</html>");
|
||||||
|
elem = XMLCDecode(StrStreamReader(html), true, true);
|
||||||
|
|
||||||
|
flags.quote = false;
|
||||||
|
xepd = XMPPifyElement(event, elem, flags);
|
||||||
|
|
||||||
|
XMLFreeElement(elem);
|
||||||
|
Free(html);
|
||||||
|
|
||||||
|
return xepd;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ParseeGenerateMTO(char *common_id)
|
||||||
|
{
|
||||||
|
char *matrix_to;
|
||||||
|
if (!common_id)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
common_id = HttpUrlEncode(common_id);
|
||||||
|
matrix_to = StrConcat(2, "https://matrix.to/#/", common_id);
|
||||||
|
Free(common_id);
|
||||||
|
|
||||||
|
return matrix_to;
|
||||||
|
}
|
||||||
75
src/Parsee/Utils/Nofly.c
Normal file
75
src/Parsee/Utils/Nofly.c
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Json.h>
|
||||||
|
#include <Cytoplasm/Util.h>
|
||||||
|
|
||||||
|
#include <Glob.h>
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseeGlobalBan(ParseeData *data, char *glob, char *reason)
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *j, *obj;
|
||||||
|
if (!data || !glob)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = DbLock(data->db, 1, "global_bans");
|
||||||
|
if (!ref)
|
||||||
|
{
|
||||||
|
ref = DbCreate(data->db, 1, "global_bans");
|
||||||
|
}
|
||||||
|
|
||||||
|
j = DbJson(ref);
|
||||||
|
|
||||||
|
obj = HashMapCreate();
|
||||||
|
if (reason)
|
||||||
|
{
|
||||||
|
HashMapSet(obj, "reason", JsonValueString(reason));
|
||||||
|
}
|
||||||
|
HashMapSet(obj, "date", JsonValueInteger(UtilTsMillis()));
|
||||||
|
JsonValueFree(HashMapSet(j, glob, JsonValueObject(obj)));
|
||||||
|
|
||||||
|
DbUnlock(data->db, ref);
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
ParseeManageBan(ParseeData *data, char *user, char *room)
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *j;
|
||||||
|
char *key;
|
||||||
|
JsonValue *val;
|
||||||
|
bool banned = false , matches = false;
|
||||||
|
if (!data || !user)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = DbLockIntent(data->db, DB_HINT_READONLY, 1, "global_bans");
|
||||||
|
j = DbJson(ref);
|
||||||
|
while (HashMapIterate(j, &key, (void **) &val))
|
||||||
|
{
|
||||||
|
HashMap *obj = JsonValueAsObject(val);
|
||||||
|
if (matches)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (GlobMatches(key, user))
|
||||||
|
{
|
||||||
|
banned = true;
|
||||||
|
matches = true;
|
||||||
|
if (room)
|
||||||
|
{
|
||||||
|
/* TODO: Use the object to set the reason */
|
||||||
|
ASBan(data->config, room, user);
|
||||||
|
(void) obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DbUnlock(data->db, ref);
|
||||||
|
|
||||||
|
return banned;
|
||||||
|
}
|
||||||
|
|
||||||
77
src/Parsee/Utils/String.c
Normal file
77
src/Parsee/Utils/String.c
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
ParseeFindDatastart(char *data)
|
||||||
|
{
|
||||||
|
char *startline;
|
||||||
|
bool found = false;
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
startline = data;
|
||||||
|
while (startline)
|
||||||
|
{
|
||||||
|
char *endline = strchr(startline, '\n');
|
||||||
|
|
||||||
|
if (*startline != '>')
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
startline = endline ? endline + 1 : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) (startline - data);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ParseeStringifyDate(uint64_t millis)
|
||||||
|
{
|
||||||
|
uint64_t rest = millis;
|
||||||
|
uint64_t hours, minutes, seconds;
|
||||||
|
char *hs, *ms, *ss, *out;
|
||||||
|
|
||||||
|
hours = rest / (1 HOURS);
|
||||||
|
rest = rest % (1 HOURS);
|
||||||
|
|
||||||
|
minutes = rest / (1 MINUTES);
|
||||||
|
rest = rest % (1 MINUTES);
|
||||||
|
|
||||||
|
seconds = rest / (1 SECONDS);
|
||||||
|
|
||||||
|
hs = StrInt(hours);
|
||||||
|
ms = StrInt(minutes);
|
||||||
|
ss = StrInt(seconds);
|
||||||
|
|
||||||
|
out = StrConcat(8,
|
||||||
|
hours ? hs : "",
|
||||||
|
hours ? " hours" : "",
|
||||||
|
(hours && minutes) ? ", " : "",
|
||||||
|
|
||||||
|
minutes ? ms : "",
|
||||||
|
minutes ? " minutes" : "",
|
||||||
|
(minutes && seconds) ? ", " : "",
|
||||||
|
|
||||||
|
seconds ? ss : "",
|
||||||
|
seconds ? " seconds" : ""
|
||||||
|
);
|
||||||
|
Free(hs);
|
||||||
|
Free(ms);
|
||||||
|
Free(ss);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
@ -77,7 +77,6 @@ XMPPInitialiseCompStream(char *host, int port)
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
static char *
|
static char *
|
||||||
ComputeHandshake(char *shared, char *stream)
|
ComputeHandshake(char *shared, char *stream)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
|
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
#include <Cytoplasm/Util.h>
|
#include <Cytoplasm/Util.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Sha.h>
|
|
||||||
|
|
||||||
#include <StringStream.h>
|
#include <StringStream.h>
|
||||||
#include <XMPPCommand.h>
|
#include <XMPPCommand.h>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue