1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-11-05 21:07:52 +00:00

New initial RSS code. Parser written by Sisu (Mikko Sysikaski) with more portable libxml2. It is still unstable and in development.\n\nNote: automake and autoconf scripts needs to be updated to support libxml2\!

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@868 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
Toni Spets 2007-06-01 10:42:57 +00:00
parent 90b318f9cb
commit 3fdb6b7027
7 changed files with 203 additions and 56 deletions

View File

@ -190,9 +190,8 @@ AC_ARG_ENABLE([rss],
AM_CONDITIONAL(BUILD_RSS, test x$want_rss = xyes) AM_CONDITIONAL(BUILD_RSS, test x$want_rss = xyes)
if test x$want_rss = xyes; then if test x$want_rss = xyes; then
WANT_GLIB=yes WANT_GLIB=yes
PKG_CHECK_MODULES([MRSS], [mrss]) CFLAGS="$CFLAGS `xml2-config --cflags`"
CFLAGS="$CFLAGS $MRSS_CFLAGS" LIBS="$LIBS `xml2-config --libs`"
LIBS="$LIBS $MRSS_LIBS"
AC_DEFINE(RSS, 1, [Define if you want rss support]) AC_DEFINE(RSS, 1, [Define if you want rss support])
fi fi

View File

@ -52,7 +52,7 @@ hddtemp = hddtemp.c
endif endif
if BUILD_RSS if BUILD_RSS
rss = rss.c rss = rss.c prss.c
endif endif
conky_SOURCES = \ conky_SOURCES = \

View File

@ -1287,6 +1287,7 @@ struct text_object {
struct { struct {
char *uri; char *uri;
int count; int count;
int delay;
} rss; } rss;
#endif #endif
} data; } data;
@ -3119,14 +3120,15 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
#ifdef RSS #ifdef RSS
OBJ(rss, 0) OBJ(rss, 0)
if (arg) { if (arg) {
int argc, count; int argc, count, delay;
char *uri = (char *)malloc(64 * sizeof(char *)); 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.uri = uri;
obj->data.rss.count = count; obj->data.rss.count = count;
obj->data.rss.delay = delay;
} else } else
CRIT_ERR("rss: needs arguments"); CRIT_ERR("rss: needs arguments (uri, item count, delay in minutes)");
END END
#endif #endif
@ -4286,26 +4288,28 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
} }
#ifdef RSS #ifdef RSS
OBJ(rss) { OBJ(rss) {
GList *walk = NULL; PRSS* data = get_rss_info(obj->data.rss.uri, obj->data.rss.delay);
GList *list = NULL; if(data == NULL)
char *titles = malloc(1024*sizeof(char *)); snprintf(p, p_max_size, "prss: Error reading RSS data\n");
else {
memset(titles, 0, sizeof(titles)); if(data->item_count > 0) {
list = get_rss_info(obj->data.rss.uri, obj->data.rss.count); int itmp;
char ctmp[64];
for (walk = g_list_first(list); walk != NULL; walk = g_list_next(walk)) { p[0] = 0;
snprintf(titles, 1023, "%s%s\n", titles, (char *)walk->data); int show;
free(walk->data); 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 #endif
#ifdef HDDTEMP #ifdef HDDTEMP

View File

@ -47,7 +47,7 @@
#endif #endif
#ifdef RSS #ifdef RSS
#include <glib.h> #include "prss.h"
#endif #endif
#include "mboxscan.h" #include "mboxscan.h"
@ -598,7 +598,7 @@ char *get_hddtemp_info(char *dev, char *addr, int port, char *unit);
/* in rss.c */ /* in rss.c */
#ifdef RSS #ifdef RSS
GList* get_rss_info(char *uri, int count); PRSS* get_rss_info(char *uri, int delay);
#endif /* RSS */ #endif /* RSS */
/* in linux.c */ /* in linux.c */

105
src/prss.c Normal file
View File

@ -0,0 +1,105 @@
#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;
}

35
src/prss.h Normal file
View File

@ -0,0 +1,35 @@
#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

View File

@ -1,41 +1,45 @@
/* /*
* rss.c * rss.c
* RSS stuff * RSS stuff (prss version)
*
* $Id$
*/ */
#include <mrss.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <glib.h> #include <time.h>
#include <assert.h>
#include "prss.h"
GList* PRSS* save = NULL;
get_rss_info(char *uri, int count)
int rss_delay(int delay)
{ {
mrss_t *data; static int wait = 0;
mrss_item_t *item; time_t now = time(NULL);
mrss_error_t ret;
GList *titles = NULL;
int i = 0;
ret = mrss_parse_url(uri, &data); if(!wait) {
wait = now + delay;
if (ret) { return 1;
titles = g_list_append(titles, mrss_strerror(ret));
return titles;
} }
for (item = data->item; item; item = item->next) { if(now >= wait + delay) {
char *tmp = strdup(item->title); wait = now + delay;
titles = g_list_append(titles, tmp); return 1;
}
if ((count > 0) && (++i > count - 1))
goto cleanup;
}
cleanup: return 0;
mrss_free(data); }
return titles; 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
save = prss_parse_file("test.xml");
//assert(save);
return save;
} }