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:
parent
90b318f9cb
commit
3fdb6b7027
@ -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
|
||||||
|
|
||||||
|
@ -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 = \
|
||||||
|
48
src/conky.c
48
src/conky.c
@ -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
|
||||||
|
@ -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
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.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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user