Keep track of posted links. - annna - Annna the nice friendly bot.
HTML git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
---
DIR commit 484cc7bd51ceaaed82b650154cff6bb7e14a878d
DIR parent 87850ff5e5fe1150688b7c725974d5383a3e496f
HTML Author: Troels Henriksen <athas@sigkill.dk>
Date: Mon, 7 Aug 2023 21:51:25 +0200
Keep track of posted links.
Signed-off-by: Annna Robert-Houdin <annna@bitreich.org>
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(-)
---
DIR 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" "$user" "$text")
+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")"
DIR diff --git a/modules/linkbrother/linkbrother.c b/modules/linkbrother/linkbrother.c
@@ -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 something new?\n",
+ 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, fileno(linksf), 0);
+ 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;
+ }
+}
DIR diff --git a/modules/linkbrother/linkbrother.sh b/modules/linkbrother/linkbrother.sh
@@ -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" ]; then
+ cc "$dir/linkbrother.c" -o "$dir/linkbrother"
+fi
+
+"$dir/linkbrother" "$@"