Keep track of posted links. - annna - Annna the nice friendly bot. | |
git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws6… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
--- | |
commit 484cc7bd51ceaaed82b650154cff6bb7e14a878d | |
parent 87850ff5e5fe1150688b7c725974d5383a3e496f | |
Author: Troels Henriksen <[email protected]> | |
Date: Mon, 7 Aug 2023 21:51:25 +0200 | |
Keep track of posted links. | |
Signed-off-by: Annna Robert-Houdin <[email protected]> | |
Diffstat: | |
M annna-message-common | 5 +++++ | |
A modules/linkbrother/linkbrother.c | 177 +++++++++++++++++++++++++++++… | |
A modules/linkbrother/linkbrother.sh | 12 ++++++++++++ | |
3 files changed, 194 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/annna-message-common b/annna-message-common | |
@@ -240,6 +240,11 @@ case "${text}" in | |
;; | |
esac | |
+critique=$($modbase/linkbrother/linkbrother.sh "$modbase/linkbrother/db" "$use… | |
+if [ "$critique" ]; then | |
+ annna-say -s "${server}" -c "${channel}" "$critique" | |
+fi | |
+ | |
case "${text}" in | |
"${ircuser}"?) | |
exclamation="$(printf "%s\n" "${text}" | sed "s,${ircuser}\(.\),\1,g")" | |
diff --git a/modules/linkbrother/linkbrother.c b/modules/linkbrother/linkbrothe… | |
@@ -0,0 +1,177 @@ | |
+// cc linkbrother.c -o linkbrother | |
+// | |
+// Use: ./linkbrother LINKSFILE USER MESSAGE | |
+ | |
+#define _GNU_SOURCE // sorry | |
+ | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#include <string.h> | |
+#include <ctype.h> | |
+#include <sys/types.h> | |
+#include <sys/stat.h> | |
+#include <sys/mman.h> | |
+#include <sys/time.h> | |
+#include <unistd.h> | |
+#include <fcntl.h> | |
+#include <time.h> | |
+#include <assert.h> | |
+ | |
+FILE* linksf; | |
+char* links; | |
+int linkslength; | |
+time_t now; | |
+int userlength; | |
+ | |
+void checklink(const char* user, const char* link) { | |
+ int l = strlen(link); | |
+ char* foundlink = (char*)memmem(links, linkslength, link, l); | |
+ if (foundlink != NULL) { | |
+ char* end = foundlink; | |
+ while (!isspace(*end) && *end != 0) { | |
+ end++; | |
+ } | |
+ end = 0; | |
+ if (*(foundlink + l) == ' ') { | |
+ char* nstart = foundlink + l + 1; | |
+ char* whostart = strstr(nstart + 1, " ") + 1; | |
+ char* whoend = strstr(whostart, "\n"); | |
+ time_t then = atoi(nstart); | |
+ *whoend = 0; | |
+ | |
+ time_t diff = now - then; | |
+ char* unit; | |
+ int unit_number; | |
+ | |
+ if (diff < 60) { | |
+ if (diff == 1) { | |
+ unit = "second"; | |
+ } else { | |
+ unit = "seconds"; | |
+ } | |
+ unit_number = diff; | |
+ } else if (diff < 60 * 60) { | |
+ unit_number = diff / 60; | |
+ if (unit_number == 1) { | |
+ unit = "minute"; | |
+ } else { | |
+ unit = "minutes"; | |
+ } | |
+ } else if (diff < 60 * 60 * 24) { | |
+ unit_number = diff / 60 / 60; | |
+ if (unit_number == 1) { | |
+ unit = "hour"; | |
+ } else { | |
+ unit = "hours"; | |
+ } | |
+ } else if (diff < 60 * 60 * 24 * 365) { | |
+ unit_number = diff / 60 / 60 / 24; | |
+ if (unit_number == 1) { | |
+ unit = "day"; | |
+ } else { | |
+ unit = "days"; | |
+ } | |
+ } else { | |
+ unit_number = diff / 60 / 60 / 24 / 365; | |
+ unit = "year"; | |
+ } | |
+ | |
+ if (strcmp(user, whostart) == 0) { | |
+ switch (rand()%3) { | |
+ case 0: | |
+ printf("%s: You first posted that link %d %s ago!\n", | |
+ user, unit_number, unit); | |
+ break; | |
+ case 1: | |
+ printf("%s: We heard you the first time (%d %s ago).\n", | |
+ user, unit_number, unit); | |
+ break; | |
+ case 2: | |
+ printf("%s: %d %s ago you posted something similar. How about somet… | |
+ user, unit_number, unit); | |
+ break; | |
+ } | |
+ } else { | |
+ switch (rand()%3) { | |
+ case 0: | |
+ printf("%s: %s already linked that %d %s ago.\n", | |
+ user, whostart, unit_number, unit); | |
+ break; | |
+ case 1: | |
+ printf("%s: Comrade! That link was first seen %d %s ago!\n", | |
+ user, unit_number, unit); | |
+ break; | |
+ case 2: | |
+ printf("%s: How nostalgic! Just like %s a whole %d %s ago!\n", | |
+ user, whostart, unit_number, unit); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ /* Always log */ | |
+ fprintf(linksf, "%s %ld %s\n", link, (long int)now, user); | |
+} | |
+ | |
+int main(int argc, char** argv) { | |
+ assert(argc == 4); | |
+ char* dbfile = argv[1]; | |
+ char* user = argv[2]; | |
+ char* message = argv[3]; | |
+ | |
+ now = time(NULL); | |
+ srand(now); | |
+ | |
+ if (message != NULL && user != NULL) { | |
+ struct stat fs; | |
+ | |
+ userlength = strlen(user); | |
+ linksf = fopen(dbfile, "a+"); | |
+ assert(linksf != NULL); | |
+ fstat(fileno(linksf), &fs); | |
+ linkslength = fs.st_size; | |
+ links = mmap(NULL, linkslength, PROT_WRITE | PROT_READ, MAP_PRIVATE, filen… | |
+ while (1) { | |
+ char* start, *end; | |
+ int atend; | |
+ | |
+ start = strstr(message, "http://"); | |
+ | |
+ if (start == NULL) { | |
+ start = strstr(message, "https://"); | |
+ } | |
+ | |
+ if (start == NULL) { | |
+ start = strstr(message, "gopher://"); | |
+ } | |
+ | |
+ if (start == NULL) { | |
+ start = strstr(message, "gophers://"); | |
+ } | |
+ | |
+ if (start == NULL) { | |
+ return 0; | |
+ } | |
+ | |
+ end = start; | |
+ | |
+ while (*end != ' ' && *end != 0) { | |
+ end++; | |
+ } | |
+ | |
+ atend = *end == 0; | |
+ *end = 0; | |
+ | |
+ checklink(user, start); | |
+ | |
+ if (atend) { | |
+ return 0; | |
+ } | |
+ | |
+ message = end+1; | |
+ } | |
+ return 0; | |
+ } else { | |
+ return 1; | |
+ } | |
+} | |
diff --git a/modules/linkbrother/linkbrother.sh b/modules/linkbrother/linkbroth… | |
@@ -0,0 +1,12 @@ | |
+#!/bin/sh | |
+# | |
+# State-of-the-art JIT compilation of linkbrother. | |
+ | |
+set -e | |
+ | |
+dir=$(dirname $0) | |
+if ! [ -x "$dir/linkbrother" -a "$dir/linkbrother" -nt "$dir/linkbrother.c" ];… | |
+ cc "$dir/linkbrother.c" -o "$dir/linkbrother" | |
+fi | |
+ | |
+"$dir/linkbrother" "$@" |