X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Frss.c;h=2f06cc71bea5d96c38abd00cef67e1a5d6e0fc2b;hb=8264fbe05e119a10711d7377d18f38b2cf1f956a;hp=8edb0ba742d6d5b6f3ba8379f63b433f6e1b566a;hpb=2c8426dcc78fb0deae4aab7a53a364ebf7064a50;p=monky diff --git a/src/rss.c b/src/rss.c index 8edb0ba..2f06cc7 100644 --- a/src/rss.c +++ b/src/rss.c @@ -1,156 +1,195 @@ -/* - * rss.c - * RSS stuff (prss version) +/* -*- 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-2010 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . * - * prss.c and prss.h written by Sisu (Mikko Sysikaski) - * new rss.c written by hifi (Toni Spets) */ -#include -#include +#include "conky.h" +#include "logging.h" +#include "prss.h" +#include "text_object.h" +#include "ccurl_thread.h" #include #include -#include "prss.h" -#include -#include -#include -#include "conky.h" - -#define MAX_FEEDS 16 - -struct MemoryStruct { - char *memory; - size_t size; +struct rss_data { + char uri[128]; + char action[64]; + int act_par; + float interval; + unsigned int nrspaces; }; -typedef struct feed_ { - char* uri; - int last_update; - PRSS* data; -} feed; +static ccurl_location_t *locations_head = 0; -int num_feeds = 0; -feed feeds[MAX_FEEDS]; - -size_t -WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) +void rss_free_info(void) { - size_t realsize = size * nmemb; - struct MemoryStruct *mem = (struct MemoryStruct *)data; - - mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); - if (mem->memory) { - memcpy(&(mem->memory[mem->size]), ptr, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; + ccurl_location_t *tail = locations_head; + + while (tail) { + if (tail->result) prss_free((PRSS*)tail->result); /* clean up old data */ + tail = tail->next; } - return realsize; + ccurl_free_locations(&locations_head); } - -int rss_delay(int *wait, int delay) +static void rss_process_info(char *p, int p_max_size, char *uri, char *action, int + act_par, int interval, unsigned int nrspaces) { - time_t now = time(NULL); + PRSS *data; + char *str; - // make it minutes - if(delay < 1) delay = 1; - delay *= 60; + ccurl_location_t *curloc = ccurl_find_location(&locations_head, uri); - if(!*wait) { - *wait = now + delay; - return 1; - } + assert(act_par >= 0 && action); - if(now >= *wait + delay) { - *wait = now + delay; - return 1; + 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"); + } } - return 0; -} - -void init_rss_info() -{ - int i; - for(i = 0; i < MAX_FEEDS; i++) { - feeds[i].uri = NULL; - feeds[i].data = NULL; - feeds[i].last_update = 0; + 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); } -void free_rss_info() +void rss_scan_arg(struct text_object *obj, const char *arg) { - int i; - for(i = 0; i < num_feeds; i++) - if(feeds[i].uri != NULL) - free(feeds[i].uri); + 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; } -PRSS* -get_rss_info(char *uri, int delay) +void rss_print_info(struct text_object *obj, char *p, int p_max_size) { - CURL *curl = NULL; - CURLcode res; - // curl temps - struct MemoryStruct chunk; - chunk.memory = NULL; - chunk.size = 0; - - // pointers to struct - feed *curfeed = NULL; - PRSS *curdata = NULL; - int *last_update = 0; - - int i; - - // 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; - } - } + struct rss_data *rd = obj->data.opaque; - if(!curfeed) { // new feed - if(num_feeds == MAX_FEEDS-1) return NULL; - curfeed = &feeds[num_feeds]; - curfeed->uri = strdup(uri); - num_feeds++; - } - - last_update = &curfeed->last_update; - curdata = curfeed->data; - - if(!rss_delay(last_update, delay)) - return curdata; // wait for delay to pass - - 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(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; }