X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Frss.c;h=2f06cc71bea5d96c38abd00cef67e1a5d6e0fc2b;hb=8264fbe05e119a10711d7377d18f38b2cf1f956a;hp=5bdbc8a5884630fb4f7dec32dc5aa3751b14c53b;hpb=80a71ea8bd7da0dc352f7ef7261a2e59f5c747e4;p=monky diff --git a/src/rss.c b/src/rss.c index 5bdbc8a..2f06cc7 100644 --- a/src/rss.c +++ b/src/rss.c @@ -1,9 +1,12 @@ -/* Conky, a system monitor, based on torsmo +/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- + * vim: ts=4 sw=4 noet ai cindent syntax=c + * + * Conky, a system monitor, based on torsmo * * Please see COPYING for details * * Copyright (c) 2007 Toni Spets - * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al. + * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al. * (see AUTHORS) * All rights reserved. * @@ -24,137 +27,169 @@ #include "conky.h" #include "logging.h" #include "prss.h" +#include "text_object.h" +#include "ccurl_thread.h" #include #include -#include -#include -#include - -#define MAX_FEEDS 16 -typedef struct feed_ { - char *uri; - int last_update; - PRSS *data; -} feed; +struct rss_data { + char uri[128]; + char action[64]; + int act_par; + float interval; + unsigned int nrspaces; +}; -int num_feeds = 0; -feed feeds[MAX_FEEDS]; +static ccurl_location_t *locations_head = 0; -int rss_delay(int *wait_time, int delay) +void rss_free_info(void) { - time_t now = time(NULL); - - // make it minutes - if (delay < 1) { - delay = 1; - } - delay *= 60; + ccurl_location_t *tail = locations_head; - if (!*wait_time) { - *wait_time = now + delay; - return 1; + while (tail) { + if (tail->result) prss_free((PRSS*)tail->result); /* clean up old data */ + tail = tail->next; } - - if (now >= *wait_time + delay) { - *wait_time = now + delay; - return 1; - } - - return 0; + ccurl_free_locations(&locations_head); } -void init_rss_info(void) +static void rss_process_info(char *p, int p_max_size, char *uri, char *action, int + act_par, int interval, unsigned int nrspaces) { - int i; + PRSS *data; + char *str; - for (i = 0; i < MAX_FEEDS; i++) { - feeds[i].uri = NULL; - feeds[i].data = NULL; - feeds[i].last_update = 0; - } -} + ccurl_location_t *curloc = ccurl_find_location(&locations_head, uri); -void free_rss_info(void) -{ - int i; + assert(act_par >= 0 && action); - for (i = 0; i < num_feeds; i++) { - if (feeds[i].uri != NULL) { - free(feeds[i].uri); + if (!curloc->p_timed_thread) { + curloc->result = malloc(sizeof(PRSS)); + memset(curloc->result, 0, sizeof(PRSS)); + curloc->process_function = &prss_parse_data; + ccurl_init_thread(curloc, interval); + if (!curloc->p_timed_thread) { + NORM_ERR("error setting up RSS thread"); } } -} - -PRSS *get_rss_info(char *uri, int delay) -{ - CURL *curl = NULL; - CURLcode res; - - // pointers to struct - feed *curfeed = NULL; - PRSS *curdata = NULL; - int *last_update = 0; - - int i; - - // curl temps - struct MemoryStruct chunk; - - chunk.memory = NULL; - chunk.size = 0; - // first seek for the uri in list - for (i = 0; i < num_feeds; i++) { - if (feeds[i].uri != NULL) { - if (!strcmp(feeds[i].uri, uri)) { - curfeed = &feeds[i]; - break; + timed_thread_lock(curloc->p_timed_thread); + data = (PRSS*)curloc->result; + + if (data == NULL || data->item_count < 1) { + *p = 0; + } else { + /* + * XXX: Refactor this so that we can retrieve any of the fields in the + * PRSS struct (in prss.h). + */ + if (strcmp(action, "feed_title") == EQUAL) { + str = data->title; + if (str && strlen(str) > 0) { + // remove trailing new line if one exists + if (str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = 0; + } + snprintf(p, p_max_size, "%s", str); } + } else if (strcmp(action, "item_title") == EQUAL) { + if (act_par < data->item_count) { + str = data->items[act_par].title; + // remove trailing new line if one exists + if (str && strlen(str) > 0) { + if (str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = 0; + } + snprintf(p, p_max_size, "%s", str); + } + } + } else if (strcmp(action, "item_desc") == EQUAL) { + if (act_par < data->item_count) { + str = + data->items[act_par].description; + // remove trailing new line if one exists + if (str && strlen(str) > 0) { + if (str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = 0; + } + snprintf(p, p_max_size, "%s", str); + } + } + } else if (strcmp(action, "item_titles") == EQUAL) { + if (data->item_count > 0) { + int itmp; + int show; + //'tmpspaces' is a string with spaces too be placed in front of each title + char *tmpspaces = malloc(nrspaces + 1); + memset(tmpspaces, ' ', nrspaces); + tmpspaces[nrspaces]=0; + + if (act_par > data->item_count) { + show = data->item_count; + } else { + show = act_par; + } + for (itmp = 0; itmp < show; itmp++) { + PRSS_Item *item = &data->items[itmp]; + + str = item->title; + if (str) { + // don't add new line before first item + if (itmp > 0) { + strncat(p, "\n", p_max_size); + } + /* remove trailing new line if one exists, + * we have our own */ + if (strlen(str) > 0 && str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = 0; + } + strncat(p, tmpspaces, p_max_size); + strncat(p, str, p_max_size); + } + } + free(tmpspaces); + } + } else { + NORM_ERR("rss: Invalid action '%s'", action); } } + timed_thread_unlock(curloc->p_timed_thread); +} - if (!curfeed) { // new feed - if (num_feeds == MAX_FEEDS - 1) { - return NULL; - } - curfeed = &feeds[num_feeds]; - curfeed->uri = strndup(uri, text_buffer_size); - num_feeds++; +void rss_scan_arg(struct text_object *obj, const char *arg) +{ + int argc; + struct rss_data *rd; + + rd = malloc(sizeof(struct rss_data)); + memset(rd, 0, sizeof(struct rss_data)); + + argc = sscanf(arg, "%127s %f %63s %d %u", rd->uri, &rd->interval, rd->action, + &rd->act_par, &rd->nrspaces); + if (argc < 3) { + NORM_ERR("wrong number of arguments for $rss"); + free(rd); + return; } + obj->data.opaque = rd; +} - last_update = &curfeed->last_update; - curdata = curfeed->data; - - if (!rss_delay(last_update, delay)) { - return curdata; // wait for delay to pass - } +void rss_print_info(struct text_object *obj, char *p, int p_max_size) +{ + struct rss_data *rd = obj->data.opaque; - if (curdata != NULL) { - prss_free(curdata); // clean up old data - curdata = NULL; + if (!rd) { + NORM_ERR("error processing RSS data"); + return; } + rss_process_info(p, p_max_size, rd->uri, rd->action, + rd->act_par, rd->interval, rd->nrspaces); +} - curl = curl_easy_init(); - if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, uri); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-rss/1.0"); - - res = curl_easy_perform(curl); - if (res == CURLE_OK && chunk.size) { - curdata = prss_parse_data(chunk.memory); - free(chunk.memory); - } else { - ERR("No data from server"); - } - - curl_easy_cleanup(curl); +void rss_free_obj_info(struct text_object *obj) +{ + if (obj->data.opaque) { + free(obj->data.opaque); + obj->data.opaque = NULL; } - - curfeed->data = curdata; - - return curdata; }