mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-17 18:45:10 +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:
parent
90b318f9cb
commit
3fdb6b7027
@ -190,9 +190,8 @@ AC_ARG_ENABLE([rss],
|
||||
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
|
||||
|
||||
|
@ -52,7 +52,7 @@ hddtemp = hddtemp.c
|
||||
endif
|
||||
|
||||
if BUILD_RSS
|
||||
rss = rss.c
|
||||
rss = rss.c prss.c
|
||||
endif
|
||||
|
||||
conky_SOURCES = \
|
||||
|
48
src/conky.c
48
src/conky.c
@ -1287,6 +1287,7 @@ struct text_object {
|
||||
struct {
|
||||
char *uri;
|
||||
int count;
|
||||
int delay;
|
||||
} rss;
|
||||
#endif
|
||||
} data;
|
||||
@ -3119,14 +3120,15 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
|
||||
#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
|
||||
@ -4286,26 +4288,28 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
|
||||
}
|
||||
#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
|
||||
|
@ -47,7 +47,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef RSS
|
||||
#include <glib.h>
|
||||
#include "prss.h"
|
||||
#endif
|
||||
|
||||
#include "mboxscan.h"
|
||||
@ -598,7 +598,7 @@ char *get_hddtemp_info(char *dev, char *addr, int port, char *unit);
|
||||
|
||||
/* 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 */
|
||||
|
105
src/prss.c
Normal file
105
src/prss.c
Normal 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
35
src/prss.h
Normal 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
|
60
src/rss.c
60
src/rss.c
@ -1,41 +1,45 @@
|
||||
/*
|
||||
* 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 (ret) {
|
||||
titles = g_list_append(titles, mrss_strerror(ret));
|
||||
return titles;
|
||||
if(!wait) {
|
||||
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;
|
||||
}
|
||||
if(now >= wait + delay) {
|
||||
wait = now + delay;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mrss_free(data);
|
||||
|
||||
return titles;
|
||||
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
|
||||
|
||||
save = prss_parse_file("test.xml");
|
||||
//assert(save);
|
||||
|
||||
return save;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user