feeds.c (3041B)
1 #include "feeds.h" 2 3 #include <string.h> 4 #include <mrss.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <pthread.h> 8 #include <curl/curl.h> 9 10 #include "config.h" 11 #include "utils.h" 12 #include "http.h" 13 14 static void parse_feed(feed_t*, char*, char*); 15 static void populate_feed(feed_t*); 16 17 app_t 18 load_app(char* contents_feeds) 19 { 20 CURLcode res = curl_global_init(CURL_GLOBAL_ALL); 21 if (res) panic("Curl init error %d", res); 22 pthread_t t[MAX_FEEDS]; 23 char* lines[MAX_FEEDS]; 24 int feed_count = 0; 25 26 app_t app = { 27 .feeds_cap = FEEDS_CAP, 28 .feeds = ecalloc(FEEDS_CAP, sizeof(feed_t*)), 29 }; 30 31 remove_all_chars(contents_feeds, '\r'); 32 char* line = strtok(contents_feeds, "\n"); 33 34 while (line != NULL) { 35 lines[feed_count] = strdup(line); 36 37 /* threads out --> */ 38 pthread_create(&t[feed_count], NULL, threaded_fetch, lines[feed_count]); 39 /* threads out --> */ 40 41 feed_count++; 42 if (feed_count > MAX_FEEDS) { 43 fprintf(stderr, "WARNING exeeded number of feeds %d\n", MAX_FEEDS); 44 break; 45 } 46 line = strtok(NULL, "\n"); 47 } 48 49 for (int i = 0; i < feed_count; i++) { 50 void* ret; 51 52 /* <-- thread join */ 53 pthread_join(t[i], &ret); 54 /* <-- thread join */ 55 56 http_blob* httpblob = (http_blob*)ret; 57 feed_t* feed = (feed_t*)ecalloc(1, sizeof(feed_t)); 58 if (!httpblob) continue; 59 parse_feed(feed, lines[i], httpblob->data); 60 populate_feed(feed); 61 free(lines[i]); 62 http_blob_free(ret); 63 64 if (app.feeds_cap == app.feeds_len) { 65 app.feeds_cap *= 2; 66 app.feeds = realloc(app.feeds, app.feeds_cap * sizeof(feed_t*)); 67 } 68 app.feeds[app.feeds_len++] = feed; 69 } 70 71 free(line); 72 curl_global_cleanup(); 73 return app; 74 } 75 76 static void 77 parse_feed(feed_t* feed, char* url, char* http_body) 78 { 79 mrss_t* rss = NULL; 80 81 *feed = (feed_t) { .url = url }; 82 feed->title = (char*)ecalloc(FEED_CAP, sizeof(char)); 83 84 /* process feed from given buffer */ 85 mrss_error_t rc = mrss_parse_buffer(http_body, strlen(http_body), &rss); 86 87 if (rc != MRSS_OK || rss == NULL) { 88 snprintf(feed->title, FEED_CAP, "%s%s ", "(bad) ", url ? url : "(unknown feed url)"); 89 return; 90 } 91 92 feed->website_url = strdup(rss->link); 93 94 snprintf(feed->title, FEED_CAP, "%s", rss->title ? rss->title : "(unknown feedtitle)"); 95 96 for (mrss_item_t* it = rss->item; it; it = it->next) { 97 char* title = (it->title && *it->title) ? it->title : ""; 98 char* link = (it->link && *it->link) ? it->link : ""; 99 char* comments = (it->comments && *it->comments) ? it->comments : ""; 100 char* desc = (it->description && *it->description) ? it->description : ""; 101 char* date = (it->pubDate && *it->pubDate) ? it->pubDate : ""; 102 103 remove_all_tags(desc); 104 105 db_post_t db_post = { 106 .title = title, 107 .link = link, 108 .comments = comments, 109 .pub_date = date, 110 .summary = desc, 111 .feed_url = url, 112 }; 113 114 db_insert_post(db_post); 115 } 116 117 mrss_free(rss); 118 printf("."); 119 fflush(stdout); 120 } 121 122 static void 123 populate_feed(feed_t* feed) 124 { 125 const char* url = feed->url; 126 db_fetch_post_t dbposts = db_fetch_posts(url); 127 if (!dbposts.success) return; 128 feed->posts = dbposts.posts; 129 feed->posts_len = dbposts.count; 130 }