mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-17 18:45:10 +00:00
Undid last 3 commits, see rest of the comment for the reason:
I am not really comfortable with adding support to the conky-code for sites that only work when you register, that's more something for in a script. But the biggest reason I undid the commits is that it is now impossible to compile conky with support for weather if you don't have the xml libs installed. Users used to be able to compile with support for weather (using the other site) without xml2. If you really want to include this other site in the conky code then split WEATHER in WEATHERCOM and WEATHERNOAA (altough my personal opinion is that weather.com should only be supported with scripts)
This commit is contained in:
parent
7b38e810f2
commit
d872562942
@ -1,6 +1,3 @@
|
||||
2009-07-18
|
||||
* www.weather.com can now be used as well as a source of weather data
|
||||
|
||||
2009-07-11
|
||||
* Added support for $desktop, $desktop_number and $desktop_name (sf.net #2040528)
|
||||
|
||||
|
@ -356,10 +356,9 @@ AC_ARG_ENABLE([weather],
|
||||
#
|
||||
AM_CONDITIONAL(BUILD_WEATHER, test x$want_weather = xyes)
|
||||
if test x$want_weather = xyes; then
|
||||
PKG_CHECK_MODULES([libxml2], libxml-2.0)
|
||||
PKG_CHECK_MODULES([libcurl], libcurl)
|
||||
conky_CFLAGS="$conky_CFLAGS $libxml2_CFLAGS $libcurl_CFLAGS"
|
||||
conky_LIBS="$conky_LIBS $libxml2_LIBS $libcurl_LIBS"
|
||||
conky_CFLAGS="$conky_CFLAGS $libcurl_CFLAGS"
|
||||
conky_LIBS="$conky_LIBS $libcurl_LIBS"
|
||||
AC_DEFINE(WEATHER, 1, [Define if you want weather support])
|
||||
fi
|
||||
|
||||
@ -707,7 +706,6 @@ dnl
|
||||
|
||||
AC_DEFINE(DEFAULTNETDEV, "eth0", [Default networkdevice])
|
||||
AC_DEFINE(CONFIG_FILE, "$HOME/.conkyrc", [Configfile of the user])
|
||||
AC_DEFINE(XOAP_FILE, "$HOME/.xoaprc", [User xoap keys file])
|
||||
AC_DEFINE(MAX_SPECIALS_DEFAULT, 512, [Default maximum number of special things, e.g. fonts, offsets, aligns, etc.])
|
||||
AC_DEFINE(MAX_USER_TEXT_DEFAULT, 16384, [Default maximum size of config TEXT buffer, i.e. below TEXT line.])
|
||||
AC_DEFINE(DEFAULT_TEXT_BUFFER_SIZE, 256, [Default size used for temporary, static text buffers])
|
||||
|
@ -3290,40 +3290,23 @@
|
||||
<command>
|
||||
<option>weather</option>
|
||||
</command>
|
||||
<option>URI locID data_type (delay_in_minutes)</option>
|
||||
<option>URI icao data_type (delay_in_minutes)</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Download, parse and display METAR data.</para>
|
||||
<para>For the 'URI', there are two possibilities:</para>
|
||||
<simplelist>
|
||||
<member>
|
||||
http://weather.noaa.gov/pub/data/observations/metar/stations/
|
||||
</member>
|
||||
<member>
|
||||
http://xoap.weather.com/weather/local/
|
||||
</member>
|
||||
</simplelist>
|
||||
<para>The first one is free to use but the second requires you to
|
||||
register and obtain your partner ID and license key.
|
||||
These two must be written, separated by a space, into a file
|
||||
called .xoaprc which needs to be placed into your home directory.
|
||||
<para>For the 'URI', right now only
|
||||
http://weather.noaa.gov/pub/data/observations/metar/stations/
|
||||
is supported. Other sources might be supported in the future.
|
||||
</para>
|
||||
<para>'locID' must be a valid location identifier for the required
|
||||
uri. For the NOAA site this must be a valid ICAO
|
||||
<para>'icao' must be a valid icao for the required location
|
||||
(see for instance https://pilotweb.nas.faa.gov/qryhtml/icao/).
|
||||
For the weather.com site this must be a valid location ID
|
||||
(see for instance http://aspnetresources.com/tools/locid.aspx).
|
||||
</para>
|
||||
<para>'data_type' must be one of the following:</para>
|
||||
<simplelist>
|
||||
<member>
|
||||
<command>last_update</command>
|
||||
<option>The date and time stamp of the data.
|
||||
The result depends on the URI used. For the NOAA site
|
||||
it is date (yyyy/mm/dd) and UTC time. For the
|
||||
weather.com one it is date ([m]m/[d]d/yy) and Local Time
|
||||
of the station.
|
||||
</option>
|
||||
<option>The date (yyyy/mm/dd) and time (UTC) of
|
||||
the last update</option>
|
||||
</member>
|
||||
<member>
|
||||
<command>temperature</command>
|
||||
@ -3336,7 +3319,7 @@
|
||||
<option>The highest cloud cover status</option>
|
||||
</member>
|
||||
<member>
|
||||
<command>pressure</command>
|
||||
<command>pressurer</command>
|
||||
<option>Air pressure in millibar</option>
|
||||
</member>
|
||||
<member>
|
||||
@ -3358,9 +3341,7 @@
|
||||
<member>
|
||||
<command>weather</command>
|
||||
<option>Any relevant weather event (rain, snow,
|
||||
etc.). This is not used if you are querying the
|
||||
weather.com site since this data is aggregated
|
||||
into the cloud_cover one</option>
|
||||
etc.))</option>
|
||||
</member>
|
||||
</simplelist>
|
||||
<para>'delay_in_minutes' (optional, default 30) cannot be
|
||||
|
97
src/conky.c
97
src/conky.c
@ -318,11 +318,6 @@ static int cpu_avg_samples, net_avg_samples, diskio_avg_samples;
|
||||
char *overwrite_file = NULL; FILE *overwrite_fpointer = NULL;
|
||||
char *append_file = NULL; FILE *append_fpointer = NULL;
|
||||
|
||||
/* xoap suffix for weather from weather.com */
|
||||
#ifdef WEATHER
|
||||
static char *xoap = NULL;
|
||||
#endif /* WEATHER */
|
||||
|
||||
#ifdef X11
|
||||
|
||||
static int show_graph_scale;
|
||||
@ -2825,53 +2820,35 @@ static struct text_object *construct_text_object(const char *s,
|
||||
END OBJ_THREAD(weather, 0)
|
||||
if (arg) {
|
||||
int argc, interval;
|
||||
char *locID = (char *) malloc(9 * sizeof(char));
|
||||
char *icao = (char *) malloc(5 * sizeof(char));
|
||||
char *uri = (char *) malloc(128 * sizeof(char));
|
||||
char *data_type = (char *) malloc(32 * sizeof(char));
|
||||
char *tmp_p;
|
||||
|
||||
argc = sscanf(arg, "%119s %8s %31s %d", uri, locID, data_type, &interval);
|
||||
argc = sscanf(arg, "%119s %4s %31s %d", uri, icao, data_type, &interval);
|
||||
|
||||
//locID MUST BE upper-case
|
||||
tmp_p = locID;
|
||||
//icao MUST BE upper-case
|
||||
tmp_p = icao;
|
||||
while (*tmp_p) {
|
||||
*tmp_p = toupper(*tmp_p);
|
||||
tmp_p++;
|
||||
*tmp_p = toupper(*tmp_p);
|
||||
tmp_p++;
|
||||
}
|
||||
|
||||
//Construct complete uri
|
||||
if (strstr(uri, "xoap.weather.com")) {
|
||||
if(xoap != NULL) {
|
||||
strcat(uri, locID);
|
||||
strcat(uri, xoap);
|
||||
} else {
|
||||
free(uri);
|
||||
uri = NULL;
|
||||
}
|
||||
} else if (strstr(uri, "weather.noaa.gov")) {
|
||||
strcat(uri, locID);
|
||||
strcat(uri, ".TXT");
|
||||
} else if (!strstr(uri, "localhost") && !strstr(uri, "127.0.0.1")) {
|
||||
CRIT_ERR(obj, free_at_crash, \
|
||||
"could not recognize the weather uri");
|
||||
}
|
||||
|
||||
strcat(uri, icao);
|
||||
strcat(uri, ".TXT");
|
||||
obj->data.weather.uri = uri;
|
||||
|
||||
obj->data.weather.data_type = data_type;
|
||||
|
||||
//Limit the data retrieval interval to half hour min
|
||||
// The data retrieval interval is limited to half an hour
|
||||
if (interval < 30) {
|
||||
interval = 30;
|
||||
}
|
||||
|
||||
//Convert to seconds
|
||||
obj->data.weather.interval = interval * 60;
|
||||
free(locID);
|
||||
|
||||
DBGP("weather: fetching %s from %s every %d seconds", \
|
||||
data_type, uri, obj->data.weather.interval);
|
||||
obj->data.weather.interval = interval * 60; // convert to seconds
|
||||
free(icao);
|
||||
} else {
|
||||
CRIT_ERR(obj, free_at_crash, "weather needs arguments: <uri> <locID> <data_type> [interval in minutes]");
|
||||
CRIT_ERR(obj, free_at_crash, "weather needs arguments: <uri> <icao> <data_type> [interval in minutes]");
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LUA
|
||||
@ -4670,11 +4647,7 @@ static void generate_text_internal(char *p, int p_max_size,
|
||||
#endif
|
||||
#ifdef WEATHER
|
||||
OBJ(weather) {
|
||||
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);
|
||||
} else {
|
||||
strncpy(p, "invalid xoap keys file", p_max_size);
|
||||
}
|
||||
process_weather_info(p, p_max_size, obj->data.weather.uri, obj->data.weather.data_type, obj->data.weather.interval);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LUA
|
||||
@ -8912,42 +8885,6 @@ static void load_config_file_x11(const char *f)
|
||||
}
|
||||
#endif /* X11 */
|
||||
|
||||
#ifdef WEATHER
|
||||
/*
|
||||
* TODO: make the xoap keys file readable from the config file
|
||||
* make the keys directly readable from the config file
|
||||
* make the xoap keys file giveable as a command line option
|
||||
*/
|
||||
static void load_xoap_keys(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char *par = (char *) malloc(11 * sizeof(char));
|
||||
char *key = (char *) malloc(17 * sizeof(char));
|
||||
|
||||
xoap = (char *) malloc(64 * sizeof(char));
|
||||
to_real_path(xoap, XOAP_FILE);
|
||||
fp = fopen(xoap, "r");
|
||||
if (fp != NULL) {
|
||||
if( fscanf(fp, "%10s %16s", par, key) == 2 ) {
|
||||
strcpy(xoap, "?cc=*&link=xoap&prod=xoap&par=");
|
||||
strcat(xoap, par);
|
||||
strcat(xoap, "&key=");
|
||||
strcat(xoap, key);
|
||||
strcat(xoap, "&unit=m");
|
||||
} else {
|
||||
free(xoap);
|
||||
xoap = NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
free(xoap);
|
||||
xoap = NULL;
|
||||
}
|
||||
free(par);
|
||||
free(key);
|
||||
}
|
||||
#endif /* WEATHER */
|
||||
|
||||
static void print_help(const char *prog_name) {
|
||||
printf("Usage: %s [OPTION]...\n"
|
||||
PACKAGE_NAME" is a system monitor that renders text on desktop or to own transparent\n"
|
||||
@ -9331,12 +9268,6 @@ int main(int argc, char **argv)
|
||||
#endif /* ! CONF_OUTPUT */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WEATHER
|
||||
/* Load xoap keys, if existing */
|
||||
load_xoap_keys();
|
||||
#endif /* WEATHER */
|
||||
|
||||
#ifdef HAVE_SYS_INOTIFY_H
|
||||
inotify_fd = inotify_init();
|
||||
#endif /* HAVE_SYS_INOTIFY_H */
|
||||
|
137
src/weather.c
137
src/weather.c
@ -21,11 +21,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Add weather forecast info from weather.com
|
||||
*
|
||||
*/
|
||||
|
||||
#include "conky.h"
|
||||
#include "logging.h"
|
||||
#include "weather.h"
|
||||
@ -38,7 +33,6 @@
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
/* Possible sky conditions */
|
||||
#define NUM_CC_CODES 6
|
||||
@ -126,75 +120,6 @@ int rel_humidity(int dew_point, int air) {
|
||||
#endif /* MATH */
|
||||
}
|
||||
|
||||
//TODO: Lets get rid of the recursion
|
||||
static void parse_cc(PWEATHER *res, xmlNodePtr cc)
|
||||
{
|
||||
|
||||
xmlNodePtr cur = NULL;
|
||||
|
||||
for (cur = cc; cur; cur = cur->next) {
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *) "lsup")) {
|
||||
strncpy(res->lastupd, (char *)cur->children->content, 31);
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "tmp")) {
|
||||
res->temp = atoi((char *)cur->children->content);
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "t")) {
|
||||
if(res->xoap_t[0] == '\0') {
|
||||
strncpy(res->xoap_t, (char *)cur->children->content, 31);
|
||||
}
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "r")) {
|
||||
res->bar = atoi((char *)cur->children->content);
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "s")) {
|
||||
res->wind_s = atoi((char *)cur->children->content);
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "d")) {
|
||||
if (isdigit((char)cur->children->content[0])) {
|
||||
res->wind_d = atoi((char *)cur->children->content);
|
||||
}
|
||||
} else if (!xmlStrcmp(cur->name, (const xmlChar *) "hmid")) {
|
||||
res->hmid = atoi((char *)cur->children->content);
|
||||
}
|
||||
}
|
||||
parse_cc(res, cur->children);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void parse_weather_xml(PWEATHER *res, const char *data)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur;
|
||||
|
||||
if (!(doc = xmlReadMemory(data, strlen(data), "", NULL, 0))) {
|
||||
ERR("weather: can't read xml data");
|
||||
return;
|
||||
}
|
||||
|
||||
cur = xmlDocGetRootElement(doc);
|
||||
|
||||
while(cur) {
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *) "weather")) {
|
||||
cur = cur->children;
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *) "cc")) {
|
||||
parse_cc(res, cur->children);
|
||||
xmlFreeDoc(doc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ERR("weather: incorrect xml data");
|
||||
xmlFreeDoc(doc);
|
||||
return ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Horrible hack to avoid using regexes
|
||||
*
|
||||
@ -412,7 +337,6 @@ static inline void parse_token(PWEATHER *res, char *token) {
|
||||
|
||||
//First 3 digits are wind direction
|
||||
strncpy(s_tmp, token, 3);
|
||||
s_tmp[3]='\0';
|
||||
res->wind_d=atoi(s_tmp);
|
||||
|
||||
//4th and 5th digit are wind speed in knots (convert to km/hr)
|
||||
@ -469,7 +393,6 @@ static inline void parse_token(PWEATHER *res, char *token) {
|
||||
|
||||
//First 3 digits are wind direction
|
||||
strncpy(s_tmp, token, 3);
|
||||
s_tmp[3]='\0';
|
||||
res->wind_d=atoi(s_tmp);
|
||||
|
||||
//4th and 5th digit are wind speed in m/s (convert to km/hr)
|
||||
@ -487,44 +410,38 @@ static inline void parse_token(PWEATHER *res, char *token) {
|
||||
|
||||
static void parse_weather(PWEATHER *res, const char *data)
|
||||
{
|
||||
//Reset results
|
||||
char s_tmp[256];
|
||||
const char delim[] = " ";
|
||||
|
||||
memset(res, 0, sizeof(PWEATHER));
|
||||
|
||||
//Check if it is an xml file
|
||||
if ( strncmp(data, "<?xml ", 6) == 0 ) {
|
||||
parse_weather_xml(res, data);
|
||||
} else {
|
||||
//We assume its a text file
|
||||
char s_tmp[256];
|
||||
const char delim[] = " ";
|
||||
//Divide time stamp and metar data
|
||||
if (sscanf(data, "%[^'\n']\n%[^'\n']", res->lastupd, s_tmp) == 2) {
|
||||
|
||||
//Divide time stamp and metar data
|
||||
if (sscanf(data, "%[^'\n']\n%[^'\n']", res->lastupd, s_tmp) == 2) {
|
||||
//Process all tokens
|
||||
char *p_tok = NULL;
|
||||
char *p_save = NULL;
|
||||
|
||||
//Process all tokens
|
||||
char *p_tok = NULL;
|
||||
char *p_save = NULL;
|
||||
if ((strtok_r(s_tmp, delim, &p_save)) != NULL) {
|
||||
|
||||
if ((strtok_r(s_tmp, delim, &p_save)) != NULL) {
|
||||
//Jump first token, must be icao
|
||||
p_tok = strtok_r(NULL, delim, &p_save);
|
||||
|
||||
//Jump first token, must be icao
|
||||
p_tok = strtok_r(NULL, delim, &p_save);
|
||||
do {
|
||||
|
||||
do {
|
||||
parse_token(res, p_tok);
|
||||
p_tok = strtok_r(NULL, delim, &p_save);
|
||||
|
||||
parse_token(res, p_tok);
|
||||
p_tok = strtok_r(NULL, delim, &p_save);
|
||||
|
||||
} while (p_tok != NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
} while (p_tok != NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fetch_weather_info(location *curloc)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
@ -551,7 +468,7 @@ void fetch_weather_info(location *curloc)
|
||||
timed_thread_unlock(curloc->p_timed_thread);
|
||||
free(chunk.memory);
|
||||
} else {
|
||||
ERR("weather: no data from server");
|
||||
ERR("No data from server");
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
@ -568,12 +485,12 @@ void init_thread(location *curloc, int interval)
|
||||
timed_thread_create(&weather_thread,
|
||||
(void *)curloc, interval * 1000000);
|
||||
if (!curloc->p_timed_thread) {
|
||||
ERR("weather: error creating timed thread");
|
||||
ERR("Error creating weather 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");
|
||||
ERR("Error running weather timed thread");
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,15 +507,14 @@ void process_weather_info(char *p, int p_max_size, char *uri, char *data_type, i
|
||||
location *curloc = find_location(uri);
|
||||
if (!curloc->p_timed_thread) init_thread(curloc, interval);
|
||||
|
||||
|
||||
timed_thread_lock(curloc->p_timed_thread);
|
||||
if (strcmp(data_type, "last_update") == EQUAL) {
|
||||
strncpy(p, curloc->data.lastupd, p_max_size);
|
||||
} else if (strcmp(data_type, "temperature") == EQUAL) {
|
||||
temp_print(p, p_max_size, curloc->data.temp, TEMP_CELSIUS);
|
||||
} else if (strcmp(data_type, "cloud_cover") == EQUAL) {
|
||||
if (curloc->data.xoap_t[0] != '\0') {
|
||||
strncpy(p, curloc->data.xoap_t, p_max_size);
|
||||
} else if (curloc->data.cc == 0) {
|
||||
if (curloc->data.cc == 0) {
|
||||
strncpy(p, "", p_max_size);
|
||||
} else if (curloc->data.cc < 3) {
|
||||
strncpy(p, "clear", p_max_size);
|
||||
@ -659,7 +575,6 @@ void process_weather_info(char *p, int p_max_size, char *uri, char *data_type, i
|
||||
} else if (strcmp(data_type, "weather") == EQUAL) {
|
||||
strncpy(p, wc[curloc->data.wc], p_max_size);
|
||||
}
|
||||
|
||||
timed_thread_unlock(curloc->p_timed_thread);
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,7 @@
|
||||
|
||||
/* WEATHER data */
|
||||
typedef struct PWEATHER_ {
|
||||
char lastupd[32];
|
||||
char xoap_t[32];
|
||||
char lastupd[17];
|
||||
int temp;
|
||||
int dew;
|
||||
int cc;
|
||||
@ -40,16 +39,6 @@ typedef struct PWEATHER_ {
|
||||
int wind_d;
|
||||
int hmid;
|
||||
int wc;
|
||||
/*
|
||||
* TODO:
|
||||
* Is it worth investigating about using icons from weather.com?
|
||||
* We could use them for data from noaa as well.
|
||||
* They can display nicely with cimlib_add_image (with appropriate
|
||||
* #ifdefs on imlib2 and x11), and an additional input argoment for position.
|
||||
|
||||
char icon[3];
|
||||
|
||||
*/
|
||||
} PWEATHER;
|
||||
|
||||
/* Prototypes */
|
||||
|
Loading…
Reference in New Issue
Block a user