AM_CONDITIONAL(BUILD_RSS, test x$want_rss = xyes)
if test x$want_rss = xyes; then
WANT_GLIB=yes
- PKG_CHECK_MODULES([MRSS], [mrss])
- CFLAGS="$CFLAGS $MRSS_CFLAGS"
- LIBS="$LIBS $MRSS_LIBS"
+ CFLAGS="$CFLAGS `xml2-config --cflags`"
+ LIBS="$LIBS `xml2-config --libs`"
AC_DEFINE(RSS, 1, [Define if you want rss support])
fi
endif
if BUILD_RSS
-rss = rss.c
+rss = rss.c prss.c
endif
conky_SOURCES = \
struct {
char *uri;
int count;
+ int delay;
} rss;
#endif
} data;
#ifdef RSS
OBJ(rss, 0)
if (arg) {
- int argc, count;
+ int argc, count, delay;
char *uri = (char *)malloc(64 * sizeof(char *));
- argc = sscanf(arg, "%63s %d", uri, &count);
+ argc = sscanf(arg, "%63s %d %d", uri, &count, &delay);
obj->data.rss.uri = uri;
obj->data.rss.count = count;
+ obj->data.rss.delay = delay;
} else
- CRIT_ERR("rss: needs arguments");
+ CRIT_ERR("rss: needs arguments (uri, item count, delay in minutes)");
END
#endif
}
#ifdef RSS
OBJ(rss) {
- GList *walk = NULL;
- GList *list = NULL;
- char *titles = malloc(1024*sizeof(char *));
-
- memset(titles, 0, sizeof(titles));
- list = get_rss_info(obj->data.rss.uri, obj->data.rss.count);
-
- for (walk = g_list_first(list); walk != NULL; walk = g_list_next(walk)) {
- snprintf(titles, 1023, "%s%s\n", titles, (char *)walk->data);
- free(walk->data);
+ PRSS* data = get_rss_info(obj->data.rss.uri, obj->data.rss.delay);
+ if(data == NULL)
+ snprintf(p, p_max_size, "prss: Error reading RSS data\n");
+ else {
+ if(data->item_count > 0) {
+ int itmp;
+ char ctmp[64];
+ p[0] = 0;
+ int show;
+ if(obj->data.rss.count > data->item_count)
+ show = data->item_count;
+ else show = obj->data.rss.count;
+ for(itmp = 0; itmp < show; itmp++) {
+ PRSS_Item *item = &data->items[itmp];
+ if(i>0)
+ strncat(p, "\n", p_max_size);
+ snprintf(ctmp, 64, "%s", item->title);
+ strncat(p, ctmp, p_max_size);
+ }
+ } else
+ snprintf(p, p_max_size, "prss: Empty feed");
}
-
- /* we don't need last \n */
- titles[strlen(titles)-1] = '\0';
-
- snprintf(p, p_max_size, "%s", titles);
-
- free(titles);
- g_list_free(walk);
- g_list_free(list);
}
#endif
#ifdef HDDTEMP
#endif
#ifdef RSS
-#include <glib.h>
+#include "prss.h"
#endif
#include "mboxscan.h"
/* in rss.c */
#ifdef RSS
-GList* get_rss_info(char *uri, int count);
+PRSS* get_rss_info(char *uri, int delay);
#endif /* RSS */
/* in linux.c */
--- /dev/null
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "prss.h"
+
+#ifndef PARSE_OPTIONS
+#define PARSE_OPTIONS 0
+#endif
+
+static PRSS* get_data(xmlDocPtr doc);
+
+PRSS* prss_parse_data(const char* xml_data)
+{
+ xmlDocPtr doc = xmlReadMemory(xml_data, strlen(xml_data), "", NULL, PARSE_OPTIONS);
+ if (!doc)
+ return NULL;
+
+ PRSS* data = get_data(doc);
+ return data;
+}
+PRSS* prss_parse_file(const char* xml_file)
+{
+ xmlDocPtr doc = xmlReadFile(xml_file, NULL, PARSE_OPTIONS);
+ if (!doc)
+ return NULL;
+
+ PRSS* data = get_data(doc);
+ return data;
+}
+void prss_free(PRSS* data)
+{
+ xmlFreeDoc(data->_data);
+ free(data->items);
+}
+
+static inline void read_item(PRSS_Item* res, xmlNodePtr data)
+{
+ res->title = res->link = res->description = 0;
+ for(; data; data = data->next) {
+ if (data->type != XML_ELEMENT_NODE)
+ continue;
+ xmlNodePtr child = data->children;
+ if (!child)
+ continue;
+
+ if (!strcmp((char*)data->name, "title")) {
+ res->title = (char*)child->content;
+ } else if (!strcmp((char*)data->name, "link")) {
+ res->link = (char*)child->content;
+ } else if (!strcmp((char*)data->name, "description")) {
+ res->description = (char*)child->content;
+ } else if (!strcmp((char*)data->name, "category")) {
+ res->category = (char*)child->content;
+ } else if (!strcmp((char*)data->name, "pubDate")) {
+ res->pubdate = (char*)child->content;
+ }
+ }
+}
+
+PRSS* get_data(xmlDocPtr doc)
+{
+ PRSS* result = malloc(sizeof(PRSS));
+ xmlNodePtr channel = xmlDocGetRootElement(doc)->children->next;
+ if (!channel) {
+ fprintf(stderr, "Got root? No!\n");
+ return NULL;
+ }
+ result->_data = doc;
+ result->title = result->link = result->description = result->language = NULL;
+
+ /* Get item count */
+ int items = 0;
+ xmlNodePtr n;
+ for(n = channel->children; n; n = n->next)
+ if (n->type==XML_ELEMENT_NODE && !strcmp((char*)n->name, "item"))
+ ++items;
+
+ result->item_count = items;
+ result->items = malloc(items*sizeof(PRSS_Item));
+
+ int cur_item = 0;
+ for(n = channel->children; n; n = n->next) {
+ if (n->type != XML_ELEMENT_NODE)
+ continue;
+ xmlNodePtr child = n->children;
+ if (!child)
+ continue;
+
+ if (!strcmp((char*)n->name, "title")) {
+ result->title = (char*)child->content;
+ } else if (!strcmp((char*)n->name, "link")) {
+ result->link = (char*)child->content;
+ } else if (!strcmp((char*)n->name, "description")) {
+ result->description = (char*)child->content;
+ } else if (!strcmp((char*)n->name, "language")) {
+ result->language = (char*)child->content;
+ } else if (!strcmp((char*)n->name, "item")) {
+ read_item(&result->items[cur_item++], n->children);
+ }
+ }
+
+ return result;
+}
--- /dev/null
+#ifndef PRSS_H
+#define PRSS_H
+
+#include <libxml/parser.h>
+
+typedef struct PRSS_Item_ {
+ char* title;
+ char* link;
+ char* description;
+ char* category;
+ char* pubdate;
+} PRSS_Item;
+
+typedef struct PRSS_ {
+ xmlDocPtr _data;
+
+ char* title;
+ char* link;
+ char* description;
+ char* language;
+
+ PRSS_Item* items;
+ int item_count;
+} PRSS;
+
+/* Functions for parsing RSS-data */
+PRSS* prss_parse_data(const char *xml_data);
+PRSS* prss_parse_file(const char *xml_file);
+
+/* Frees the PRSS-stucture returned by prss_parse_*.
+ * The memory area pointed by data becomes invalid
+ * after call to this function. */
+void prss_free(PRSS* data);
+
+#endif // PRSS_H
/*
* rss.c
- * RSS stuff
- *
- * $Id$
+ * RSS stuff (prss version)
*/
-#include <mrss.h>
#include <stdio.h>
#include <string.h>
-#include <glib.h>
+#include <time.h>
+#include <assert.h>
+#include "prss.h"
-GList*
-get_rss_info(char *uri, int count)
+PRSS* save = NULL;
+
+int rss_delay(int delay)
{
- mrss_t *data;
- mrss_item_t *item;
- mrss_error_t ret;
- GList *titles = NULL;
- int i = 0;
+ static int wait = 0;
+ time_t now = time(NULL);
- ret = mrss_parse_url(uri, &data);
+ if(!wait) {
+ wait = now + delay;
+ return 1;
+ }
- if (ret) {
- titles = g_list_append(titles, mrss_strerror(ret));
- return titles;
+ if(now >= wait + delay) {
+ wait = now + delay;
+ return 1;
}
- for (item = data->item; item; item = item->next) {
- char *tmp = strdup(item->title);
- titles = g_list_append(titles, tmp);
-
- if ((count > 0) && (++i > count - 1))
- goto cleanup;
- }
+ return 0;
+}
+
+PRSS*
+get_rss_info(char *uri, int delay)
+{
+ if(!rss_delay(delay))
+ return save; // wait for delay to pass
+
+ if(save != NULL)
+ prss_free(save); // clean up old data
-cleanup:
- mrss_free(data);
+ save = prss_parse_file("test.xml");
+ //assert(save);
- return titles;
+ return save;
}