summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--litterbox.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/litterbox.c b/litterbox.c
index 338a003..b28398b 100644
--- a/litterbox.c
+++ b/litterbox.c
@@ -55,6 +55,7 @@ enum {
 	InsertJoin,
 	DeleteJoin,
 	UpdateJoin,
+	InsertEvents,
 };
 static const char *Statements[] = {
 	[InsertContext] = SQL(
@@ -80,6 +81,20 @@ static const char *Statements[] = {
 			AND names.host = :host;
 	),
 
+	[InsertEvents] = SQL(
+		INSERT INTO events (time, type, context, name, target, message)
+		SELECT
+			coalesce(datetime(:time), datetime('now')),
+			:type, context, names.name, :target, :message
+		FROM joins, contexts, names
+		WHERE joins.nick = :nick
+			AND contexts.name = joins.channel
+			AND contexts.network = :network
+			AND names.nick = :nick
+			AND names.user = :user
+			AND names.host = :host;
+	),
+
 	[InsertJoin] = SQL(
 		INSERT INTO joins (nick, channel) VALUES (:nick, :channel);
 	),
@@ -103,6 +118,7 @@ static void prepare(void) {
 static void bindNetwork(const char *network) {
 	dbBindTextCopy(stmts[InsertContext], ":network", network);
 	dbBindTextCopy(stmts[InsertEvent], ":network", network);
+	dbBindTextCopy(stmts[InsertEvents], ":network", network);
 }
 
 static void insertContext(const char *context, bool query) {
@@ -122,6 +138,9 @@ static void insertName(const char *nick, const char *user, const char *host) {
 	dbBindText(stmts[InsertEvent], ":nick", nick);
 	dbBindText(stmts[InsertEvent], ":user", user);
 	dbBindText(stmts[InsertEvent], ":host", host);
+	dbBindText(stmts[InsertEvents], ":nick", nick);
+	dbBindText(stmts[InsertEvents], ":user", user);
+	dbBindText(stmts[InsertEvents], ":host", host);
 	if (sqlite3_changes(db)) printSQL(stmts[InsertName]);
 	sqlite3_reset(stmts[InsertName]);
 }
@@ -138,6 +157,18 @@ static void insertEvent(
 	sqlite3_reset(stmts[InsertEvent]);
 }
 
+static void insertEvents(
+	const char *time, enum Type type, const char *target, const char *message
+) {
+	dbBindText(stmts[InsertEvents], ":time", time);
+	dbBindInt(stmts[InsertEvents], ":type", type);
+	dbBindText(stmts[InsertEvents], ":target", target);
+	dbBindText(stmts[InsertEvents], ":message", message);
+	dbStep(stmts[InsertEvents]);
+	printSQL(stmts[InsertEvents]);
+	sqlite3_reset(stmts[InsertEvents]);
+}
+
 static void insertJoin(const char *nick, const char *channel) {
 	dbBindText(stmts[InsertJoin], ":nick", nick);
 	dbBindText(stmts[InsertJoin], ":channel", channel);
@@ -154,6 +185,14 @@ static void deleteJoin(const char *nick, const char *channel) {
 	sqlite3_reset(stmts[DeleteJoin]);
 }
 
+static void updateJoin(const char *old, const char *new) {
+	dbBindText(stmts[UpdateJoin], ":old", old);
+	dbBindText(stmts[UpdateJoin], ":new", new);
+	dbStep(stmts[UpdateJoin]);
+	printSQL(stmts[UpdateJoin]);
+	sqlite3_reset(stmts[UpdateJoin]);
+}
+
 static struct tls *client;
 
 static void clientWrite(const char *ptr, size_t len) {
@@ -295,30 +334,38 @@ static void handlePrivmsg(struct Message *msg) {
 
 static void handleJoin(struct Message *msg) {
 	require(msg, 1);
-	insertJoin(msg->nick, msg->params[0]);
 	insertContext(msg->params[0], false);
 	insertName(msg->nick, msg->user, msg->host);
 	insertEvent(msg->time, Join, NULL, NULL);
+	insertJoin(msg->nick, msg->params[0]);
 }
 
 static void handlePart(struct Message *msg) {
 	require(msg, 1);
-	deleteJoin(msg->nick, msg->params[0]);
 	insertContext(msg->params[0], false);
 	insertName(msg->nick, msg->user, msg->host);
 	insertEvent(msg->time, Part, NULL, msg->params[1]);
+	deleteJoin(msg->nick, msg->params[0]);
 	// TODO: Clear joins if self.
 }
 
 static void handleKick(struct Message *msg) {
 	require(msg, 2);
-	deleteJoin(msg->params[1], msg->params[0]);
 	insertContext(msg->params[0], false);
 	insertName(msg->nick, msg->user, msg->host);
 	insertEvent(msg->time, Kick, msg->params[1], msg->params[2]);
+	deleteJoin(msg->params[1], msg->params[0]);
 	// TODO: Clear joins if self.
 }
 
+static void handleNick(struct Message *msg) {
+	require(msg, 1);
+	if (!strcmp(msg->nick, self)) set(&self, msg->params[0]);
+	insertName(msg->nick, msg->user, msg->host);
+	insertEvents(msg->time, Nick, msg->params[0], NULL);
+	updateJoin(msg->nick, msg->params[0]);
+}
+
 static void handlePing(struct Message *msg) {
 	require(msg, 1);
 	format("PONG :%s\r\n", msg->params[0]);
@@ -333,11 +380,12 @@ static const struct {
 	{ "005", false, handleReplyISupport },
 	{ "CAP", false, handleCap },
 	{ "JOIN", true, handleJoin },
+	{ "KICK", true, handleKick },
+	{ "NICK", true, handleNick },
 	{ "NOTICE", true, handlePrivmsg },
 	{ "PART", true, handlePart },
 	{ "PING", false, handlePing },
 	{ "PRIVMSG", true, handlePrivmsg },
-	{ "KICK", true, handleKick },
 };
 
 static void handle(struct Message msg) {
21:13:12 +0000'>2021-09-22Call sandbox in CGI modeJune McEnroe Otherwise upload won't actually work. 2021-09-22Support HTTP PUT in upJune McEnroe For use by Palaver[1]. Unfortunately, at least in the current App Store version of Palaver, this doesn't work correctly with basic auth. [1]: https://palaverapp.com/guides/commands/set.html#ui-image_service 2021-09-22Remove default faviconJune McEnroe I hate these things and also this one sucks. 2021-09-21Use Z_FILTERED strategyJune McEnroe 2021-09-21Recalculate various lengths only as neededJune McEnroe This actually speeds things up quite a bit, saving roughly a second on a big PNG screenshot. Almost all the remaining time is spent in deflate. 2021-09-21Rewrite pngo, add explicit optionsJune McEnroe Interesting to see how my code habits have changed. 2021-09-16Fix /* **/ comment matchingJune McEnroe 2021-09-15Remove typer, add downgrade to READMEJune McEnroe 2021-09-15Set bot mode on downgradeJune McEnroe 2021-09-15Enter capsicum in downgradeJune McEnroe 2021-09-15Factor out common parts of downgrade messagesJune McEnroe Also bump the message cap to 1024 because that is ostensibly useful for replying to older messages. 2021-09-14Add downgrade IRC botJune McEnroe 2021-09-14Sort by title if authors matchJune McEnroe There are probably better things to sort by but title definitely always exists. 2021-09-13Swap-remove tags as they're foundJune McEnroe This makes it even faster. From ~1s on a sqlite3.c amalgamation to ~0.85s. 2021-09-12Replace htagml regex with strncmpJune McEnroe Since ctags only ever produces regular expressions of the form /^re$/ or /^re/ with no other special characters, instead unescape the pattern and simply use strncmp. Running on a sqlite3.c amalgamation, the regex version takes ~37s while the strncmp version takes ~1s, producing identical output. Big win! 2021-09-11Also defer printing comment for lone close-parensJune McEnroe 2021-09-10Publish "git-comment"June McEnroe 2021-09-10Add git comment --pretty optionJune McEnroe 2021-09-08Defer printing comment if line is blank or closing braceJune McEnroe This fixes badly indented comments. 2021-09-08Up default min-repeat to 30 linesJune McEnroe 2021-09-08Handle dirty lines in git-commentJune McEnroe 2021-09-08Document and install git-commentJune McEnroe 2021-09-08Add repeat and all options to git-commentJune McEnroe 2021-09-08Add group threshold to git-commentJune McEnroe