27
27
#include <glib/gstdio.h>
29
29
#include "applet-struct.h"
30
#include "applet-load-icons.h"
30
31
#include "applet-read-data.h"
32
33
#define CD_WEATHER_BASE_URL "http://xml.weather.com"
34
gchar *cd_weather_get_location_data (const gchar *cLocation)
36
GError *erreur = NULL;
37
gchar *cURL = g_strdup_printf (CD_WEATHER_BASE_URL"/search/search?where=%s", cLocation);
38
gchar *cData = cairo_dock_get_url_data (cURL, &erreur);
42
cd_warning ("while downlading location data : %s", erreur->message);
43
g_error_free (erreur);
48
36
static xmlDocPtr _cd_weather_open_xml_buffer (const gchar *cData, xmlNodePtr *root_node, const gchar *cRootNodeName, GError **erreur)
152
140
if (xmlStrcmp (fils->name, (const xmlChar *) "ut") == 0)
154
142
gchar *degree = xmlNodeGetContent (fils);
155
if (degree == NULL || strncmp (degree, "°", strlen ("°")) != 0)
143
if (degree == NULL || strncmp (degree, "°", strlen ("°")) != 0) // prepend � if not present.
157
myData.units.cTemp = g_strconcat ("°", degree, NULL);
145
pSharedMemory->wdata.units.cTemp = g_strconcat ("°", degree, NULL);
161
myData.units.cTemp = degree;
149
pSharedMemory->wdata.units.cTemp = degree;
163
151
else if (xmlStrcmp (fils->name, (const xmlChar *) "ud") == 0)
164
myData.units.cDistance = xmlNodeGetContent (fils);
152
pSharedMemory->wdata.units.cDistance = xmlNodeGetContent (fils);
165
153
else if (xmlStrcmp (fils->name, (const xmlChar *) "us") == 0)
166
myData.units.cSpeed = xmlNodeGetContent (fils);
154
pSharedMemory->wdata.units.cSpeed = xmlNodeGetContent (fils);
167
155
else if (xmlStrcmp (fils->name, (const xmlChar *) "up") == 0)
168
myData.units.cPressure = xmlNodeGetContent (fils);
156
pSharedMemory->wdata.units.cPressure = xmlNodeGetContent (fils);
169
157
//else if (xmlStrcmp (fils->name, (const xmlChar *) "ur") == 0) // ?
170
// myData.units.cR = xmlNodeGetContent (fils);
158
// pSharedMemory->wdata.units.cR = xmlNodeGetContent (fils);
173
161
else if (bParseHeader && xmlStrcmp (param->name, (const xmlChar *) "loc") == 0)
175
163
for (fils = param->children; fils != NULL; fils = fils->next)
177
165
if (xmlStrcmp (fils->name, (const xmlChar *) "dnam") == 0)
178
myData.cLocation_ = xmlNodeGetContent (fils);
179
else if (xmlStrcmp (fils->name, (const xmlChar *) "lat") == 0)
180
myData.cLat = xmlNodeGetContent (fils);
166
pSharedMemory->wdata.cLocation = xmlNodeGetContent (fils);
167
/**else if (xmlStrcmp (fils->name, (const xmlChar *) "lat") == 0)
168
pSharedMemory->cLat = xmlNodeGetContent (fils);
181
169
else if (xmlStrcmp (fils->name, (const xmlChar *) "lon") == 0)
182
myData.cLon = xmlNodeGetContent (fils);
170
pSharedMemory->cLon = xmlNodeGetContent (fils);*/
183
171
else if (xmlStrcmp (fils->name, (const xmlChar *) "sunr") == 0)
184
myData.currentConditions.cSunRise = xmlNodeGetContent (fils);
172
pSharedMemory->wdata.currentConditions.cSunRise = xmlNodeGetContent (fils);
185
173
else if (xmlStrcmp (fils->name, (const xmlChar *) "suns") == 0)
186
myData.currentConditions.cSunSet = xmlNodeGetContent (fils);
174
pSharedMemory->wdata.currentConditions.cSunSet = xmlNodeGetContent (fils);
189
177
else if (xmlStrcmp (param->name, (const xmlChar *) "cc") == 0)
191
179
for (fils = param->children; fils != NULL; fils = fils->next)
193
181
if (xmlStrcmp (fils->name, (const xmlChar *) "lsup") == 0)
194
myData.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
182
pSharedMemory->wdata.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
195
183
else if (xmlStrcmp (fils->name, (const xmlChar *) "obst") == 0)
196
myData.currentConditions.cObservatory = xmlNodeGetContent (fils);
184
pSharedMemory->wdata.currentConditions.cObservatory = xmlNodeGetContent (fils);
197
185
else if (xmlStrcmp (fils->name, (const xmlChar *) "tmp") == 0)
198
myData.currentConditions.cTemp = xmlNodeGetContent (fils);
186
pSharedMemory->wdata.currentConditions.cTemp = xmlNodeGetContent (fils);
199
187
else if (xmlStrcmp (fils->name, (const xmlChar *) "flik") == 0)
200
myData.currentConditions.cFeltTemp = xmlNodeGetContent (fils);
188
pSharedMemory->wdata.currentConditions.cFeltTemp = xmlNodeGetContent (fils);
201
189
else if (xmlStrcmp (fils->name, (const xmlChar *) "t") == 0)
202
myData.currentConditions.cWeatherDescription = xmlNodeGetContent (fils);
190
pSharedMemory->wdata.currentConditions.cWeatherDescription = xmlNodeGetContent (fils);
203
191
else if (xmlStrcmp (fils->name, (const xmlChar *) "icon") == 0)
204
myData.currentConditions.cIconNumber = xmlNodeGetContent (fils);
192
pSharedMemory->wdata.currentConditions.cIconNumber = xmlNodeGetContent (fils);
205
193
else if (xmlStrcmp (fils->name, (const xmlChar *) "wind") == 0)
207
195
for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
209
197
if (xmlStrcmp (petitfils->name, (const xmlChar *) "s") == 0)
210
myData.currentConditions.cWindSpeed = xmlNodeGetContent (petitfils);
198
pSharedMemory->wdata.currentConditions.cWindSpeed = xmlNodeGetContent (petitfils);
211
199
else if (xmlStrcmp (petitfils->name, (const xmlChar *) "t") == 0)
212
myData.currentConditions.cWindDirection = xmlNodeGetContent (petitfils);
200
pSharedMemory->wdata.currentConditions.cWindDirection = xmlNodeGetContent (petitfils);
215
203
else if (xmlStrcmp (fils->name, (const xmlChar *) "bar") == 0)
217
205
for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
219
207
if (xmlStrcmp (petitfils->name, (const xmlChar *) "r") == 0)
220
myData.currentConditions.cPressure = xmlNodeGetContent (petitfils);
208
pSharedMemory->wdata.currentConditions.cPressure = xmlNodeGetContent (petitfils);
223
211
else if (xmlStrcmp (fils->name, (const xmlChar *) "hmid") == 0)
224
myData.currentConditions.cHumidity = xmlNodeGetContent (fils);
212
pSharedMemory->wdata.currentConditions.cHumidity = xmlNodeGetContent (fils);
225
213
else if (xmlStrcmp (fils->name, (const xmlChar *) "moon") == 0)
227
215
for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
229
217
if (xmlStrcmp (petitfils->name, (const xmlChar *) "icon") == 0)
230
myData.currentConditions.cMoonIconNumber = xmlNodeGetContent (petitfils);
218
pSharedMemory->wdata.currentConditions.cMoonIconNumber = xmlNodeGetContent (petitfils);
237
225
for (fils = param->children; fils != NULL; fils = fils->next)
239
227
if (xmlStrcmp (fils->name, (const xmlChar *) "lsup") == 0)
240
myData.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
228
pSharedMemory->wdata.currentConditions.cDataAcquisitionDate = xmlNodeGetContent (fils);
241
229
else if (xmlStrcmp (fils->name, (const xmlChar *) "day") == 0)
243
231
index_str = (gchar *) xmlGetProp (fils, (xmlChar *) "d");
246
234
i = atoi (index_str);
247
235
g_free (index_str);
248
236
cDayName = (gchar *) xmlGetProp (fils, (xmlChar *) "t");
249
myData.days[i].cName = g_strdup (D_(cDayName));
237
pSharedMemory->wdata.days[i].cName = g_strdup (D_(cDayName));
250
238
g_free (cDayName);
251
239
cDate = (gchar *) xmlGetProp (fils, (xmlChar *) "dt");
252
240
str = strchr (cDate, ' ');
256
myData.days[i].cDate = g_strconcat (D_(cDate), " ", str+1, NULL);
244
pSharedMemory->wdata.days[i].cDate = g_strconcat (D_(cDate), " ", str+1, NULL);
260
myData.days[i].cDate = cDate;
248
pSharedMemory->wdata.days[i].cDate = cDate;
261
249
for (petitfils = fils->children; petitfils != NULL; petitfils = petitfils->next)
263
251
if (xmlStrcmp (petitfils->name, (const xmlChar *) "hi") == 0)
264
myData.days[i].cTempMax = xmlNodeGetContent (petitfils);
252
pSharedMemory->wdata.days[i].cTempMax = xmlNodeGetContent (petitfils);
265
253
else if (xmlStrcmp (petitfils->name, (const xmlChar *) "low") == 0)
266
myData.days[i].cTempMin = xmlNodeGetContent (petitfils);
254
pSharedMemory->wdata.days[i].cTempMin = xmlNodeGetContent (petitfils);
267
255
else if (xmlStrcmp (petitfils->name, (const xmlChar *) "sunr") == 0)
268
myData.days[i].cSunRise = xmlNodeGetContent (petitfils);
256
pSharedMemory->wdata.days[i].cSunRise = xmlNodeGetContent (petitfils);
269
257
else if (xmlStrcmp (petitfils->name, (const xmlChar *) "suns") == 0)
270
myData.days[i].cSunSet = xmlNodeGetContent (petitfils);
258
pSharedMemory->wdata.days[i].cSunSet = xmlNodeGetContent (petitfils);
271
259
else if (xmlStrcmp (petitfils->name, (const xmlChar *) "part") == 0)
273
261
index_str = (gchar *) xmlGetProp (petitfils, (xmlChar *) "p");
277
265
for (arrpetitfils = petitfils->children; arrpetitfils != NULL; arrpetitfils = arrpetitfils->next)
279
267
if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "icon") == 0)
280
myData.days[i].part[j].cIconNumber = xmlNodeGetContent (arrpetitfils);
268
pSharedMemory->wdata.days[i].part[j].cIconNumber = xmlNodeGetContent (arrpetitfils);
281
269
else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "t") == 0)
282
myData.days[i].part[j].cWeatherDescription = xmlNodeGetContent (arrpetitfils);
270
pSharedMemory->wdata.days[i].part[j].cWeatherDescription = xmlNodeGetContent (arrpetitfils);
283
271
else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "wind") == 0)
285
273
for (arrarrpetitfils = arrpetitfils->children; arrarrpetitfils != NULL; arrarrpetitfils = arrarrpetitfils->next)
287
275
if (xmlStrcmp (arrarrpetitfils->name, (const xmlChar *) "s") == 0)
288
myData.days[i].part[j].cWindSpeed = xmlNodeGetContent (arrarrpetitfils);
276
pSharedMemory->wdata.days[i].part[j].cWindSpeed = xmlNodeGetContent (arrarrpetitfils);
289
277
else if (xmlStrcmp (arrarrpetitfils->name, (const xmlChar *) "t") == 0)
290
myData.days[i].part[j].cWindDirection = xmlNodeGetContent (arrarrpetitfils);
278
pSharedMemory->wdata.days[i].part[j].cWindDirection = xmlNodeGetContent (arrarrpetitfils);
293
281
else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "hmid") == 0)
294
myData.days[i].part[j].cHumidity = xmlNodeGetContent (arrpetitfils);
282
pSharedMemory->wdata.days[i].part[j].cHumidity = xmlNodeGetContent (arrpetitfils);
295
283
else if (xmlStrcmp (arrpetitfils->name, (const xmlChar *) "ppcp") == 0)
296
myData.days[i].part[j].cPrecipitationProba = xmlNodeGetContent (arrpetitfils);
284
pSharedMemory->wdata.days[i].part[j].cPrecipitationProba = xmlNodeGetContent (arrpetitfils);
308
void cd_weather_get_distant_data (CairoDockModuleInstance *myApplet)
296
static void cd_weather_get_distant_data (CDSharedMemory *pSharedMemory)
310
//\____________________ On efface toutes les donnees.
311
cd_weather_reset_data (myApplet);
313
298
//\____________________ On recupere les conditions courantes sur le serveur.
314
myData.bErrorInThread = FALSE;
299
pSharedMemory->bErrorInThread = FALSE;
315
300
GError *erreur = NULL;
317
302
gchar *cCCData = NULL;
318
if (myConfig.bCurrentConditions)
303
if (pSharedMemory->bCurrentConditions)
320
gchar *cURL = g_strdup_printf (CD_WEATHER_BASE_URL"/weather/local/%s?cc=*%s", myConfig.cLocationCode, (myConfig.bISUnits ? "&unit=m" : ""));
305
gchar *cURL = g_strdup_printf (CD_WEATHER_BASE_URL"/weather/local/%s?cc=*%s", pSharedMemory->cLocationCode, (pSharedMemory->bISUnits ? "&unit=m" : ""));
321
306
cCCData = cairo_dock_get_url_data (cURL, &erreur);
323
308
if (erreur != NULL)
325
cd_warning ("while downlading current conditions data:\n%s -> %s", cURL, erreur->message);
310
cd_warning ("while downloading current conditions data:\n%s -> %s", cURL, erreur->message);
326
311
g_error_free (erreur);
329
314
if (cCCData == NULL)
331
myData.bErrorInThread = TRUE;
316
pSharedMemory->bErrorInThread = TRUE;
332
317
return; // a la 1ere erreur on quitte.
336
321
//\____________________ On recupere les previsions a N jours sur le serveur.
337
322
gchar *cForecastData = NULL;
338
if (myConfig.iNbDays > 0)
323
if (pSharedMemory->iNbDays > 0)
340
gchar *cURL = g_strdup_printf (CD_WEATHER_BASE_URL"/weather/local/%s?dayf=%d%s", myConfig.cLocationCode, myConfig.iNbDays, (myConfig.bISUnits ? "&unit=m" : ""));
325
gchar *cURL = g_strdup_printf (CD_WEATHER_BASE_URL"/weather/local/%s?dayf=%d%s", pSharedMemory->cLocationCode, pSharedMemory->iNbDays, (pSharedMemory->bISUnits ? "&unit=m" : ""));
341
326
cForecastData = cairo_dock_get_url_data (cURL, &erreur);
343
328
if (erreur != NULL)
345
cd_warning ("while downlading forecast data:\n%s -> %s", cURL, erreur->message);
330
cd_warning ("while downloading forecast data:\n%s -> %s", cURL, erreur->message);
346
331
g_error_free (erreur);
348
myData.bErrorInThread = TRUE;
333
pSharedMemory->bErrorInThread = TRUE;
350
335
if (cForecastData == NULL)
352
myData.bErrorInThread = TRUE;
337
pSharedMemory->bErrorInThread = TRUE;
356
341
//\____________________ On extrait les donnees des conditions courantes.
357
342
if (cCCData != NULL)
359
_cd_weather_parse_data (myApplet, cCCData, TRUE, &erreur);
344
_cd_weather_parse_data (pSharedMemory, cCCData, TRUE, &erreur);
360
345
if (erreur != NULL)
362
347
cd_warning ("weather : %s", erreur->message);
363
348
g_error_free (erreur);
365
myData.bErrorInThread = TRUE;
350
pSharedMemory->bErrorInThread = TRUE;
367
352
g_free (cCCData);
370
355
//\____________________ On extrait les donnees des previsions a N jours.
371
356
if (cForecastData != NULL)
373
_cd_weather_parse_data (myApplet, cForecastData, FALSE, &erreur);
358
_cd_weather_parse_data (pSharedMemory, cForecastData, FALSE, &erreur);
374
359
if (erreur != NULL)
376
361
cd_warning ("weather : %s", erreur->message);
377
362
g_error_free (erreur);
379
myData.bErrorInThread = TRUE;
364
pSharedMemory->bErrorInThread = TRUE;
381
366
g_free (cForecastData);
417
void cd_weather_reset_weather_data (CDWeatherData *pData)
419
/**xmlFree (pData->cLon);
420
xmlFree (pData->cLat);*/
421
xmlFree (pData->cLocation);
422
_reset_units (&pData->units);
423
_reset_current_conditions (&pData->currentConditions);
425
for (i = 0; i < WEATHER_NB_DAYS_MAX; i ++)
427
_reset_current_one_day (&pData->days[i]);
430
431
void cd_weather_reset_data (CairoDockModuleInstance *myApplet)
432
// on libere toutes les ressources de la memoire partagee.
433
xmlFree (myData.cLon);
434
xmlFree (myData.cLat);
435
xmlFree (myData.cLocation_);
436
_reset_units (&myData.units);
437
_reset_current_conditions (&myData.currentConditions);
439
for (i = 0; i < myConfig.iNbDays; i ++)
433
cd_weather_reset_weather_data (&myData.wdata);
436
static void _free_shared_memory (CDSharedMemory *pSharedMemory)
438
cd_weather_reset_weather_data (&pSharedMemory->wdata);
439
g_free (pSharedMemory);
441
void cd_weather_launch_periodic_task (CairoDockModuleInstance *myApplet)
443
if (myData.pTask != NULL)
441
_reset_current_one_day (&myData.days[i]);
445
cairo_dock_discard_task (myData.pTask);
444
// on remet tout a 0.
447
myData.cLocation_ = NULL;
448
memset (&myData.currentConditions, 0, sizeof (CurrentContitions));
449
memset (&myData.units, 0, sizeof (Unit));
450
memset (&myData.days, 0, WEATHER_NB_DAYS_MAX * sizeof (Day));
449
CDSharedMemory *pSharedMemory = g_new0 (CDSharedMemory, 1);
450
pSharedMemory->cLocationCode = g_strdup (myConfig.cLocationCode);
451
pSharedMemory->bISUnits = myConfig.bISUnits;
452
pSharedMemory->bCurrentConditions = myConfig.bCurrentConditions;
453
pSharedMemory->iNbDays = myConfig.iNbDays;
454
pSharedMemory->pApplet = myApplet;
456
myData.pTask = cairo_dock_new_task_full (myConfig.iCheckInterval,
457
(CairoDockGetDataAsyncFunc) cd_weather_get_distant_data,
458
(CairoDockUpdateSyncFunc) cd_weather_update_from_data,
459
(GFreeFunc) _free_shared_memory,
461
cairo_dock_launch_task (myData.pTask);