~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to weather/src/applet-read-data.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
/******************************************************************************
 
21
 
 
22
This file is a part of the cairo-dock program,
 
23
released under the terms of the GNU General Public License.
 
24
 
 
25
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
 
26
 
 
27
******************************************************************************/
 
28
#define _BSD_SOURCE
 
29
#include <string.h>
 
30
#include <stdio.h>
 
31
#include <unistd.h>
 
32
 
 
33
#include <libxml/tree.h>
 
34
#include <libxml/parser.h>
 
35
#include <glib/gstdio.h>
 
36
 
 
37
#include "applet-struct.h"
 
38
#include "applet-read-data.h"
 
39
 
 
40
#define CD_WEATHER_BASE_URL "http://xml.weather.com"
 
41
 
 
42
gchar *cd_weather_get_location_data (gchar *cLocation)
 
43
{
 
44
        gchar *cLocationFilePath = g_strdup ("/tmp/weather-location.XXXXXX");
 
45
        int fds = mkstemp (cLocationFilePath);
 
46
        if (fds == -1)
 
47
        {
 
48
                g_free (cLocationFilePath);
 
49
                return NULL;
 
50
        }
 
51
        gchar *cCommand = g_strdup_printf ("wget \""CD_WEATHER_BASE_URL"/search/search?where=%s\" -O %s -o /dev/null -t 3 -T 10", cLocation, cLocationFilePath);
 
52
        int r = system (cCommand);
 
53
        g_free (cCommand);
 
54
        close(fds);
 
55
        return cLocationFilePath;
 
56
}
 
57
 
 
58
 
 
59
static xmlDocPtr _cd_weather_open_xml_file (gchar *cDataFilePath, xmlNodePtr *root_node, gchar *cRootNodeName, GError **erreur)
 
60
{
 
61
        if (cairo_dock_get_file_size (cDataFilePath) == 0)
 
62
        {
 
63
                g_set_error (erreur, 1, 1, "file '%s' doesn't exist (no connection ?)", cDataFilePath);
 
64
                return NULL;
 
65
        }
 
66
        xmlInitParser ();
 
67
        
 
68
        xmlDocPtr doc = xmlParseFile (cDataFilePath);
 
69
        if (doc == NULL)
 
70
        {
 
71
                g_set_error (erreur, 1, 1, "file '%s' is uncorrect (no connection ?)", cDataFilePath);
 
72
                return NULL;
 
73
        }
 
74
        
 
75
        xmlNodePtr noeud = xmlDocGetRootElement (doc);
 
76
        if (noeud == NULL || xmlStrcmp (noeud->name, (const xmlChar *) cRootNodeName) != 0)
 
77
        {
 
78
                g_set_error (erreur, 1, 2, "xml file '%s' is not well formed (weather.com may have changed its data format)", cDataFilePath);
 
79
                return doc;
 
80
        }
 
81
        *root_node = noeud;
 
82
        return doc;
 
83
}
 
84
static void _cd_weather_close_xml_file (xmlDocPtr doc)
 
85
{
 
86
        xmlCleanupParser ();
 
87
        xmlFreeDoc (doc);
 
88
}
 
89
 
 
90
 
 
91
GList *cd_weather_parse_location_data (gchar *cDataFilePath, GError **erreur)
 
92
{
 
93
        cd_message ("%s (%s)", __func__, cDataFilePath);
 
94
        
 
95
        GError *tmp_erreur = NULL;
 
96
        xmlNodePtr noeud;
 
97
        xmlDocPtr doc = _cd_weather_open_xml_file (cDataFilePath, &noeud, "search", &tmp_erreur);
 
98
        if (tmp_erreur != NULL)
 
99
        {
 
100
                g_propagate_error (erreur, tmp_erreur);
 
101
                _cd_weather_close_xml_file (doc);
 
102
                return NULL;
 
103
        }
 
104
        
 
105
        GList *cLocationsList = NULL;
 
106
        xmlNodePtr param;
 
107
        for (param = noeud->xmlChildrenNode; param != NULL; param = param->next)
 
108
        {
 
109
                if (xmlStrcmp (param->name, (const xmlChar *) "loc") == 0)
 
110
                {
 
111
                        cLocationsList = g_list_prepend (cLocationsList, xmlNodeGetContent (param));
 
112
                        cLocationsList = g_list_prepend (cLocationsList,  xmlGetProp (param, (xmlChar *) "id"));
 
113
                }
 
114
        }
 
115
        _cd_weather_close_xml_file (doc);
 
116
        return cLocationsList;
 
117
}
 
118
 
 
119
 
 
120
static void _cd_weather_parse_data (CairoDockModuleInstance *myApplet, gchar *cDataFilePath, gboolean bParseHeader, GError **erreur)
 
121
{
 
122
        cd_message ("%s (%s)", __func__, cDataFilePath);
 
123
        
 
124
        GError *tmp_erreur = NULL;
 
125
        xmlNodePtr noeud;
 
126
        xmlDocPtr doc = _cd_weather_open_xml_file (cDataFilePath, &noeud, "weather", &tmp_erreur);
 
127
        if (tmp_erreur != NULL)
 
128
        {
 
129
                g_propagate_error (erreur, tmp_erreur);
 
130
                _cd_weather_close_xml_file (doc);
 
131
                return ;
 
132
        }
 
133
        
 
134
        xmlNodePtr param, fils, petitfils, arrpetitfils, arrarrpetitfils;
 
135
        gchar *nom, *visible, *name, *defaultsource = NULL, *source, *where;
 
136
        xmlChar *contenu;
 
137
        int i, j;
 
138
        gchar *index_str, *cDayName, *cDate, *str;
 
139
        for (param = noeud->xmlChildrenNode; param != NULL; param = param->next)
 
140
        {
 
141
                if (bParseHeader && xmlStrcmp (param->name, (const xmlChar *) "head") == 0)
 
142
                {
 
143
                        for (fils = param->children; fils != NULL; fils = fils->next)
 
144
                        {
 
145
                                if (xmlStrcmp (fils->name, (const xmlChar *) "ut") == 0)
 
146
                                {
 
147
                                        gchar *degree = xmlNodeGetContent (fils);
 
148
                                        if (degree == NULL || strncmp (degree, "Ā°", strlen ("Ā°")) != 0)
 
149
                                        {
 
150
                                                myData.units.cTemp = g_strconcat ("Ā°", degree, NULL);
 
151
                                                g_free (degree);
 
152
                                        }
 
153
                                        else
 
154
                                                myData.units.cTemp = degree;
 
155
                                }
 
156
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "ud") == 0)
 
157
                                        myData.units.cDistance = xmlNodeGetContent (fils);
 
158
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "us") == 0)
 
159
                                        myData.units.cSpeed = xmlNodeGetContent (fils);
 
160
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "up") == 0)
 
161
                                        myData.units.cPressure = xmlNodeGetContent (fils);
 
162
                                //else if (xmlStrcmp (fils->name, (const xmlChar *) "ur") == 0)  // ?
 
163
                                //      myData.units.cR = xmlNodeGetContent (fils);
 
164
                        }
 
165
                }
 
166
                else if (bParseHeader && xmlStrcmp (param->name, (const xmlChar *) "loc") == 0)
 
167
                {
 
168
                        for (fils = param->children; fils != NULL; fils = fils->next)
 
169
                        {
 
170
                                if (xmlStrcmp (fils->name, (const xmlChar *) "dnam") == 0)
 
171
                                        myData.cLocation = xmlNodeGetContent (fils);
 
172
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "lat") == 0)
 
173
                                        myData.cLat = xmlNodeGetContent (fils);
 
174
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "lon") == 0)
 
175
                                        myData.cLon = xmlNodeGetContent (fils);
 
176
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "sunr") == 0)
 
177
                                        myData.currentConditions.cSunRise = xmlNodeGetContent (fils);
 
178
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "suns") == 0)
 
179
                                        myData.currentConditions.cSunSet = xmlNodeGetContent (fils);
 
180
                        }
 
181
                }
 
182
                else if (xmlStrcmp (param->name, (const xmlChar *) "cc") == 0)
 
183
                {
 
184
                        for (fils = param->children; fils != NULL; fils = fils->next)
 
185
                        {
 
186
                                if (xmlStrcmp (fils->name, (const xmlChar *) "lsup") == 0)
 
187
                                        myData.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
 
188
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "obst") == 0)
 
189
                                        myData.currentConditions.cObservatory = xmlNodeGetContent (fils);
 
190
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "tmp") == 0)
 
191
                                        myData.currentConditions.cTemp = xmlNodeGetContent (fils);
 
192
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "flik") == 0)
 
193
                                        myData.currentConditions.cFeeledTemp = xmlNodeGetContent (fils);
 
194
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "t") == 0)
 
195
                                        myData.currentConditions.cWeatherDescription = xmlNodeGetContent (fils);
 
196
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "icon") == 0)
 
197
                                        myData.currentConditions.cIconNumber = xmlNodeGetContent (fils);
 
198
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "wind") == 0)
 
199
                                {
 
200
                                        for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
 
201
                                        {
 
202
                                                if (xmlStrcmp (petitfils->name, (const xmlChar *) "s") == 0)
 
203
                                                        myData.currentConditions.cWindSpeed = xmlNodeGetContent (petitfils);
 
204
                                                else if (xmlStrcmp (petitfils->name, (const xmlChar *) "t") == 0)
 
205
                                                        myData.currentConditions.cWindDirection = xmlNodeGetContent (petitfils);
 
206
                                        }
 
207
                                }
 
208
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "bar") == 0)
 
209
                                {
 
210
                                        for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
 
211
                                        {
 
212
                                                if (xmlStrcmp (petitfils->name, (const xmlChar *) "r") == 0)
 
213
                                                        myData.currentConditions.cPressure = xmlNodeGetContent (petitfils);
 
214
                                        }
 
215
                                }
 
216
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "hmid") == 0)
 
217
                                        myData.currentConditions.cHumidity = xmlNodeGetContent (fils);
 
218
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "moon") == 0)
 
219
                                {
 
220
                                        for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
 
221
                                        {
 
222
                                                if (xmlStrcmp (petitfils->name, (const xmlChar *) "icon") == 0)
 
223
                                                        myData.currentConditions.cMoonIconNumber = xmlNodeGetContent (petitfils);
 
224
                                        }
 
225
                                }
 
226
                        }
 
227
                }
 
228
                else if (xmlStrcmp (param->name, (const xmlChar *) "dayf") == 0)
 
229
                {
 
230
                        for (fils = param->children; fils != NULL; fils = fils->next)
 
231
                        {
 
232
                                if (xmlStrcmp (fils->name, (const xmlChar *) "lsup") == 0)
 
233
                                        myData.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
 
234
                                else if (xmlStrcmp (fils->name, (const xmlChar *) "day") == 0)
 
235
                                {
 
236
                                        index_str = (gchar *) xmlGetProp (fils, (xmlChar *) "d");
 
237
                                        if (index_str == NULL)
 
238
                                                continue;
 
239
                                        i = atoi (index_str);
 
240
                                        g_free (index_str);
 
241
                                        cDayName = (gchar *) xmlGetProp (fils, (xmlChar *) "t");
 
242
                                        myData.days[i].cName = g_strdup (D_(cDayName));
 
243
                                        g_free (cDayName);
 
244
                                        cDate = (gchar *) xmlGetProp (fils, (xmlChar *) "dt");
 
245
                                        str = strchr (cDate, ' ');
 
246
                                        if (str != NULL)
 
247
                                        {
 
248
                                                *str = '\0';
 
249
                                                myData.days[i].cDate = g_strconcat (D_(cDate), " ", str+1, NULL);
 
250
                                                g_free (cDate);
 
251
                                        }
 
252
                                        else
 
253
                                                myData.days[i].cDate = cDate;
 
254
                                        for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
 
255
                                        {
 
256
                                                if (xmlStrcmp (petitfils->name, (const xmlChar *) "hi") == 0)
 
257
                                                        myData.days[i].cTempMax = xmlNodeGetContent (petitfils);
 
258
                                                else if (xmlStrcmp (petitfils->name, (const xmlChar *) "low") == 0)
 
259
                                                        myData.days[i].cTempMin = xmlNodeGetContent (petitfils);
 
260
                                                else if (xmlStrcmp (petitfils->name, (const xmlChar *) "sunr") == 0)
 
261
                                                        myData.days[i].cSunRise = xmlNodeGetContent (petitfils);
 
262
                                                else if (xmlStrcmp (petitfils->name, (const xmlChar *) "suns") == 0)
 
263
                                                        myData.days[i].cSunSet = xmlNodeGetContent (petitfils);
 
264
                                                else if (xmlStrcmp (petitfils->name, (const xmlChar *) "part") == 0)
 
265
                                                {
 
266
                                                        index_str = (gchar *) xmlGetProp (petitfils, (xmlChar *) "p");
 
267
                                                        if (index_str == NULL)
 
268
                                                                continue;
 
269
                                                        j = (*index_str == 'd' ? 0 : 1);  // jour : 0 / nuit : 1.
 
270
                                                        for (arrpetitfils = petitfils->children; arrpetitfils != NULL; arrpetitfils = arrpetitfils->next)
 
271
                                                        {
 
272
                                                                if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "icon") == 0)
 
273
                                                                        myData.days[i].part[j].cIconNumber = xmlNodeGetContent (arrpetitfils);
 
274
                                                                else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "t") == 0)
 
275
                                                                        myData.days[i].part[j].cWeatherDescription = xmlNodeGetContent (arrpetitfils);
 
276
                                                                else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "wind") == 0)
 
277
                                                                {
 
278
                                                                        for (arrarrpetitfils = arrpetitfils->children; arrarrpetitfils != NULL; arrarrpetitfils = arrarrpetitfils->next)
 
279
                                                                        {
 
280
                                                                                if (xmlStrcmp (arrarrpetitfils->name, (const xmlChar *) "s") == 0)
 
281
                                                                                        myData.days[i].part[j].cWindSpeed = xmlNodeGetContent (arrarrpetitfils);
 
282
                                                                                else if (xmlStrcmp (arrarrpetitfils->name, (const xmlChar *) "t") == 0)
 
283
                                                                                        myData.days[i].part[j].cWindDirection = xmlNodeGetContent (arrarrpetitfils);
 
284
                                                                        }
 
285
                                                                }
 
286
                                                                else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "hmid") == 0)
 
287
                                                                        myData.days[i].part[j].cHumidity = xmlNodeGetContent (arrpetitfils);
 
288
                                                                else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "ppcp") == 0)
 
289
                                                                        myData.days[i].part[j].cPrecipitationProba = xmlNodeGetContent (arrpetitfils);
 
290
                                                        }
 
291
                                                }
 
292
                                        }
 
293
                                }  // fin du jour n.
 
294
                        }
 
295
                }
 
296
        }
 
297
        _cd_weather_close_xml_file (doc);
 
298
}
 
299
 
 
300
 
 
301
void cd_weather_get_distant_data (CairoDockModuleInstance *myApplet)
 
302
{
 
303
        //\____________________ On recupere les conditions courantes sur le serveur.
 
304
        int r;
 
305
        gchar *cCommand;
 
306
        gchar *cCCDataFilePath = NULL;
 
307
        if (myConfig.bCurrentConditions)
 
308
        {
 
309
                cCCDataFilePath = g_strdup ("/tmp/weather-cc.XXXXXX");
 
310
                int fds = mkstemp (cCCDataFilePath);
 
311
                if (fds == -1)
 
312
                {
 
313
                        g_free (cCCDataFilePath);
 
314
                        return;
 
315
                }
 
316
                cCommand = g_strdup_printf ("wget \""CD_WEATHER_BASE_URL"/weather/local/%s?cc=*%s\" -O %s -o /dev/null -t 3 -T 10", myConfig.cLocationCode, (myConfig.bISUnits ? "&unit=m" : ""), cCCDataFilePath);  // &prod=xoap&par=1048871467&key=12daac2f3a67cb39
 
317
                cd_debug ("weather : %s", cCommand);
 
318
                r = system (cCommand);
 
319
                g_free (cCommand);
 
320
                close(fds);
 
321
        }
 
322
        
 
323
        //\____________________ On recupere les previsions a N jours sur le serveur.
 
324
        gchar *cForecastDataFilePath = NULL;
 
325
        if (myConfig.iNbDays > 0)
 
326
        {
 
327
                cForecastDataFilePath = g_strdup ("/tmp/weather-forecast.XXXXXX");
 
328
                int fds = mkstemp (cForecastDataFilePath);
 
329
                if (fds == -1)
 
330
                {
 
331
                        g_free (cForecastDataFilePath);
 
332
                        return;
 
333
                }
 
334
                cCommand = g_strdup_printf ("wget \""CD_WEATHER_BASE_URL"/weather/local/%s?dayf=%d%s\" -O %s -o /dev/null -t 3 -T 10", myConfig.cLocationCode, myConfig.iNbDays, (myConfig.bISUnits ? "&unit=m" : ""), cForecastDataFilePath);  // &prod=xoap&par=1048871467&key=12daac2f3a67cb39
 
335
                cd_debug ("weather : %s", cCommand);
 
336
                r = system (cCommand);
 
337
                g_free (cCommand);
 
338
                close(fds);
 
339
        }
 
340
        
 
341
        //\____________________ On extrait les donnees des conditions courantes.
 
342
        GError *erreur = NULL;
 
343
        if (cCCDataFilePath != NULL)
 
344
        {
 
345
                _cd_weather_parse_data (myApplet, cCCDataFilePath, TRUE, &erreur);
 
346
                if (erreur != NULL)
 
347
                {
 
348
                        cd_warning ("weather : %s", erreur->message);
 
349
                        g_error_free (erreur);
 
350
                        erreur = NULL;
 
351
                        myData.bErrorInThread = TRUE;
 
352
                }
 
353
                else
 
354
                        myData.bErrorInThread = FALSE;
 
355
                g_remove (cCCDataFilePath);
 
356
                g_free (cCCDataFilePath);
 
357
        }
 
358
        
 
359
        //\____________________ On extrait les donnees des previsions a N jours.
 
360
        if (cForecastDataFilePath != NULL)
 
361
        {
 
362
                _cd_weather_parse_data (myApplet, cForecastDataFilePath, FALSE, &erreur);
 
363
                if (erreur != NULL)
 
364
                {
 
365
                        cd_warning ("weather : %s", erreur->message);
 
366
                        g_error_free (erreur);
 
367
                        erreur = NULL;
 
368
                        myData.bErrorInThread = TRUE;
 
369
                }
 
370
                else
 
371
                        myData.bErrorInThread = FALSE;
 
372
                g_remove (cForecastDataFilePath);
 
373
                g_free (cForecastDataFilePath);
 
374
        }
 
375
}