feeds.c (3041B)
#include "feeds.h"
#include <string.h>
#include <mrss.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <curl/curl.h>
#include "config.h"
#include "utils.h"
#include "http.h"
static void parse_feed(feed_t*, char*, char*);
static void populate_feed(feed_t*);
app_t
load_app(char* contents_feeds)
{
CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if (res) panic("Curl init error %d", res);
pthread_t t[MAX_FEEDS];
char* lines[MAX_FEEDS];
int feed_count = 0;
app_t app = {
.feeds_cap = FEEDS_CAP,
.feeds = ecalloc(FEEDS_CAP, sizeof(feed_t*)),
};
remove_all_chars(contents_feeds, '\r');
char* line = strtok(contents_feeds, "\n");
while (line != NULL) {
lines[feed_count] = strdup(line);
/* threads out --> */
pthread_create(&t[feed_count], NULL, threaded_fetch, lines[feed_count]);
/* threads out --> */
feed_count++;
if (feed_count > MAX_FEEDS) {
fprintf(stderr, "WARNING exeeded number of feeds %d\n", MAX_FEEDS);
break;
}
line = strtok(NULL, "\n");
}
for (int i = 0; i < feed_count; i++) {
void* ret;
/* <-- thread join */
pthread_join(t[i], &ret);
/* <-- thread join */
http_blob* httpblob = (http_blob*)ret;
feed_t* feed = (feed_t*)ecalloc(1, sizeof(feed_t));
if (!httpblob) continue;
parse_feed(feed, lines[i], httpblob->data);
populate_feed(feed);
free(lines[i]);
http_blob_free(ret);
if (app.feeds_cap == app.feeds_len) {
app.feeds_cap *= 2;
app.feeds = realloc(app.feeds, app.feeds_cap * sizeof(feed_t*));
}
app.feeds[app.feeds_len++] = feed;
}
free(line);
curl_global_cleanup();
return app;
}
static void
parse_feed(feed_t* feed, char* url, char* http_body)
{
mrss_t* rss = NULL;
*feed = (feed_t) { .url = url };
feed->title = (char*)ecalloc(FEED_CAP, sizeof(char));
/* process feed from given buffer */
mrss_error_t rc = mrss_parse_buffer(http_body, strlen(http_body), &rss);
if (rc != MRSS_OK || rss == NULL) {
snprintf(feed->title, FEED_CAP, "%s%s ", "(bad) ", url ? url : "(unknown feed url)");
return;
}
feed->website_url = strdup(rss->link);
snprintf(feed->title, FEED_CAP, "%s", rss->title ? rss->title : "(unknown feedtitle)");
for (mrss_item_t* it = rss->item; it; it = it->next) {
char* title = (it->title && *it->title) ? it->title : "";
char* link = (it->link && *it->link) ? it->link : "";
char* comments = (it->comments && *it->comments) ? it->comments : "";
char* desc = (it->description && *it->description) ? it->description : "";
char* date = (it->pubDate && *it->pubDate) ? it->pubDate : "";
remove_all_tags(desc);
db_post_t db_post = {
.title = title,
.link = link,
.comments = comments,
.pub_date = date,
.summary = desc,
.feed_url = url,
};
db_insert_post(db_post);
}
mrss_free(rss);
printf(".");
fflush(stdout);
}
static void
populate_feed(feed_t* feed)
{
const char* url = feed->url;
db_fetch_post_t dbposts = db_fetch_posts(url);
if (!dbposts.success) return;
feed->posts = dbposts.posts;
feed->posts_len = dbposts.count;
}