rss_t* load_rss(gchar* feed_url, GError** err){ mrss_t *feed; mrss_error_t ret; mrss_item_t *item; CURLcode code; ret = mrss_parse_url_with_options_and_error(feed_url, &feed, NULL, &code); if(ret){ if(ret == MRSS_ERR_DOWNLOAD){ g_set_error(err, rss_quark(), RSS_ERR_CURL, "mrss_curl_strerror: %s\n", mrss_curl_strerror(code)); } else{ g_set_error(err, rss_quark(), RSS_ERR_MRSS, "mrss_strerror: %s\n", mrss_strerror(ret)); } return NULL; } rss_t* rss = (rss_t*) malloc(sizeof(rss_t)); if(rss == NULL){ g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC, "malloc: Failed to alloc memory for read the rss_t* structure.\n"); return NULL; } rss->chapters = NULL; for(item = feed->item, rss->chap_len = 0; item != NULL; item = item->next, rss->chap_len++){ rss->chapters = (chapter_t**) realloc( rss->chapters, (rss->chap_len + 1) * sizeof(chapter_t*) ); if(rss->chapters == NULL){ g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC, "malloc: Failed to alloc memory for read the chapter_t** structure.\n"); return NULL; } rss->chapters[rss->chap_len] = (chapter_t*) malloc(sizeof(chapter_t)); if(rss->chapters[rss->chap_len] == NULL){ g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC, "malloc: Failed to alloc memory for read the chapter_t* structure.\n"); return NULL; } rss->chapters[rss->chap_len]->title = g_strdup(item->title); rss->chapters[rss->chap_len]->url = g_strdup(item->enclosure_url); rss->chapters[rss->chap_len]->type = g_strdup(item->enclosure_type); rss->chapters[rss->chap_len]->size = item->enclosure_length; } mrss_free(feed); return rss; }
/* todo: save podcast episodes to db rather than loading them every time */ char *load_episodes() { int i; int podcast_uris_num; char **podcast_uris = select_podcasts(&podcast_uris_num); mrss_t *feed; mrss_item_t *episode; mrss_tag_t *other_tags; json_t *jsn_podcasts_obj = json_object(); json_t *jsn_podcasts_arr = json_array(); for (i = 0; i < podcast_uris_num; i++) { mrss_parse_url_with_options_and_error(podcast_uris[i], &feed, NULL, NULL); json_t *jsn_podcast_obj = json_object(); json_object_set_new(jsn_podcast_obj, "title", json_string(feed->title)); json_t *jsn_episodes_arr = json_array(); episode = feed->item; while (episode) { struct tm tm_publish; time_t time_now, time_publish; memset(&tm_publish, 0, sizeof(struct tm)); time(&time_now); /* episode->pubDate is formated like e.g. Sat, 30 Jul 2016 00:00:00 +0200 when parsing the datetime string only year, month and day will be used for windows something like e.g. char month[4]; int day, year; sscanf(episode->pubDate, "%*s %d %s %d %*d:%*d:%*d %*s", &day, month, &year); could be used instead of relying on strptime */ /* time string format like "Sat, 06 Aug 2016 08:14:24 +0200" */ if (strptime(episode->pubDate, "%a, %0d %b %Y %T %z", &tm_publish) != NULL) { double time_diff = difftime(time_now, mktime(&tm_publish)); if (time_diff / 86400.0 > 30.0) { break; } } /* time string format like "Sat, 30 Jul 2016 01:00:00 GMT" */ else if (strptime(episode->pubDate, "%a, %0d %b %Y %T %Z", &tm_publish) != NULL) { double time_diff = difftime(time_now, mktime(&tm_publish)); if (time_diff / 86400.0 > 30.0) { break; } } else { printf("unsopported time format: %s\n", episode->pubDate); break; } json_t *jsn_episode_obj = json_object(); json_object_set_new(jsn_episode_obj, "title", json_string(episode->title)); json_object_set_new(jsn_episode_obj, "description", json_string(episode->description)); json_object_set_new(jsn_episode_obj, "stream_uri", json_string(episode->enclosure_url)); if (episode->other_tags) { other_tags = episode->other_tags; while (other_tags) { if (strcmp(other_tags->name, "duration") == 0) { json_object_set_new(jsn_episode_obj, "duration", json_string(other_tags->value)); } other_tags = other_tags->next; } } episode = episode->next; json_array_append_new(jsn_episodes_arr, jsn_episode_obj); } mrss_free(feed); json_object_set_new(jsn_podcast_obj, "episodes", jsn_episodes_arr); json_array_append_new(jsn_podcasts_arr, jsn_podcast_obj); free(podcast_uris[i]); } free(podcast_uris); json_object_set_new(jsn_podcasts_obj, "podcasts", jsn_podcasts_arr); return json_dumps(jsn_podcasts_obj, JSON_COMPACT); }
mrss_error_t mrss_parse_url_with_options (char *url, mrss_t ** ret, mrss_options_t * options) { return mrss_parse_url_with_options_and_error (url, ret, options, NULL); }
mrss_error_t mrss_parse_url (char *url, mrss_t ** ret) { return mrss_parse_url_with_options_and_error (url, ret, NULL, NULL); }