From 0815820759292ff1e72697058ad7895193cae876 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sat, 7 Dec 2019 22:12:45 -0500 Subject: Add irc format --- unscoop.1 | 14 +++++-- unscoop.c | 132 +++++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 102 insertions(+), 44 deletions(-) diff --git a/unscoop.1 b/unscoop.1 index 9acba7c..32ca23b 100644 --- a/unscoop.1 +++ b/unscoop.1 @@ -1,4 +1,4 @@ -.Dd December 6, 2019 +.Dd December 7, 2019 .Dt UNSCOOP 1 .Os . @@ -52,9 +52,10 @@ The default path is as in .It Fl f Ar format Set the input log format. The following formats are supported: +.Sy catgirl , .Sy generic , -.Sy textual , -.Sy catgirl . +.Sy irc , +.Sy textual . The default format is .Sy generic . .Pp @@ -66,6 +67,13 @@ format matches the following: [timestamp] -nick- notice [timestamp] * nick action .Ed +.Pp +The +.Sy irc +format matches IRC protocol messages +tagged with the IRCv3.2 +.Sy server-time +extension. .El . .Sh SEE ALSO diff --git a/unscoop.c b/unscoop.c index 6d757a8..f2eddaf 100644 --- a/unscoop.c +++ b/unscoop.c @@ -39,106 +39,151 @@ struct Matcher { const char *params[ParamCap]; }; -#define WS "[[:blank:]]" -#define P1_TIME "[[]([^]]+)[]]" #define P0_MODE "[!~&@%+ ]?" +#define P1_TIME "^[[]([^]]+)[]][ \t]" -static const struct Matcher Generic[] = { +#define P2_MESSAGE "(, \"([^\"]+)\")?" +static const struct Matcher Catgirl[] = { { - "^" P1_TIME WS "<" P0_MODE "([^>]+)" ">" WS "(.+)", + P1_TIME "<([^>]+)> (.+)", Privmsg, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME WS "-" P0_MODE "([^-]+)" "-" WS "(.+)", + P1_TIME "-([^-]+)- (.+)", Notice, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME WS "[*]" WS P0_MODE "([^[:blank:]]+)" WS "(.+)", + P1_TIME "[*] ([^ ]+) (.+)", Action, { "$time", "$nick", "$message" }, }, + { + P1_TIME "([^ ]+) arrives", + Join, { "$time", "$nick" }, + }, + { + P1_TIME "([^ ]+) leaves [^,]+" P2_MESSAGE, + Part, { "$time", "$nick", NULL, "$message" }, + }, + { + P1_TIME "([^ ]+) kicks ([^ ]+) out of [^,]+" P2_MESSAGE, + Kick, { "$time", "$nick", "$target", NULL, "$message" }, + }, + { + P1_TIME "([^ ]+) leaves" P2_MESSAGE, + Quit, { "$time", "$nick", NULL, "$message" }, + }, + { + P1_TIME "([^ ]+) is now known as ([^ ]+)", + Nick, { "$time", "$nick", "$target" }, + }, + { + P1_TIME "([^ ]+) places a new sign in [^,]+" P2_MESSAGE, + Topic, { "$time", "$nick", "$message" }, + }, }; +#undef P2_MESSAGE -#define P2_USERHOST "[(]([^@]+)@([^)]+)[)]" -#define P2_MESSAGE "( [(]([^)]+)[)])?" -static const struct Matcher Textual[] = { +static const struct Matcher Generic[] = { { - "^" P1_TIME " <" P0_MODE "([^>]+)> (.+)", + P1_TIME "<" P0_MODE "([^>]+)>[ \t](.+)", Privmsg, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME " -" P0_MODE "([^-]+)- (.+)", + P1_TIME "-" P0_MODE "([^-]+)-[ \t](.+)", Notice, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME " • ([^:]+): (.+)", + P1_TIME "[*][ \t]" P0_MODE "([^ \t]+)[ \t](.+)", Action, { "$time", "$nick", "$message" }, }, +}; + +#define P2_TAGS "^@([^;]+;)*time=([^ ;]+)[^ ]* " +#define P3_ORIGIN ":([^!]+)!([^@]+)@([^ ]+) " +static const struct Matcher IRC[] = { + { + P2_TAGS P3_ORIGIN "PRIVMSG [^ ]+ :?\1ACTION ([^\1]+)", + Action, { NULL, "$time", "$nick", "$user", "$host", "$message" }, + }, { - "^" P1_TIME " ([^ ]+) " P2_USERHOST " joined the channel", - Join, { "$time", "$nick", "$user", "$host" }, + P2_TAGS P3_ORIGIN "PRIVMSG [^ ]+ :?(.+)", + Privmsg, { NULL, "$time", "$nick", "$user", "$host", "$message" }, }, { - "^" P1_TIME " ([^ ]+) " P2_USERHOST " left the channel" P2_MESSAGE, - Part, { "$time", "$nick", "$user", "$host", NULL, "$message" }, + P2_TAGS P3_ORIGIN "NOTICE [^ ]+ :?(.+)", + Notice, { NULL, "$time", "$nick", "$user", "$host", "$message" }, }, { - "^" P1_TIME " ([^ ]+) kicked ([^ ]+) from the channel" P2_MESSAGE, - Kick, { "$time", "$nick", "$target", NULL, "$message" }, + P2_TAGS P3_ORIGIN "JOIN [^ ]+", + Join, { NULL, "$time", "$nick", "$user", "$host" }, }, { - "^" P1_TIME " ([^ ]+) " P2_USERHOST " left IRC" P2_MESSAGE, - Quit, { "$time", "$nick", "$user", "$host", NULL, "$message" }, + P2_TAGS P3_ORIGIN "PART [^ ]+ :?(.+)?", + Part, { NULL, "$time", "$nick", "$user", "$host", "$message" }, }, { - "^" P1_TIME " ([^ ]+) is now known as ([^ ]+)", - Nick, { "$time", "$nick", "$target" }, + P2_TAGS P3_ORIGIN "KICK [^ ]+ ([^ ]+) :?(.+)?", + Kick, + { NULL, "$time", "$nick", "$user", "$host", "$target", "$message" }, }, { - "^" P1_TIME " ([^ ]+) changed the topic to (.+)", - Topic, { "$time", "$nick", "$message" }, + P2_TAGS P3_ORIGIN "QUIT( :?(.+))?", + Quit, { NULL, "$time", "$nick", "$user", "$host", NULL, "$message" }, + }, + { + P2_TAGS P3_ORIGIN "NICK :?([^ ]+)", + Nick, { NULL, "$time", "$nick", "$user", "$host", "$target" }, + }, + { + P2_TAGS P3_ORIGIN "TOPIC [^ ]+ :?(.+)", + Topic, { NULL, "$time", "$nick", "$user", "$host", "$message" }, }, }; +#undef P2_TAGS +#undef P3_ORIGIN -#undef P2_MESSAGE -#define P2_MESSAGE "(, \"([^\"]+)\")?" -static const struct Matcher Catgirl[] = { +#define P2_USERHOST "[(]([^@]+)@([^)]+)[)]" +#define P2_MESSAGE "( [(]([^)]+)[)])?" +static const struct Matcher Textual[] = { { - "^" P1_TIME " <([^>]+)> (.+)", + P1_TIME "<" P0_MODE "([^>]+)> (.+)", Privmsg, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME " -([^-]+)- (.+)", + P1_TIME "-" P0_MODE "([^-]+)- (.+)", Notice, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME " [*] ([^ ]+) (.+)", + P1_TIME "• ([^:]+): (.+)", Action, { "$time", "$nick", "$message" }, }, { - "^" P1_TIME " ([^ ]+) arrives", - Join, { "$time", "$nick" }, + P1_TIME "([^ ]+) " P2_USERHOST " joined the channel", + Join, { "$time", "$nick", "$user", "$host" }, }, { - "^" P1_TIME " ([^ ]+) leaves [^,]+" P2_MESSAGE, - Part, { "$time", "$nick", NULL, "$message" }, + P1_TIME "([^ ]+) " P2_USERHOST " left the channel" P2_MESSAGE, + Part, { "$time", "$nick", "$user", "$host", NULL, "$message" }, }, { - "^" P1_TIME " ([^ ]+) kicks ([^ ]+) out of [^,]+" P2_MESSAGE, + P1_TIME "([^ ]+) kicked ([^ ]+) from the channel" P2_MESSAGE, Kick, { "$time", "$nick", "$target", NULL, "$message" }, }, { - "^" P1_TIME " ([^ ]+) leaves" P2_MESSAGE, - Quit, { "$time", "$nick", NULL, "$message" }, + P1_TIME "([^ ]+) " P2_USERHOST " left IRC" P2_MESSAGE, + Quit, { "$time", "$nick", "$user", "$host", NULL, "$message" }, }, { - "^" P1_TIME " ([^ ]+) is now known as ([^ ]+)", + P1_TIME "([^ ]+) is now known as ([^ ]+)", Nick, { "$time", "$nick", "$target" }, }, { - "^" P1_TIME " ([^ ]+) places a new sign in [^,]+" P2_MESSAGE, + P1_TIME "([^ ]+) changed the topic to (.+)", Topic, { "$time", "$nick", "$message" }, }, }; +#undef P2_USERHOST +#undef P2_MESSAGE static const struct Format { const char *name; @@ -146,8 +191,10 @@ static const struct Format { size_t len; } Formats[] = { { "generic", Generic, ARRAY_LEN(Generic) }, - { "textual", Textual, ARRAY_LEN(Textual) }, + { "catgirl", Catgirl, ARRAY_LEN(Catgirl) }, + { "irc", IRC, ARRAY_LEN(IRC) }, + { "textual", Textual, ARRAY_LEN(Textual) }, }; static const struct Format *formatParse(const char *name) { @@ -182,7 +229,10 @@ static void prepareInsert(sqlite3 *db) { "INSERT INTO events (context, type, time, name, target, message)" "SELECT" " $context, $type," - " datetime(substr($time, 1, 22) || ':' || substr($time, -2))," + " CASE" + " WHEN $time LIKE '%Z' THEN datetime($time)" + " ELSE datetime(substr($time, 1, 22) || ':' || substr($time, -2))" + " END," " name, $target, $message" " FROM names" " WHERE nick = $nick" -- cgit 1.4.1