mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 21:15:11 +00:00
parent
1936be0078
commit
f94db460ac
5 changed files with 204 additions and 2 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Uri.h>
|
#include <Cytoplasm/Uri.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -267,6 +268,14 @@ ParseeXMPPify(HashMap *event)
|
||||||
|
|
||||||
html = StrConcat(3, "<html>", html, "</html>");
|
html = StrConcat(3, "<html>", html, "</html>");
|
||||||
elem = XMLCDecode(StrStreamReader(html), true, true);
|
elem = XMLCDecode(StrStreamReader(html), true, true);
|
||||||
|
if (!elem)
|
||||||
|
{
|
||||||
|
/* Settle for the raw body instead.
|
||||||
|
* TODO: Have the parser be more leinent on errors in HTML mode. */
|
||||||
|
char *body = GetRawBody(event);
|
||||||
|
Free(html);
|
||||||
|
return StrDuplicate(body);
|
||||||
|
}
|
||||||
|
|
||||||
flags.quote = false;
|
flags.quote = false;
|
||||||
xepd = XMPPifyElement(event, elem, flags);
|
xepd = XMPPifyElement(event, elem, flags);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,12 @@ XMLCDecode(Stream *stream, bool autofree, bool html)
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
|
case XML_ERROR:
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
XMLFreeElement(ret);
|
||||||
|
ArrayFree(stack);
|
||||||
|
XMLFreeLexer(lexer);
|
||||||
|
return NULL;
|
||||||
case XML_LEXER_STARTELEM:
|
case XML_LEXER_STARTELEM:
|
||||||
/* Create a new element that will populated. */
|
/* Create a new element that will populated. */
|
||||||
top = XMLCreateTag(event->element);
|
top = XMLCreateTag(event->element);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ static char * XMLPopElement(XMLexer *lexer);
|
||||||
static XMLEvent * XMLCreateEmptyElem(XMLexer *lexer, HashMap *attrs);
|
static XMLEvent * XMLCreateEmptyElem(XMLexer *lexer, HashMap *attrs);
|
||||||
static XMLEvent * XMLCreateStart(XMLexer *lexer, HashMap *attrs);
|
static XMLEvent * XMLCreateStart(XMLexer *lexer, HashMap *attrs);
|
||||||
static XMLEvent * XMLCreateRelax(XMLexer *lexer);
|
static XMLEvent * XMLCreateRelax(XMLexer *lexer);
|
||||||
|
static XMLEvent * XMLCreateError(XMLexer *lexer);
|
||||||
static XMLEvent * XMLCreateEnd(XMLexer *lexer, char *end);
|
static XMLEvent * XMLCreateEnd(XMLexer *lexer, char *end);
|
||||||
static XMLEvent * XMLCreateData(XMLexer *lexer);
|
static XMLEvent * XMLCreateData(XMLexer *lexer);
|
||||||
|
|
||||||
|
|
@ -198,7 +199,9 @@ XMLCrank(XMLexer *lexer)
|
||||||
else if (XMLookahead(lexer, "--", false))
|
else if (XMLookahead(lexer, "--", false))
|
||||||
{
|
{
|
||||||
/* Throw error */
|
/* Throw error */
|
||||||
return NULL;
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateError(lexer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XML_STATE_PI:
|
case XML_STATE_PI:
|
||||||
|
|
@ -215,6 +218,9 @@ XMLCrank(XMLexer *lexer)
|
||||||
if (!attrname)
|
if (!attrname)
|
||||||
{
|
{
|
||||||
/* TODO: Throw error */
|
/* TODO: Throw error */
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateError(lexer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
XMLPushElement(lexer, attrname);
|
XMLPushElement(lexer, attrname);
|
||||||
|
|
||||||
|
|
@ -241,7 +247,10 @@ XMLCrank(XMLexer *lexer)
|
||||||
}
|
}
|
||||||
else if (XMLookahead(lexer, "'", true))
|
else if (XMLookahead(lexer, "'", true))
|
||||||
{
|
{
|
||||||
while (true);
|
//while (true); uh oh
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateError(lexer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XML_STATE_ATTRTAIL:
|
case XML_STATE_ATTRTAIL:
|
||||||
|
|
@ -250,6 +259,8 @@ XMLCrank(XMLexer *lexer)
|
||||||
if (!XMLookahead(lexer, ">", true))
|
if (!XMLookahead(lexer, ">", true))
|
||||||
{
|
{
|
||||||
/* TODO: Throw error. */
|
/* TODO: Throw error. */
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateError(lexer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lexer->state = XML_STATE_NONE;
|
lexer->state = XML_STATE_NONE;
|
||||||
|
|
@ -258,6 +269,8 @@ XMLCrank(XMLexer *lexer)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateError(lexer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* TODO: Crank our XML parser. */
|
/* TODO: Crank our XML parser. */
|
||||||
|
|
@ -693,6 +706,26 @@ XMLCreateData(XMLexer *lexer)
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
static XMLEvent *
|
static XMLEvent *
|
||||||
|
XMLCreateError(XMLexer *lexer)
|
||||||
|
{
|
||||||
|
XMLEvent *event = Malloc(sizeof(*event));
|
||||||
|
size_t elements = ArraySize(lexer->data.elements);
|
||||||
|
|
||||||
|
event->type = XML_ERROR;
|
||||||
|
event->element = elements ?
|
||||||
|
StrDuplicate(ArrayGet(lexer->data.elements, elements - 1)) :
|
||||||
|
NULL;
|
||||||
|
event->attrs = NULL;
|
||||||
|
event->data = NULL;
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
event->line = 0;
|
||||||
|
event->col = 0;
|
||||||
|
event->offset = 0;
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
static XMLEvent *
|
||||||
XMLCreateRelax(XMLexer *lexer)
|
XMLCreateRelax(XMLexer *lexer)
|
||||||
{
|
{
|
||||||
XMLEvent *event = Malloc(sizeof(*event));
|
XMLEvent *event = Malloc(sizeof(*event));
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ typedef struct XMLEvent {
|
||||||
XML_LEXER_ELEM, /* Empty attr */
|
XML_LEXER_ELEM, /* Empty attr */
|
||||||
XML_LEXER_ENDELEM,
|
XML_LEXER_ENDELEM,
|
||||||
|
|
||||||
|
XML_ERROR,
|
||||||
|
|
||||||
XML_RELAX
|
XML_RELAX
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
|
|
|
||||||
152
tools/plumb.c
Normal file
152
tools/plumb.c
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* plumb.c - Small utility to manage plumbings from a shutoff instance.
|
||||||
|
* ============================================================
|
||||||
|
* TODO: write other commands, and move some code to common.h
|
||||||
|
*
|
||||||
|
* Under CC0, as its a rather useful example of a Parsee tool.
|
||||||
|
* See LICENSE for more information about Parsee's licensing. */
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
DeletePlumbID(Db *parsee, char *chat_id)
|
||||||
|
{
|
||||||
|
DbRef *chat_id_ref = DbLockIntent(parsee, DB_HINT_READONLY, 2, "chats", chat_id);
|
||||||
|
DbRef *chats = DbLock(parsee, 1, "chats");
|
||||||
|
char *matrix_id = GrabString(DbJson(chat_id_ref), 1, "room_id");
|
||||||
|
char *jabber_id = GrabString(DbJson(chat_id_ref), 1, "jabber_id");
|
||||||
|
|
||||||
|
HashMap *rooms = GrabObject(DbJson(chats), 1, "rooms");
|
||||||
|
HashMap *mucs = GrabObject(DbJson(chats), 1, "mucs");
|
||||||
|
|
||||||
|
JsonValueFree(HashMapDelete(rooms, matrix_id));
|
||||||
|
JsonValueFree(HashMapDelete(mucs, jabber_id));
|
||||||
|
|
||||||
|
DbUnlock(parsee, chat_id_ref);
|
||||||
|
DbUnlock(parsee, chats);
|
||||||
|
DbDelete(parsee, 2, "chats", chat_id);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
DeletePlumb(Db *parsee, char *potential_id)
|
||||||
|
{
|
||||||
|
if (!parsee || !potential_id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(potential_id, "xmpp:", 5))
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *mucs;
|
||||||
|
char *chat_id;
|
||||||
|
/* Try to parse it as an XMPP address */
|
||||||
|
potential_id += 5;
|
||||||
|
|
||||||
|
ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats");
|
||||||
|
mucs = GrabObject(DbJson(ref), 1, "mucs");
|
||||||
|
chat_id = StrDuplicate(GrabString(mucs, 1, potential_id));
|
||||||
|
DbUnlock(parsee, ref);
|
||||||
|
|
||||||
|
DeletePlumbID(parsee, chat_id);
|
||||||
|
Free(chat_id);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (*potential_id == '!')
|
||||||
|
{
|
||||||
|
/* Try to parse it as a Matrix room ID */
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *rooms;
|
||||||
|
char *chat_id;
|
||||||
|
|
||||||
|
ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats");
|
||||||
|
rooms = GrabObject(DbJson(ref), 1, "rooms");
|
||||||
|
chat_id = StrDuplicate(GrabString(rooms, 1, potential_id));
|
||||||
|
DbUnlock(parsee, ref);
|
||||||
|
|
||||||
|
DeletePlumbID(parsee, chat_id);
|
||||||
|
Free(chat_id);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to parse it as a chat ID */
|
||||||
|
DeletePlumbID(parsee, potential_id);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
ListPlumbs(Db *parsee)
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *mucs;
|
||||||
|
|
||||||
|
char *muc;
|
||||||
|
JsonValue *value;
|
||||||
|
if (!parsee)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats");
|
||||||
|
mucs = GrabObject(DbJson(ref), 1, "mucs");
|
||||||
|
while (HashMapIterate(mucs, &muc, (void **) &value))
|
||||||
|
{
|
||||||
|
char *chat_id = JsonValueAsString(value);
|
||||||
|
DbRef *chat_id_ref = DbLockIntent(parsee, DB_HINT_READONLY, 2, "chats", chat_id);
|
||||||
|
char *matrix_id = GrabString(DbJson(chat_id_ref), 1, "room_id");
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
Log(LOG_INFO, "- Plumb xmpp:%s <=> %s", muc, matrix_id);
|
||||||
|
Log(LOG_INFO, " - ID=%s", chat_id);
|
||||||
|
|
||||||
|
DbUnlock(parsee, chat_id_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
DbUnlock(parsee, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Main(Array *args, HashMap *env)
|
||||||
|
{
|
||||||
|
char *db_path, *action, *exec;
|
||||||
|
int ret = EXIT_SUCCESS;
|
||||||
|
Db *parsee;
|
||||||
|
|
||||||
|
exec = ArrayGet(args, 0);
|
||||||
|
|
||||||
|
if (ArraySize(args) < 3)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "Usage: %s [config] [action] <args>", exec);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
db_path = ArrayGet(args, 1);
|
||||||
|
action = ArrayGet(args, 2);
|
||||||
|
|
||||||
|
parsee = GetDB(db_path);
|
||||||
|
if (!parsee)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "%s: couldn't open config '%s' or couldnt edit DB", exec, db_path);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEquals(action, "list") || StrEquals(action, "ls"))
|
||||||
|
{
|
||||||
|
ListPlumbs(parsee);
|
||||||
|
}
|
||||||
|
else if (StrEquals(action, "del"))
|
||||||
|
{
|
||||||
|
if (ArraySize(args) != 4)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "%s: please show a !roomid:matrix.org, xmpp:mucid@jabber.org, or local hash", exec);
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
DeletePlumb(parsee, ArrayGet(args, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
end:
|
||||||
|
DbClose(parsee);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue