From b014f835b622d61fc6d24f67df0ce0d1770d5ac4 Mon Sep 17 00:00:00 2001 From: Will Brown Date: Wed, 20 Nov 2024 23:29:38 -0500 Subject: [PATCH] Send all new entries in a feed, not just the first --- Makefile | 2 +- README.md | 2 +- main.c | 47 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index f16dd14..33e1d46 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -Wall -Wextra -O2 +CFLAGS = -Wall -Wextra -std=gnu99 -O2 LDFLAGS = -lpthread -lcurl -lmrss SRC = $(wildcard *.c) diff --git a/README.md b/README.md index 1446a58..f4fcef5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A simple, lightweight Discord RSS bot ## TODO [ ] Add build instructions -[ ] Get all new feeds, not just the first one +[x] Get all new feeds, not just the first one [ ] Set permissions for add and remove command [ ] Import feeds from disk on startup [ ] Remove all feeds if bot is removed from a guild diff --git a/main.c b/main.c index c71a739..a952855 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,8 @@ +#define _GNU_SOURCE +#define _XOPEN_SOURCE + #include +#include #include #include #include @@ -38,7 +42,7 @@ struct bot_command { struct feed_info { char *title; char *url; - char *pubDate; + char *last_pubDate; u64snowflake guild_id; u64snowflake channel_id; unsigned timer_id; @@ -48,12 +52,24 @@ struct feed_info { void feed_info_free(struct feed_info *feed) { free(feed->title); free(feed->url); - free(feed->pubDate); + free(feed->last_pubDate); free(feed); } static const char *database_path = "feeds"; +// format string for for the time format of pubDate +#define PUBDATE_FMT "%a, %d %b %Y %T %z" + +// maybe change the function signature so you can actually do error handling with the result? +static time_t pubDate_to_time_t(char *s) { + struct tm tm; + char *res = strptime(s, PUBDATE_FMT, &tm); + if (!res || !*res) return 0; // invalid time + + return mktime(&tm); +} + // default interval for the feed retrieval timer #define TIMER_INTERVAL 600 @@ -61,16 +77,27 @@ static const char *database_path = "feeds"; static void timer_retrieve_feeds(struct discord *client, struct discord_timer *timer) { struct feed_info *feed = timer->data; - struct mrss_t *mrss_feed; + mrss_t *mrss_feed; if (mrss_parse_url(feed->url, &mrss_feed)) return; // do nothing on error - // get publication date and check if it is the same (change this later this is lazy and won't get all new feeds) - if (strcmp(mrss_feed->item->pubDate, feed->pubDate)) { + // get publication date of entries send any new ones + time_t last_pubDate_time = pubDate_to_time_t(feed->last_pubDate); + mrss_item_t *item = mrss_feed->item; + bool update_pubDate = false; + while (item && pubDate_to_time_t(item->pubDate) > last_pubDate_time) { + update_pubDate = true; + // Send new entry in the feed char msg[DISCORD_MAX_MESSAGE_LEN]; snprintf(msg, sizeof(msg), "## %s\n### %s\n%s", mrss_feed->title, mrss_feed->item->title, mrss_feed->item->link); struct discord_create_message res = { .content = msg }; - discord_create_message(client, feed->channel_id, &res, NULL); + discord_create_message(client, feed->channel_id, &res, NULL); + item = item->next; + } + + if (update_pubDate) { + free(feed->last_pubDate); + feed->last_pubDate = strdup(mrss_feed->item->pubDate); } mrss_free(mrss_feed); @@ -99,13 +126,13 @@ static void bot_command_add(struct discord *client, const struct discord_interac } feed->title = mrss_feed->title; - feed->pubDate = mrss_feed->item->pubDate; + feed->last_pubDate = mrss_feed->item->pubDate; feed->feed_id = rand(); char file_path[PATH_MAX]; - // check if we ran out of path - int path_len = snprintf(file_path, sizeof(file_path), "%s/%lu/%lu/%x", database_path, event->guild_id, event->channel_id, feed->feed_id); + // maybe check if we ran out of characters for path? + snprintf(file_path, sizeof(file_path), "%s/%lu/%lu/%x", database_path, event->guild_id, event->channel_id, feed->feed_id); FILE *fp = fopen(file_path, "w"); if (!fp) { @@ -114,7 +141,7 @@ static void bot_command_add(struct discord *client, const struct discord_interac feed_info_free(feed); goto send_msg; } - fprintf(fp, "title=%s\nurl=%s\npubDate=%s\n", feed->title, feed->url, feed->pubDate); + fprintf(fp, "title=%s\nurl=%s\nlast_pubDate=%s\n", feed->title, feed->url, feed->last_pubDate); fclose(fp); // spawn the timer for this feed