1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-26 12:27:52 +00:00

Overhauled RSS and weather, added $curl.

I've taken the curl stuff out of weather and RSS and moved it into it's
own entity.  It should be easier to create curl-based objects if needed
now.
This commit is contained in:
Brenden Matthews 2009-07-19 23:43:36 -06:00
parent 80a71ea8bd
commit c05c157ead
15 changed files with 374 additions and 499 deletions

View File

@ -307,6 +307,14 @@ if test x$want_xmms2 = xyes; then
AC_DEFINE(XMMS2, 1, [Define if you want XMMS2 support]) AC_DEFINE(XMMS2, 1, [Define if you want XMMS2 support])
fi fi
dnl
dnl libcurl, see below for more (this has to be above the other uses of want_curl)
dnl
AC_ARG_ENABLE([curl],
AC_HELP_STRING([--enable-curl], [enable if you want curl support @<:@default=no@:>@]),
[want_curl="$enableval"], [want_curl=no])
dnl dnl
dnl EVE Skill Monitor dnl EVE Skill Monitor
dnl dnl
@ -317,10 +325,8 @@ AC_ARG_ENABLE([eve],
AM_CONDITIONAL(BUILD_EVE, test x$want_eve = xyes) AM_CONDITIONAL(BUILD_EVE, test x$want_eve = xyes)
if test x$want_eve = xyes; then if test x$want_eve = xyes; then
PKG_CHECK_MODULES([libxml2], libxml-2.0) want_curl=yes
PKG_CHECK_MODULES([libcurl], libcurl) want_libxml2=yes
conky_CFLAGS="$conky_CFLAGS $libxml2_CFLAGS $libcurl_CFLAGS"
conky_LIBS="$conky_LIBS $libxml2_LIBS $libcurl_LIBS"
AC_DEFINE(EVE, 1, [Define if you want Eve-Online Skill monitor support]) AC_DEFINE(EVE, 1, [Define if you want Eve-Online Skill monitor support])
AC_DEFINE(EVEURL_TRAINING, "http://api.eve-online.com/char/SkillInTraining.xml.aspx", [Eve training URL]) AC_DEFINE(EVEURL_TRAINING, "http://api.eve-online.com/char/SkillInTraining.xml.aspx", [Eve training URL])
AC_DEFINE(EVEURL_SKILLTREE, "http://api.eve-online.com/eve/Skilltree.xml.aspx", [Eve skilltree URL]) AC_DEFINE(EVEURL_SKILLTREE, "http://api.eve-online.com/eve/Skilltree.xml.aspx", [Eve skilltree URL])
@ -339,11 +345,9 @@ 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([libxml2], libxml-2.0) want_curl=yes
PKG_CHECK_MODULES([libcurl], libcurl) want_libxml2=yes
conky_CFLAGS="$conky_CFLAGS $libxml2_CFLAGS $libcurl_CFLAGS" AC_DEFINE(RSS, 1, [Define if you want Curl support])
conky_LIBS="$conky_LIBS $libxml2_LIBS $libcurl_LIBS"
AC_DEFINE(RSS, 1, [Define if you want rss support])
fi fi
dnl dnl
@ -360,17 +364,13 @@ AC_ARG_ENABLE([xoap],
# #
AM_CONDITIONAL(BUILD_WEATHER, test x$want_weather = xyes) AM_CONDITIONAL(BUILD_WEATHER, test x$want_weather = xyes)
if test x$want_weather = xyes; then if test x$want_weather = xyes; then
AM_CONDITIONAL(BUILD_XOAP, test x$want_xoap = xyes) AM_CONDITIONAL(BUILD_XOAP, test x$want_xoap = xyes)
if test x$want_xoap = xyes; then if test x$want_xoap = xyes; then
PKG_CHECK_MODULES([libxml2], libxml-2.0) want_libxml2=yes
conky_CFLAGS="$conky_CFLAGS $libxml2_CFLAGS" AC_DEFINE(XOAP, 1, [Define if you want weather xoap support])
conky_LIBS="$conky_LIBS $libxml2_LIBS" AC_DEFINE(XOAP_FILE, "$HOME/.xoaprc", [User xoap keys file])
AC_DEFINE(XOAP, 1, [Define if you want weather xoap support])
AC_DEFINE(XOAP_FILE, "$HOME/.xoaprc", [User xoap keys file])
fi fi
PKG_CHECK_MODULES([libcurl], libcurl) want_curl=yes
conky_CFLAGS="$conky_CFLAGS $libcurl_CFLAGS"
conky_LIBS="$conky_LIBS $libcurl_LIBS"
AC_DEFINE(WEATHER, 1, [Define if you want weather support]) AC_DEFINE(WEATHER, 1, [Define if you want weather support])
fi fi
@ -648,6 +648,28 @@ if test x$WANT_GLIB = xyes; then
conky_LIBS="$conky_LIBS $GLib2_LIBS" conky_LIBS="$conky_LIBS $GLib2_LIBS"
fi fi
dnl
dnl libcurl
dnl
if test x$want_curl = xyes; then
PKG_CHECK_MODULES([libcurl], libcurl)
conky_CFLAGS="$conky_CFLAGS $libcurl_CFLAGS"
conky_LIBS="$conky_LIBS $libcurl_LIBS"
AC_DEFINE(HAVE_CURL, 1, [Define if you want Curl support])
fi
AM_CONDITIONAL(BUILD_CURL, test x$want_curl = xyes)
dnl
dnl libx
dnl
if test x$want_libxml2 = xyes; then
PKG_CHECK_MODULES([libxml2], libxml-2.0)
conky_CFLAGS="$conky_CFLAGS $libxml2_CFLAGS"
conky_LIBS="$conky_LIBS $libxml2_LIBS"
fi
dnl dnl
dnl KVM dnl KVM
dnl dnl
@ -907,9 +929,10 @@ $PACKAGE $VERSION configured successfully:
hddtemp: $want_hddtemp hddtemp: $want_hddtemp
portmon: $want_portmon portmon: $want_portmon
RSS: $want_rss RSS: $want_rss
Weather (METAR) Curl: $want_curl
NOAA: $want_weather Weather
XOAP: $want_xoap NOAA: $want_weather
XOAP: $want_xoap
wireless: $want_wlan wireless: $want_wlan
IBM: $want_ibm IBM: $want_ibm
nvidia: $want_nvidia nvidia: $want_nvidia

View File

@ -194,6 +194,16 @@
Colour can be also in Colour can be also in
#rrggbb format (hex). #rrggbb format (hex).
</para> </para>
<para>
Some objects may create threads, and sometimes these threads will
not be destroyed until Conky terminates. There is no way to
destroy or clean up threads while Conky is running. For example,
if you use an MPD variable, the MPD thread will keep running until
Conky dies. Some threaded objects will use one of the parameters
as a 'key', so that you only have 1 relevant thread running (for
example, the $curl, $rss and $weather objects launch one thread per
URI).
</para>
&variables; &variables;
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -209,6 +219,11 @@
then call functions in Lua via Conky's $lua, $lua_read, and Lua then call functions in Lua via Conky's $lua, $lua_read, and Lua
hooks. hooks.
</para> </para>
<para>
Be careful when creating threaded objects through the Lua API. You
could wind up with a whole bunch of threads running if a thread is
created with each iteration.
</para>
<para> <para>
At this time, the Lua API should not be considered stable and may At this time, the Lua API should not be considered stable and may
change drastically from one release to another as it matures. change drastically from one release to another as it matures.

View File

@ -2546,22 +2546,48 @@
mailboxes are supported, mbox type will return -1. mailboxes are supported, mbox type will return -1.
<para /></listitem> <para /></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<command>
<option>curl</option>
</command>
<option>url interval_in_minutes</option>
</term>
<listitem>
<para>
Download data from URI using Curl at the specified interval.
The interval may be a floating point value greater than 0,
otherwise defaults to 15 minutes. Most useful when used in
conjunction with Lua and the Lua API. This object is threaded,
and once a thread is created it can't be explicitely destroyed.
One thread will run for each URI specified. You can use any
protocol that Curl supports.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<command> <command>
<option>rss</option> <option>rss</option>
</command> </command>
<option>url delay_in_minutes action (num_par <option>uri interval_in_minutes action (num_par
(spaces_in_front))</option> (spaces_in_front))</option>
</term> </term>
<listitem>Download and parse RSS feeds. Action may be one <listitem>
of the following: feed_title, item_title (with num par), <para>
item_desc (with num par) and item_titles (when using this Download and parse RSS feeds. The interval may be a floating
action and spaces_in_front is given conky places that many point value greater than 0, otherwise defaults to 15 minutes.
spaces in front of each item). Action may be one of the following: feed_title, item_title
<para /></listitem> (with num par), item_desc (with num par) and item_titles (when
</varlistentry> using this action and spaces_in_front is given conky places
<varlistentry> that many spaces in front of each item). This object is
threaded, and once a thread is created it can't be explicitely
destroyed. One thread will run for each URI specified. You
can use any protocol that Curl supports.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term> <term>
<command> <command>
<option>running_processes</option> <option>running_processes</option>
@ -2963,7 +2989,9 @@
longer then the time it takes your script to execute. For longer then the time it takes your script to execute. For
example, if you have a script that take 5 seconds to example, if you have a script that take 5 seconds to
execute, you should make the interval at least 6 seconds. execute, you should make the interval at least 6 seconds.
See also $execi. See also $execi. This object will clean up the thread when it is
destroyed, so it can safely be used in a nested fashion, though it may
not produce the desired behaviour if used this way.
<para /></listitem> <para /></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -3288,7 +3316,7 @@
<command> <command>
<option>weather</option> <option>weather</option>
</command> </command>
<option>URI locID data_type (delay_in_minutes)</option> <option>URI locID data_type (interval_in_minutes)</option>
</term> </term>
<listitem> <listitem>
<para>Download, parse and display METAR data.</para> <para>Download, parse and display METAR data.</para>
@ -3363,6 +3391,11 @@
</simplelist> </simplelist>
<para>'delay_in_minutes' (optional, default 30) cannot <para>'delay_in_minutes' (optional, default 30) cannot
be lower than 30 min.</para> be lower than 30 min.</para>
<para>
This object is threaded, and once a thread is created it can't be
explicitely destroyed. One thread will run for each URI specified.
You can use any protocol that Curl supports.
</para>
<para>Note that these variables are still EXPERIMENTAL <para>Note that these variables are still EXPERIMENTAL
and can be subject to many future changes.</para> and can be subject to many future changes.</para>
</listitem> </listitem>

View File

@ -110,6 +110,10 @@ if BUILD_EVE
eve = eve.c eve.h eve = eve.c eve.h
endif endif
if BUILD_CURL
ccurl_thread = ccurl_thread.c ccurl_thread.h
endif
if BUILD_RSS if BUILD_RSS
rss = rss.c prss.c prss.h rss = rss.c prss.c prss.h
endif endif
@ -161,7 +165,7 @@ conky_SOURCES = \
$(eve) \ $(eve) \
$(rss) \ $(rss) \
$(weather) \ $(weather) \
$(lua) \ $(lua) \
$(solaris) \ $(solaris) \
timed_thread.c \ timed_thread.c \
timed_thread.h \ timed_thread.h \
@ -179,8 +183,9 @@ conky_SOURCES = \
text_object.h \ text_object.h \
text_object.c \ text_object.c \
algebra.h \ algebra.h \
algebra.c \ algebra.c \
$(imlib2) $(imlib2) \
$(ccurl_thread)
conky_LDFLAGS = \ conky_LDFLAGS = \
$(PTHREAD_LIBS) \ $(PTHREAD_LIBS) \
@ -211,8 +216,9 @@ EXTRA_DIST = \
libtcp-portmon.c \ libtcp-portmon.c \
libtcp-portmon.h \ libtcp-portmon.h \
rss.h \ rss.h \
weather.h \ prss.h \
llua.h \ weather.h \
llua.h \
mail.h \ mail.h \
mixer.h \ mixer.h \
moc.h \ moc.h \
@ -240,9 +246,10 @@ EXTRA_DIST = \
ibm.c \ ibm.c \
ibm.h \ ibm.h \
sony.h \ sony.h \
users.c \ users.c \
imlib2.c \ imlib2.c \
imlib2.h imlib2.h \
ccurl_thread.h
# vi:set ts=4 sw=4 noet ai nocindent syntax=automake: # vi:set ts=4 sw=4 noet ai nocindent syntax=automake:

View File

@ -513,20 +513,3 @@ unsigned int round_to_int(float f)
} }
} }
/* utility function used by RSS and Weather stuff for a curl callback.
*/
size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
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;
}
return realsize;
}

View File

@ -89,14 +89,4 @@ int get_battery_perct(const char *bat);
int get_battery_perct_bar(const char *bat); int get_battery_perct_bar(const char *bat);
void get_battery_short_status(char *buf, unsigned int n, const char *bat); void get_battery_short_status(char *buf, unsigned int n, const char *bat);
/*
* used by RSS and Weather
*/
struct MemoryStruct {
char *memory;
size_t size;
};
size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data);
#endif /* _COMMON_H */ #endif /* _COMMON_H */

View File

@ -158,7 +158,7 @@ static void reload_config(void);
static void generate_text_internal(char *, int, struct text_object, static void generate_text_internal(char *, int, struct text_object,
struct information *); struct information *);
static int extract_variable_text_internal(struct text_object *, static int extract_variable_text_internal(struct text_object *,
const char *, char); const char *);
static void print_version(void) static void print_version(void)
{ {
@ -208,6 +208,9 @@ static void print_version(void)
#ifdef TCP_PORT_MONITOR #ifdef TCP_PORT_MONITOR
" * portmon\n" " * portmon\n"
#endif /* TCP_PORT_MONITOR */ #endif /* TCP_PORT_MONITOR */
#ifdef HAVE_CURL
" * Curl\n"
#endif /* HAVE_CURL */
#ifdef RSS #ifdef RSS
" * RSS\n" " * RSS\n"
#endif /* RSS */ #endif /* RSS */
@ -908,6 +911,11 @@ static void free_text_objects(struct text_object *root, int internal)
case OBJ_eve: case OBJ_eve:
break; break;
#endif #endif
#ifdef HAVE_CURL
case OBJ_curl:
free(data.curl.uri);
break;
#endif
#ifdef RSS #ifdef RSS
case OBJ_rss: case OBJ_rss:
free(data.rss.uri); free(data.rss.uri);
@ -954,6 +962,7 @@ static void free_text_objects(struct text_object *root, int internal)
free(data.execi.buffer); free(data.execi.buffer);
break; break;
case OBJ_texeci: case OBJ_texeci:
if (data.texeci.p_timed_thread) timed_thread_destroy(data.texeci.p_timed_thread, &data.texeci.p_timed_thread);
free(data.texeci.cmd); free(data.texeci.cmd);
free(data.texeci.buffer); free(data.texeci.buffer);
break; break;
@ -1245,7 +1254,7 @@ long current_text_color;
/* construct_text_object() creates a new text_object */ /* construct_text_object() creates a new text_object */
static struct text_object *construct_text_object(const char *s, static struct text_object *construct_text_object(const char *s,
const char *arg, long line, char allow_threaded, void **ifblock_opaque, void *free_at_crash) const char *arg, long line, void **ifblock_opaque, void *free_at_crash)
{ {
// struct text_object *obj = new_text_object(); // struct text_object *obj = new_text_object();
struct text_object *obj = new_text_object_internal(); struct text_object *obj = new_text_object_internal();
@ -1257,8 +1266,6 @@ static struct text_object *construct_text_object(const char *s,
#define OBJ_IF(a, n) if (strcmp(s, #a) == 0) { \ #define OBJ_IF(a, n) if (strcmp(s, #a) == 0) { \
obj->type = OBJ_##a; need_mask |= (1ULL << n); \ obj->type = OBJ_##a; need_mask |= (1ULL << n); \
obj_be_ifblock_if(ifblock_opaque, obj); { obj_be_ifblock_if(ifblock_opaque, obj); {
#define OBJ_THREAD(a, n) if (strcmp(s, #a) == 0 && allow_threaded) { \
obj->type = OBJ_##a; need_mask |= (1ULL << n); {
#define END } } else #define END } } else
#define SIZE_DEFAULTS(arg) { \ #define SIZE_DEFAULTS(arg) { \
@ -1821,7 +1828,7 @@ static struct text_object *construct_text_object(const char *s,
obj->data.execi.cmd = strndup(arg + n, text_buffer_size); obj->data.execi.cmd = strndup(arg + n, text_buffer_size);
obj->data.execi.buffer = malloc(text_buffer_size); obj->data.execi.buffer = malloc(text_buffer_size);
} }
END OBJ_THREAD(texeci, 0) END OBJ(texeci, 0)
int n; int n;
if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) { if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
@ -2110,7 +2117,7 @@ static struct text_object *construct_text_object(const char *s,
obj->data.ifblock.s = strndup(arg, text_buffer_size); obj->data.ifblock.s = strndup(arg, text_buffer_size);
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, extract_variable_text_internal(obj->sub,
obj->data.ifblock.s, 0); obj->data.ifblock.s);
} }
END OBJ_IF(if_match, 0) END OBJ_IF(if_match, 0)
if (!arg) { if (!arg) {
@ -2120,7 +2127,7 @@ static struct text_object *construct_text_object(const char *s,
obj->data.ifblock.s = strndup(arg, text_buffer_size); obj->data.ifblock.s = strndup(arg, text_buffer_size);
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, extract_variable_text_internal(obj->sub,
obj->data.ifblock.s, 0); obj->data.ifblock.s);
} }
END OBJ_IF(if_existing, 0) END OBJ_IF(if_existing, 0)
if (!arg) { if (!arg) {
@ -2595,7 +2602,7 @@ static struct text_object *construct_text_object(const char *s,
END OBJ(apm_battery_life, 0) END OBJ(apm_battery_life, 0)
END OBJ(apm_battery_time, 0) END OBJ(apm_battery_time, 0)
#endif /* __FreeBSD__ */ #endif /* __FreeBSD__ */
END OBJ_THREAD(imap_unseen, 0) END OBJ(imap_unseen, 0)
if (arg) { if (arg) {
// proccss // proccss
obj->data.mail = parse_mail_args(IMAP_TYPE, arg); obj->data.mail = parse_mail_args(IMAP_TYPE, arg);
@ -2603,7 +2610,7 @@ static struct text_object *construct_text_object(const char *s,
} else { } else {
obj->char_b = 1; obj->char_b = 1;
} }
END OBJ_THREAD(imap_messages, 0) END OBJ(imap_messages, 0)
if (arg) { if (arg) {
// proccss // proccss
obj->data.mail = parse_mail_args(IMAP_TYPE, arg); obj->data.mail = parse_mail_args(IMAP_TYPE, arg);
@ -2611,7 +2618,7 @@ static struct text_object *construct_text_object(const char *s,
} else { } else {
obj->char_b = 1; obj->char_b = 1;
} }
END OBJ_THREAD(pop3_unseen, 0) END OBJ(pop3_unseen, 0)
if (arg) { if (arg) {
// proccss // proccss
obj->data.mail = parse_mail_args(POP3_TYPE, arg); obj->data.mail = parse_mail_args(POP3_TYPE, arg);
@ -2619,7 +2626,7 @@ static struct text_object *construct_text_object(const char *s,
} else { } else {
obj->char_b = 1; obj->char_b = 1;
} }
END OBJ_THREAD(pop3_used, 0) END OBJ(pop3_used, 0)
if (arg) { if (arg) {
// proccss // proccss
obj->data.mail = parse_mail_args(POP3_TYPE, arg); obj->data.mail = parse_mail_args(POP3_TYPE, arg);
@ -2816,30 +2823,43 @@ static struct text_object *construct_text_object(const char *s,
CRIT_ERR(obj, free_at_crash, "eve needs arguments: <userid> <apikey> <characterid>"); CRIT_ERR(obj, free_at_crash, "eve needs arguments: <userid> <apikey> <characterid>");
} }
#endif #endif
#ifdef HAVE_CURL
END OBJ(curl, 0)
if (arg) {
int argc;
float interval;
char *uri = (char *) malloc(128 * sizeof(char));
argc = sscanf(arg, "%127s %f", uri, &interval);
obj->data.curl.uri = uri;
obj->data.curl.interval = interval > 0 ? interval * 60 : 15*60;
} else {
CRIT_ERR(obj, free_at_crash, "curl needs arguments: <uri> <interval in minutes>");
}
#endif
#ifdef RSS #ifdef RSS
END OBJ(rss, 0) END OBJ(rss, 0)
if (arg) { if (arg) {
int argc, delay, act_par; float interval;
int argc, act_par;
unsigned int nrspaces = 0; unsigned int nrspaces = 0;
char *uri = (char *) malloc(128 * sizeof(char)); char *uri = (char *) malloc(128 * sizeof(char));
char *action = (char *) malloc(64 * sizeof(char)); char *action = (char *) malloc(64 * sizeof(char));
argc = sscanf(arg, "%127s %d %63s %d %u", uri, &delay, action, argc = sscanf(arg, "%127s %f %63s %d %u", uri, &interval, action,
&act_par, &nrspaces); &act_par, &nrspaces);
obj->data.rss.uri = uri; obj->data.rss.uri = uri;
obj->data.rss.delay = delay; obj->data.rss.interval = interval > 0 ? interval * 60 : 15*60;
obj->data.rss.action = action; obj->data.rss.action = action;
obj->data.rss.act_par = act_par; obj->data.rss.act_par = act_par;
obj->data.rss.nrspaces = nrspaces; obj->data.rss.nrspaces = nrspaces;
init_rss_info();
} else { } else {
CRIT_ERR(obj, free_at_crash, "rss needs arguments: <uri> <delay in minutes> <action> " CRIT_ERR(obj, free_at_crash, "rss needs arguments: <uri> <interval in minutes> <action> "
"[act_par] [spaces in front]"); "[act_par] [spaces in front]");
} }
#endif #endif
#ifdef WEATHER #ifdef WEATHER
END OBJ_THREAD(weather, 0) END OBJ(weather, 0)
if (arg) { if (arg) {
int argc, interval; int argc, interval;
char *locID = (char *) malloc(9 * sizeof(char)); char *locID = (char *) malloc(9 * sizeof(char));
@ -2849,14 +2869,14 @@ static struct text_object *construct_text_object(const char *s,
argc = sscanf(arg, "%119s %8s %31s %d", uri, locID, data_type, &interval); argc = sscanf(arg, "%119s %8s %31s %d", uri, locID, data_type, &interval);
//locID MUST BE upper-case /* locID MUST BE upper-case */
tmp_p = locID; tmp_p = locID;
while (*tmp_p) { while (*tmp_p) {
*tmp_p = toupper(*tmp_p); *tmp_p = toupper(*tmp_p);
tmp_p++; tmp_p++;
} }
//Construct complete uri /* Construct complete uri */
if (strstr(uri, "xoap.weather.com")) { if (strstr(uri, "xoap.weather.com")) {
if(xoap != NULL) { if(xoap != NULL) {
strcat(uri, locID); strcat(uri, locID);
@ -2876,12 +2896,12 @@ static struct text_object *construct_text_object(const char *s,
obj->data.weather.uri = uri; obj->data.weather.uri = uri;
obj->data.weather.data_type = data_type; obj->data.weather.data_type = data_type;
//Limit the data retrieval interval to half hour min /* Limit the data retrieval interval to half hour min */
if (interval < 30) { if (interval < 30) {
interval = 30; interval = 30;
} }
//Convert to seconds /* Convert to seconds */
obj->data.weather.interval = interval * 60; obj->data.weather.interval = interval * 60;
free(locID); free(locID);
@ -2969,14 +2989,14 @@ static struct text_object *construct_text_object(const char *s,
END OBJ(blink, 0) END OBJ(blink, 0)
if(arg) { if(arg) {
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, arg, 0); extract_variable_text_internal(obj->sub, arg);
}else{ }else{
CRIT_ERR(obj, free_at_crash, "blink needs a argument"); CRIT_ERR(obj, free_at_crash, "blink needs a argument");
} }
END OBJ(to_bytes, 0) END OBJ(to_bytes, 0)
if(arg) { if(arg) {
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, arg, 0); extract_variable_text_internal(obj->sub, arg);
}else{ }else{
CRIT_ERR(obj, free_at_crash, "to_bytes needs a argument"); CRIT_ERR(obj, free_at_crash, "to_bytes needs a argument");
} }
@ -3001,7 +3021,7 @@ static struct text_object *construct_text_object(const char *s,
obj->data.scroll.start = 0; obj->data.scroll.start = 0;
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, extract_variable_text_internal(obj->sub,
obj->data.scroll.text, 0); obj->data.scroll.text);
} else { } else {
CRIT_ERR(obj, free_at_crash, "scroll needs arguments: <length> [<step>] <text>"); CRIT_ERR(obj, free_at_crash, "scroll needs arguments: <length> [<step>] <text>");
} }
@ -3045,9 +3065,9 @@ static struct text_object *construct_text_object(const char *s,
obj->data.combine.right[endvar[1] - startvar[1]] = 0; obj->data.combine.right[endvar[1] - startvar[1]] = 0;
obj->sub = malloc(sizeof(struct text_object)); obj->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub, obj->data.combine.left, 0); extract_variable_text_internal(obj->sub, obj->data.combine.left);
obj->sub->sub = malloc(sizeof(struct text_object)); obj->sub->sub = malloc(sizeof(struct text_object));
extract_variable_text_internal(obj->sub->sub, obj->data.combine.right, 0); extract_variable_text_internal(obj->sub->sub, obj->data.combine.right);
} else { } else {
CRIT_ERR(obj, free_at_crash, "combine needs arguments: <text1> <text2>"); CRIT_ERR(obj, free_at_crash, "combine needs arguments: <text1> <text2>");
} }
@ -3371,7 +3391,7 @@ static size_t remove_comments(char *string)
return folded; return folded;
} }
static int extract_variable_text_internal(struct text_object *retval, const char *const_p, char allow_threaded) static int extract_variable_text_internal(struct text_object *retval, const char *const_p)
{ {
struct text_object *obj; struct text_object *obj;
char *p, *s, *orig_p; char *p, *s, *orig_p;
@ -3490,8 +3510,7 @@ static int extract_variable_text_internal(struct text_object *retval, const char
} }
obj = construct_text_object(buf, arg, obj = construct_text_object(buf, arg,
line, allow_threaded, line, &ifblock_opaque, orig_p);
&ifblock_opaque, orig_p);
if (obj != NULL) { if (obj != NULL) {
append_object(retval, obj); append_object(retval, obj);
} }
@ -3543,12 +3562,12 @@ static void extract_variable_text(const char *p)
text_buffer = 0; text_buffer = 0;
} }
extract_variable_text_internal(&global_root_object, p, 1); extract_variable_text_internal(&global_root_object, p);
} }
void parse_conky_vars(struct text_object *root, char *txt, char *p, struct information *cur) void parse_conky_vars(struct text_object *root, char *txt, char *p, struct information *cur)
{ {
extract_variable_text_internal(root, txt, 0); extract_variable_text_internal(root, txt);
generate_text_internal(p, max_user_text, *root, cur); generate_text_internal(p, max_user_text, *root, cur);
return; return;
} }
@ -4439,8 +4458,10 @@ static void generate_text_internal(char *p, int p_max_size,
if (!obj->data.texeci.p_timed_thread) { if (!obj->data.texeci.p_timed_thread) {
ERR("Error creating texeci timed thread"); ERR("Error creating texeci timed thread");
} }
timed_thread_register(obj->data.texeci.p_timed_thread, /*
&obj->data.texeci.p_timed_thread); * note that we don't register this thread with the
* timed_thread list, because we destroy it manually
*/
if (timed_thread_run(obj->data.texeci.p_timed_thread)) { if (timed_thread_run(obj->data.texeci.p_timed_thread)) {
ERR("Error running texeci timed thread"); ERR("Error running texeci timed thread");
} }
@ -4631,87 +4652,30 @@ static void generate_text_internal(char *p, int p_max_size,
snprintf(p, p_max_size, "%s", skill); snprintf(p, p_max_size, "%s", skill);
} }
#endif #endif
#ifdef HAVE_CURL
OBJ(curl) {
if (obj->data.curl.uri != NULL) {
ccurl_process_info(p, p_max_size, obj->data.curl.uri, obj->data.curl.interval);
} else {
ERR("error processing Curl data");
}
}
#endif
#ifdef RSS #ifdef RSS
OBJ(rss) { OBJ(rss) {
PRSS *data = get_rss_info(obj->data.rss.uri, if (obj->data.rss.uri != NULL) {
obj->data.rss.delay); rss_process_info(p, p_max_size, obj->data.rss.uri, obj->data.rss.action, obj->data.rss.act_par, obj->data.rss.interval, obj->data.rss.nrspaces);
char *str;
if (data == NULL) {
snprintf(p, p_max_size, "prss: Error reading RSS data\n");
} else { } else {
if (strcmp(obj->data.rss.action, "feed_title") == EQUAL) { ERR("error processing RSS data");
str = data->title;
// 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(obj->data.rss.action, "item_title") == EQUAL) {
if (obj->data.rss.act_par < data->item_count) {
str = data->items[obj->data.rss.act_par].title;
// 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(obj->data.rss.action, "item_desc") == EQUAL) {
if (obj->data.rss.act_par < data->item_count) {
str =
data->items[obj->data.rss.act_par].description;
// 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(obj->data.rss.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(obj->data.rss.nrspaces + 1);
memset(tmpspaces, ' ', obj->data.rss.nrspaces);
tmpspaces[obj->data.rss.nrspaces]=0;
p[0] = 0;
if (obj->data.rss.act_par > data->item_count) {
show = data->item_count;
} else {
show = obj->data.rss.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 (str[strlen(str) - 1] == '\n') {
str[strlen(str) - 1] = 0;
}
strncat(p, tmpspaces, p_max_size);
strncat(p, str, p_max_size);
}
}
free(tmpspaces);
}
}
} }
} }
#endif #endif
#ifdef WEATHER #ifdef WEATHER
OBJ(weather) { OBJ(weather) {
if( obj->data.weather.uri != NULL ) { if (obj->data.weather.uri != NULL) {
process_weather_info(p, p_max_size, obj->data.weather.uri, obj->data.weather.data_type, obj->data.weather.interval); weather_process_info(p, p_max_size, obj->data.weather.uri, obj->data.weather.data_type, obj->data.weather.interval);
} else { } else {
strncpy(p, "either invalid xoap keys file or compiled without xoap support", p_max_size); ERR("error processing weather data, check that you have a valid XOAP key if using XOAP.");
} }
} }
#endif #endif
@ -7636,11 +7600,14 @@ void clean_up(void *memtofree1, void* memtofree2)
#ifdef TCP_PORT_MONITOR #ifdef TCP_PORT_MONITOR
tcp_portmon_clear(); tcp_portmon_clear();
#endif #endif
#ifdef HAVE_CURL
ccurl_free_info();
#endif
#ifdef RSS #ifdef RSS
free_rss_info(); rss_free_info();
#endif #endif
#ifdef WEATHER #ifdef WEATHER
free_weather_info(); weather_free_info();
#endif #endif
#ifdef HAVE_LUA #ifdef HAVE_LUA
llua_close(); llua_close();

View File

@ -87,17 +87,21 @@ char *strndup(const char *s, size_t n);
#include "nvidia.h" #include "nvidia.h"
#endif #endif
#ifdef HAVE_CURL
#include "ccurl_thread.h"
#endif /* HAVE_CURL */
#ifdef RSS #ifdef RSS
#include "rss.h" #include "rss.h"
#endif #endif /* RSS */
#ifdef WEATHER #ifdef WEATHER
#include "weather.h" #include "weather.h"
#endif #endif /* WEATHER */
#ifdef HAVE_LUA #ifdef HAVE_LUA
#include "llua.h" #include "llua.h"
#endif #endif /* HAVE_LUA */
#ifdef TCP_PORT_MONITOR #ifdef TCP_PORT_MONITOR
#include "tcp-portmon.h" #include "tcp-portmon.h"
@ -196,9 +200,6 @@ enum {
INFO_XMMS2 = 22, INFO_XMMS2 = 22,
#endif #endif
INFO_ENTROPY = 23, INFO_ENTROPY = 23,
#ifdef RSS
INFO_RSS = 24,
#endif
#ifdef IBM #ifdef IBM
INFO_SMAPI = 25, INFO_SMAPI = 25,
#endif #endif

View File

@ -24,29 +24,19 @@
#define PARSE_OPTIONS 0 #define PARSE_OPTIONS 0
#endif #endif
PRSS *prss_parse_doc(xmlDocPtr doc); void prss_parse_doc(PRSS *result, xmlDocPtr doc);
PRSS *prss_parse_data(const char *xml_data) void prss_parse_data(void *result, const char *xml_data)
{ {
PRSS *data = (PRSS*)result;
xmlDocPtr doc = xmlReadMemory(xml_data, strlen(xml_data), "", NULL, xmlDocPtr doc = xmlReadMemory(xml_data, strlen(xml_data), "", NULL,
PARSE_OPTIONS); PARSE_OPTIONS);
if (!doc) { if (!doc) {
return NULL; return;
} }
return prss_parse_doc(doc); prss_parse_doc(data, doc);
}
PRSS *prss_parse_file(const char *xml_file)
{
xmlDocPtr doc = xmlReadFile(xml_file, NULL, PARSE_OPTIONS);
if (!doc) {
return NULL;
}
return prss_parse_doc(doc);
} }
void prss_free(PRSS *data) void prss_free(PRSS *data)
@ -57,7 +47,6 @@ void prss_free(PRSS *data)
xmlFreeDoc(data->_data); xmlFreeDoc(data->_data);
free(data->version); free(data->version);
free(data->items); free(data->items);
free(data);
} }
static inline void prss_null(PRSS *p) static inline void prss_null(PRSS *p)
@ -169,6 +158,7 @@ static inline int parse_rss_2_0(PRSS *res, xmlNodePtr root)
} }
res->version = strndup("2.0", text_buffer_size); res->version = strndup("2.0", text_buffer_size);
if (res->items) free(res->items);
res->items = malloc(items * sizeof(PRSS_Item)); res->items = malloc(items * sizeof(PRSS_Item));
res->item_count = 0; res->item_count = 0;
@ -198,6 +188,7 @@ static inline int parse_rss_1_0(PRSS *res, xmlNodePtr root)
} }
res->version = strndup("1.0", text_buffer_size); res->version = strndup("1.0", text_buffer_size);
if (res->items) free(res->items);
res->items = malloc(items * sizeof(PRSS_Item)); res->items = malloc(items * sizeof(PRSS_Item));
res->item_count = 0; res->item_count = 0;
@ -216,13 +207,12 @@ static inline int parse_rss_0_9x(PRSS *res, xmlNodePtr root)
return parse_rss_2_0(res, root); return parse_rss_2_0(res, root);
} }
PRSS *prss_parse_doc(xmlDocPtr doc) void prss_parse_doc(PRSS *result, xmlDocPtr doc)
{ {
/* FIXME: doc shouldn't be freed after failure when called explicitly from /* FIXME: doc shouldn't be freed after failure when called explicitly from
* program! */ * program! */
xmlNodePtr root = xmlDocGetRootElement(doc); xmlNodePtr root = xmlDocGetRootElement(doc);
PRSS *result = malloc(sizeof(PRSS));
prss_null(result); prss_null(result);
result->_data = doc; result->_data = doc;
@ -230,24 +220,15 @@ PRSS *prss_parse_doc(xmlDocPtr doc)
if (root->type == XML_ELEMENT_NODE) { if (root->type == XML_ELEMENT_NODE) {
if (!strcmp((const char *) root->name, "RDF")) { if (!strcmp((const char *) root->name, "RDF")) {
// RSS 1.0 document // RSS 1.0 document
if (!parse_rss_1_0(result, root)) { parse_rss_1_0(result, root);
free(result); return;
xmlFreeDoc(doc);
return NULL;
}
return result;
} else if (!strcmp((const char *) root->name, "rss")) { } else if (!strcmp((const char *) root->name, "rss")) {
// RSS 2.0 or <1.0 document // RSS 2.0 or <1.0 document
if (!parse_rss_2_0(result, root)) { parse_rss_2_0(result, root);
free(result); return;
xmlFreeDoc(doc);
return NULL;
}
return result;
} }
} }
root = root->next; root = root->next;
} while (root); } while (root);
free(result); return;
return NULL;
} }

View File

@ -51,8 +51,7 @@ typedef struct PRSS_ {
} PRSS; } PRSS;
/* Functions for parsing RSS-data */ /* Functions for parsing RSS-data */
PRSS *prss_parse_data(const char *xml_data); void prss_parse_data(void *result, const char *xml_data);
PRSS *prss_parse_file(const char *xml_file);
/* // Works wrong currently when called from application! /* // Works wrong currently when called from application!
PRSS *prss_parse_doc(xmlDocPtr doc); */ PRSS *prss_parse_doc(xmlDocPtr doc); */

207
src/rss.c
View File

@ -24,137 +24,110 @@
#include "conky.h" #include "conky.h"
#include "logging.h" #include "logging.h"
#include "prss.h" #include "prss.h"
#include "ccurl_thread.h"
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#define MAX_FEEDS 16 static ccurl_location_t *locations_head = 0;
typedef struct feed_ { void rss_free_info(void)
char *uri; {
int last_update; ccurl_location_t *tail = locations_head;
while (tail) {
if (tail->result) prss_free((PRSS*)tail->result); /* clean up old data */
tail = tail->next;
}
ccurl_free_locations(&locations_head);
}
void rss_process_info(char *p, int p_max_size, char *uri, char *action, int
act_par, int interval, unsigned int nrspaces)
{
PRSS *data; PRSS *data;
} feed; char *str;
int num_feeds = 0; ccurl_location_t *curloc = ccurl_find_location(&locations_head, uri);
feed feeds[MAX_FEEDS]; if (!curloc->p_timed_thread) {
curloc->result = malloc(sizeof(PRSS));
int rss_delay(int *wait_time, int delay) memset(curloc->result, 0, sizeof(PRSS));
{ curloc->process_function = &prss_parse_data;
time_t now = time(NULL); ccurl_init_thread(curloc, interval);
if (!curloc->p_timed_thread) {
// make it minutes ERR("error setting up weather thread");
if (delay < 1) {
delay = 1;
}
delay *= 60;
if (!*wait_time) {
*wait_time = now + delay;
return 1;
}
if (now >= *wait_time + delay) {
*wait_time = now + delay;
return 1;
}
return 0;
}
void init_rss_info(void)
{
int i;
for (i = 0; i < MAX_FEEDS; i++) {
feeds[i].uri = NULL;
feeds[i].data = NULL;
feeds[i].last_update = 0;
}
}
void free_rss_info(void)
{
int i;
for (i = 0; i < num_feeds; i++) {
if (feeds[i].uri != NULL) {
free(feeds[i].uri);
} }
} }
}
PRSS *get_rss_info(char *uri, int delay) timed_thread_lock(curloc->p_timed_thread);
{ data = (PRSS*)curloc->result;
CURL *curl = NULL;
CURLcode res;
// pointers to struct if (data == NULL) {
feed *curfeed = NULL; snprintf(p, p_max_size, "prss: Error reading RSS data\n");
PRSS *curdata = NULL; } else {
int *last_update = 0; if (strcmp(action, "feed_title") == EQUAL) {
str = data->title;
// 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) - 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) - 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;
int i; p[0] = 0;
// curl temps if (act_par > data->item_count) {
struct MemoryStruct chunk; show = data->item_count;
} else {
show = act_par;
}
for (itmp = 0; itmp < show; itmp++) {
PRSS_Item *item = &data->items[itmp];
chunk.memory = NULL; str = item->title;
chunk.size = 0; if (str) {
// don't add new line before first item
// first seek for the uri in list if (itmp > 0) {
for (i = 0; i < num_feeds; i++) { strncat(p, "\n", p_max_size);
if (feeds[i].uri != NULL) { }
if (!strcmp(feeds[i].uri, uri)) { /* remove trailing new line if one exists,
curfeed = &feeds[i]; * we have our own */
break; if (str[strlen(str) - 1] == '\n') {
str[strlen(str) - 1] = 0;
}
strncat(p, tmpspaces, p_max_size);
strncat(p, str, p_max_size);
}
}
free(tmpspaces);
} }
} }
} }
timed_thread_unlock(curloc->p_timed_thread);
if (!curfeed) { // new feed
if (num_feeds == MAX_FEEDS - 1) {
return NULL;
}
curfeed = &feeds[num_feeds];
curfeed->uri = strndup(uri, text_buffer_size);
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;
}
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 (res == CURLE_OK && chunk.size) {
curdata = prss_parse_data(chunk.memory);
free(chunk.memory);
} else {
ERR("No data from server");
}
curl_easy_cleanup(curl);
}
curfeed->data = curdata;
return curdata;
} }

View File

@ -3,8 +3,8 @@
#include "prss.h" #include "prss.h"
PRSS *get_rss_info(char *uri, int delay); void rss_free_info(void);
void init_rss_info(void); void rss_process_info(char *p, int p_max_size, char *uri, char *action, int
void free_rss_info(void); act_par, int interval, unsigned int nrspaces);
#endif /*RSS_H_*/ #endif /*RSS_H_*/

View File

@ -375,6 +375,9 @@ enum text_object_type {
#ifdef EVE #ifdef EVE
OBJ_eve, OBJ_eve,
#endif /* EVE */ #endif /* EVE */
#ifdef HAVE_CURL
OBJ_curl,
#endif /* HAVE_CURL */
#ifdef RSS #ifdef RSS
OBJ_rss, OBJ_rss,
#endif /* RSS */ #endif /* RSS */
@ -538,22 +541,26 @@ struct text_object {
char *userid; char *userid;
} eve; } eve;
#endif #endif
#ifdef HAVE_CURL
struct {
char *uri;
float interval;
} curl;
#endif
#ifdef RSS #ifdef RSS
struct { struct {
char *uri; char *uri;
char *action; char *action;
int act_par; int act_par;
int delay; float interval;
unsigned int nrspaces; unsigned int nrspaces;
timed_thread *p_timed_thread;
} rss; } rss;
#endif #endif
#ifdef WEATHER #ifdef WEATHER
struct { struct {
char *uri; char *uri;
char *data_type; char *data_type;
int interval; int interval;
timed_thread *p_timed_thread;
} weather; } weather;
#endif #endif
struct { struct {

View File

@ -30,14 +30,12 @@
#include "logging.h" #include "logging.h"
#include "weather.h" #include "weather.h"
#include "temphelper.h" #include "temphelper.h"
#include "ccurl_thread.h"
#include <time.h> #include <time.h>
#include <ctype.h> #include <ctype.h>
#ifdef MATH #ifdef MATH
#include <math.h> #include <math.h>
#endif /* MATH */ #endif /* MATH */
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#ifdef XOAP #ifdef XOAP
#include <libxml/parser.h> #include <libxml/parser.h>
#endif /* XOAP */ #endif /* XOAP */
@ -63,57 +61,11 @@ const char *WC_CODES[NUM_WC_CODES] = {
"FC", "PO", "SQ", "SS", "DS" "FC", "PO", "SQ", "SS", "DS"
}; };
typedef struct location_ { static ccurl_location_t *locations_head = 0;
char *uri;
int last_update;
PWEATHER data;
timed_thread *p_timed_thread;
struct location_ *next;
} location;
static location *locations_head = 0; void weather_free_info(void)
location *find_location(char *uri)
{ {
location *tail = locations_head; ccurl_free_locations(&locations_head);
location *new = 0;
while (tail) {
if (tail->uri &&
strcmp(tail->uri, uri) == EQUAL) {
return tail;
}
tail = tail->next;
}
if (!tail) { // new location!!!!!!!
new = malloc(sizeof(location));
memset(new, 0, sizeof(location));
new->uri = strndup(uri, text_buffer_size);
tail = locations_head;
while (tail && tail->next) {
tail = tail->next;
}
if (!tail) {
// omg the first one!!!!!!!
locations_head = new;
} else {
tail->next = new;
}
}
return new;
}
void free_weather_info(void)
{
location *tail = locations_head;
location *last = 0;
while (tail) {
if (tail->uri) free(tail->uri);
last = tail;
tail = tail->next;
free(last);
}
locations_head = 0;
} }
int rel_humidity(int dew_point, int air) { int rel_humidity(int dew_point, int air) {
@ -489,9 +441,10 @@ static inline void parse_token(PWEATHER *res, char *token) {
} }
} }
static void parse_weather(PWEATHER *res, const char *data) void parse_weather(void *result, const char *data)
{ {
//Reset results PWEATHER *res = (PWEATHER*)result;
/* Reset results */
memset(res, 0, sizeof(PWEATHER)); memset(res, 0, sizeof(PWEATHER));
#ifdef XOAP #ifdef XOAP
@ -532,60 +485,7 @@ static void parse_weather(PWEATHER *res, const char *data)
} }
} }
void fetch_weather_info(location *curloc) void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, int interval)
{
CURL *curl = NULL;
CURLcode res;
// curl temps
struct MemoryStruct chunk;
chunk.memory = NULL;
chunk.size = 0;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, curloc->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-weather/1.0");
res = curl_easy_perform(curl);
if (res == CURLE_OK && chunk.size) {
timed_thread_lock(curloc->p_timed_thread);
parse_weather(&curloc->data, chunk.memory);
timed_thread_unlock(curloc->p_timed_thread);
free(chunk.memory);
} else {
ERR("weather: no data from server");
}
curl_easy_cleanup(curl);
}
return;
}
void *weather_thread(void *) __attribute__((noreturn));
void init_thread(location *curloc, int interval)
{
curloc->p_timed_thread =
timed_thread_create(&weather_thread,
(void *)curloc, interval * 1000000);
if (!curloc->p_timed_thread) {
ERR("weather: error creating timed thread");
}
timed_thread_register(curloc->p_timed_thread,
&curloc->p_timed_thread);
if (timed_thread_run(curloc->p_timed_thread)) {
ERR("weather: error running timed thread");
}
}
void process_weather_info(char *p, int p_max_size, char *uri, char *data_type, int interval)
{ {
static const char *wc[] = { static const char *wc[] = {
"", "drizzle", "rain", "hail", "soft hail", "", "drizzle", "rain", "hail", "soft hail",
@ -593,96 +493,93 @@ void process_weather_info(char *p, int p_max_size, char *uri, char *data_type, i
"mist", "dust", "sand", "funnel cloud tornado", "mist", "dust", "sand", "funnel cloud tornado",
"dust/sand", "squall", "sand storm", "dust storm" "dust/sand", "squall", "sand storm", "dust storm"
}; };
PWEATHER *data;
location *curloc = find_location(uri); ccurl_location_t *curloc = ccurl_find_location(&locations_head, uri);
if (!curloc->p_timed_thread) init_thread(curloc, interval); if (!curloc->p_timed_thread) {
curloc->result = malloc(sizeof(PWEATHER));
memset(curloc->result, 0, sizeof(PWEATHER));
curloc->process_function = &parse_weather;
ccurl_init_thread(curloc, interval);
if (!curloc->p_timed_thread) {
ERR("error setting up weather thread");
}
}
timed_thread_lock(curloc->p_timed_thread); timed_thread_lock(curloc->p_timed_thread);
data = (PWEATHER*)curloc->result;
if (strcmp(data_type, "last_update") == EQUAL) { if (strcmp(data_type, "last_update") == EQUAL) {
strncpy(p, curloc->data.lastupd, p_max_size); strncpy(p, data->lastupd, p_max_size);
} else if (strcmp(data_type, "temperature") == EQUAL) { } else if (strcmp(data_type, "temperature") == EQUAL) {
temp_print(p, p_max_size, curloc->data.temp, TEMP_CELSIUS); temp_print(p, p_max_size, data->temp, TEMP_CELSIUS);
} else if (strcmp(data_type, "cloud_cover") == EQUAL) { } else if (strcmp(data_type, "cloud_cover") == EQUAL) {
#ifdef XOAP #ifdef XOAP
if (curloc->data.xoap_t[0] != '\0') { if (data->xoap_t[0] != '\0') {
strncpy(p, curloc->data.xoap_t, p_max_size); strncpy(p, data->xoap_t, p_max_size);
} else } else
#endif /* XOAP */ #endif /* XOAP */
if (curloc->data.cc == 0) { if (data->cc == 0) {
strncpy(p, "", p_max_size); strncpy(p, "", p_max_size);
} else if (curloc->data.cc < 3) { } else if (data->cc < 3) {
strncpy(p, "clear", p_max_size); strncpy(p, "clear", p_max_size);
} else if (curloc->data.cc < 5) { } else if (data->cc < 5) {
strncpy(p, "partly cloudy", p_max_size); strncpy(p, "partly cloudy", p_max_size);
} else if (curloc->data.cc == 5) { } else if (data->cc == 5) {
strncpy(p, "cloudy", p_max_size); strncpy(p, "cloudy", p_max_size);
} else if (curloc->data.cc == 6) { } else if (data->cc == 6) {
strncpy(p, "overcast", p_max_size); strncpy(p, "overcast", p_max_size);
} else if (curloc->data.cc == 7) { } else if (data->cc == 7) {
strncpy(p, "towering cumulus", p_max_size); strncpy(p, "towering cumulus", p_max_size);
} else { } else {
strncpy(p, "cumulonimbus", p_max_size); strncpy(p, "cumulonimbus", p_max_size);
} }
} else if (strcmp(data_type, "pressure") == EQUAL) { } else if (strcmp(data_type, "pressure") == EQUAL) {
snprintf(p, p_max_size, "%d", curloc->data.bar); snprintf(p, p_max_size, "%d", data->bar);
} else if (strcmp(data_type, "wind_speed") == EQUAL) { } else if (strcmp(data_type, "wind_speed") == EQUAL) {
snprintf(p, p_max_size, "%d", curloc->data.wind_s); snprintf(p, p_max_size, "%d", data->wind_s);
} else if (strcmp(data_type, "wind_dir") == EQUAL) { } else if (strcmp(data_type, "wind_dir") == EQUAL) {
if ((curloc->data.wind_d >= 349) || (curloc->data.wind_d < 12)) { if ((data->wind_d >= 349) || (data->wind_d < 12)) {
strncpy(p, "N", p_max_size); strncpy(p, "N", p_max_size);
} else if (curloc->data.wind_d < 33) { } else if (data->wind_d < 33) {
strncpy(p, "NNE", p_max_size); strncpy(p, "NNE", p_max_size);
} else if (curloc->data.wind_d < 57) { } else if (data->wind_d < 57) {
strncpy(p, "NE", p_max_size); strncpy(p, "NE", p_max_size);
} else if (curloc->data.wind_d < 79) { } else if (data->wind_d < 79) {
strncpy(p, "ENE", p_max_size); strncpy(p, "ENE", p_max_size);
} else if (curloc->data.wind_d < 102) { } else if (data->wind_d < 102) {
strncpy(p, "E", p_max_size); strncpy(p, "E", p_max_size);
} else if (curloc->data.wind_d < 124) { } else if (data->wind_d < 124) {
strncpy(p, "ESE", p_max_size); strncpy(p, "ESE", p_max_size);
} else if (curloc->data.wind_d < 147) { } else if (data->wind_d < 147) {
strncpy(p, "SE", p_max_size); strncpy(p, "SE", p_max_size);
} else if (curloc->data.wind_d < 169) { } else if (data->wind_d < 169) {
strncpy(p, "SSE", p_max_size); strncpy(p, "SSE", p_max_size);
} else if (curloc->data.wind_d < 192) { } else if (data->wind_d < 192) {
strncpy(p, "S", p_max_size); strncpy(p, "S", p_max_size);
} else if (curloc->data.wind_d < 214) { } else if (data->wind_d < 214) {
strncpy(p, "SSW", p_max_size); strncpy(p, "SSW", p_max_size);
} else if (curloc->data.wind_d < 237) { } else if (data->wind_d < 237) {
strncpy(p, "SW", p_max_size); strncpy(p, "SW", p_max_size);
} else if (curloc->data.wind_d < 259) { } else if (data->wind_d < 259) {
strncpy(p, "WSW", p_max_size); strncpy(p, "WSW", p_max_size);
} else if (curloc->data.wind_d < 282) { } else if (data->wind_d < 282) {
strncpy(p, "W", p_max_size); strncpy(p, "W", p_max_size);
} else if (curloc->data.wind_d < 304) { } else if (data->wind_d < 304) {
strncpy(p, "WNW", p_max_size); strncpy(p, "WNW", p_max_size);
} else if (curloc->data.wind_d < 327) { } else if (data->wind_d < 327) {
strncpy(p, "NW", p_max_size); strncpy(p, "NW", p_max_size);
} else if (curloc->data.wind_d < 349) { } else if (data->wind_d < 349) {
strncpy(p, "NNW", p_max_size); strncpy(p, "NNW", p_max_size);
}; };
} else if (strcmp(data_type, "wind_dir_DEG") == EQUAL) { } else if (strcmp(data_type, "wind_dir_DEG") == EQUAL) {
snprintf(p, p_max_size, "%d", curloc->data.wind_d); snprintf(p, p_max_size, "%d", data->wind_d);
} else if (strcmp(data_type, "humidity") == EQUAL) { } else if (strcmp(data_type, "humidity") == EQUAL) {
snprintf(p, p_max_size, "%d", curloc->data.hmid); snprintf(p, p_max_size, "%d", data->hmid);
} else if (strcmp(data_type, "weather") == EQUAL) { } else if (strcmp(data_type, "weather") == EQUAL) {
strncpy(p, wc[curloc->data.wc], p_max_size); strncpy(p, wc[data->wc], p_max_size);
} }
timed_thread_unlock(curloc->p_timed_thread); timed_thread_unlock(curloc->p_timed_thread);
} }
void *weather_thread(void *arg)
{
location *curloc = (location*)arg;
while (1) {
fetch_weather_info(curloc);
if (timed_thread_test(curloc->p_timed_thread, 0)) {
timed_thread_exit(curloc->p_timed_thread);
}
}
/* never reached */
}

View File

@ -55,8 +55,7 @@ typedef struct PWEATHER_ {
} PWEATHER; } PWEATHER;
/* Prototypes */ /* Prototypes */
void init_weather_info(void); void weather_free_info(void);
void free_weather_info(void); void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, int interval);
void process_weather_info(char *p, int p_max_size, char *uri, char *data_type, int interval);
#endif /*WEATHER_H_*/ #endif /*WEATHER_H_*/