1 /*  Copyright (c) 2003-2014 Xfce Development Team
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301, USA.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 
27 #include <glib.h>
28 #include <stdarg.h>
29 
30 #include "weather-debug.h"
31 
32 #define YESNO(bool) ((bool) ? "yes" : "no")
33 
34 
35 #if GLIB_CHECK_VERSION(2,32,0)
36 #else
37 static void
weather_dummy_log_handler(const gchar * log_domain,const GLogLevelFlags log_level,const gchar * message,const gpointer unused_data)38 weather_dummy_log_handler(const gchar *log_domain,
39                           const GLogLevelFlags log_level,
40                           const gchar *message,
41                           const gpointer unused_data)
42 {
43     /* Swallow all messages */
44 }
45 #endif
46 
47 
48 void
weather_debug_init(const gchar * log_domain,const gboolean w_debug_mode)49 weather_debug_init(const gchar *log_domain,
50                    const gboolean w_debug_mode)
51 {
52     /*
53      * GLIB >= 2.32 only shows debug messages if G_MESSAGES_DEBUG contains the
54      * log domain or "all", earlier GLIB versions always show debugging output
55      */
56 #if GLIB_CHECK_VERSION(2,32,0)
57     const gchar *debug_env;
58     gchar *debug_env_new_array[] = { NULL, NULL, NULL, NULL };
59     gchar *debug_env_new;
60     gint i = 0, j = 0;
61 
62     if (w_debug_mode) {
63         debug_env = g_getenv("G_MESSAGES_DEBUG");
64 
65         if (log_domain == NULL)
66             debug_env_new_array[i++] = g_strdup("all");
67         else {
68             if (debug_env != NULL)
69                 debug_env_new_array[i++] = g_strdup(debug_env);
70             if (debug_env == NULL || strstr(debug_env, log_domain) == NULL)
71                 debug_env_new_array[i++] = g_strdup(log_domain);
72             if (debug_env == NULL || strstr(debug_env, G_LOG_DOMAIN) == NULL)
73                 debug_env_new_array[i++] = g_strdup(G_LOG_DOMAIN);
74         }
75         debug_env_new = g_strjoinv(" ", debug_env_new_array);
76         g_setenv("G_MESSAGES_DEBUG", debug_env_new, TRUE);
77         g_free(debug_env_new);
78 
79         while (j < i)
80             g_free(debug_env_new_array[j++]);
81     }
82 #else
83     if (!w_debug_mode) {
84         g_log_set_handler(log_domain, G_LOG_LEVEL_DEBUG,
85                           weather_dummy_log_handler, NULL);
86         g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
87                           weather_dummy_log_handler, NULL);
88     }
89 #endif
90 }
91 
92 
93 void
weather_debug_real(const gchar * log_domain,const gchar * file,const gchar * func,const gint line,const gchar * format,...)94 weather_debug_real(const gchar *log_domain,
95                    const gchar *file,
96                    const gchar *func,
97                    const gint line,
98                    const gchar *format,
99                    ...)
100 {
101     va_list args;
102     gchar *prefixed_format;
103 
104     va_start(args, format);
105     prefixed_format = g_strdup_printf("[%s:%d %s]: %s",
106                                       file, line, func, format);
107     g_logv(log_domain, G_LOG_LEVEL_DEBUG, prefixed_format, args);
108     va_end(args);
109     g_free(prefixed_format);
110 }
111 
112 
113 gchar *
weather_dump_geolocation(const xml_geolocation * geo)114 weather_dump_geolocation(const xml_geolocation *geo)
115 {
116     gchar *out;
117 
118     if (!geo)
119         return g_strdup("No geolocation data.");
120 
121     out = g_strdup_printf("Geolocation data:\n"
122                           "  --------------------------------------------\n"
123                           "  city: %s\n"
124                           "  country name: %s\n"
125                           "  country code: %s\n"
126                           "  region name: %s\n"
127                           "  latitude: %s\n"
128                           "  longitude: %s\n"
129                           "  --------------------------------------------",
130                           geo->city,
131                           geo->country_name,
132                           geo->country_code,
133                           geo->region_name,
134                           geo->latitude,
135                           geo->longitude);
136     return out;
137 }
138 
139 
140 gchar *
weather_dump_place(const xml_place * place)141 weather_dump_place(const xml_place *place)
142 {
143     gchar *out;
144 
145     if (!place)
146         return g_strdup("No place data.");
147 
148     out = g_strdup_printf("Place data:\n"
149                           "  --------------------------------------------\n"
150                           "  display_name: %s\n"
151                           "  latitude: %s\n"
152                           "  longitude: %s\n"
153                           "  --------------------------------------------",
154                           place->display_name,
155                           place->lat,
156                           place->lon);
157     return out;
158 }
159 
160 
161 gchar *
weather_dump_timezone(const xml_timezone * tz)162 weather_dump_timezone(const xml_timezone *tz)
163 {
164     gchar *out;
165 
166     if (!tz)
167         return g_strdup("No timezone data.");
168 
169     out = g_strdup_printf("Timezone data:\n"
170                           "  --------------------------------------------\n"
171                           "  country_code: %s\n"
172                           "  country_name: %s\n"
173                           "  timezone_id: %s\n"
174                           "  --------------------------------------------",
175                           tz->country_code,
176                           tz->country_name,
177                           tz->timezone_id);
178     return out;
179 }
180 
181 
182 gchar *
weather_dump_icon_theme(const icon_theme * theme)183 weather_dump_icon_theme(const icon_theme *theme)
184 {
185     gchar *out;
186 
187     if (!theme)
188         return g_strdup("No icon theme data.");
189 
190     out = g_strdup_printf("Icon theme data:\n"
191                           "  --------------------------------------------\n"
192                           "  Dir: %s\n"
193                           "  Name: %s\n"
194                           "  Author: %s\n"
195                           "  Description: %s\n"
196                           "  License: %s\n"
197                           "  --------------------------------------------",
198                           theme->dir,
199                           theme->name,
200                           theme->author,
201                           theme->description,
202                           theme->license);
203     return out;
204 }
205 
206 
207 gchar *
weather_dump_astrodata(const GArray * astrodata)208 weather_dump_astrodata(const GArray *astrodata)
209 {
210     GString *out;
211     gchar *result, *line;
212     xml_astro *astro;
213     guint i;
214 
215     if (!astrodata || astrodata->len <= 0)
216         return g_strdup("No astronomical data available.");
217 
218     out = g_string_sized_new(1024);
219     g_string_assign(out, "Astronomical data:\n");
220     for (i = 0; i < astrodata->len; i++) {
221         astro = g_array_index(astrodata, xml_astro *, i);
222         line = weather_dump_astro(astro);
223         g_string_append(out, line);
224         g_free(line);
225     }
226     /* Free GString only and return its character data */
227     result = out->str;
228     g_string_free(out, FALSE);
229     return result;
230 }
231 
232 
233 gchar *
weather_dump_astro(const xml_astro * astro)234 weather_dump_astro(const xml_astro *astro)
235 {
236     gchar *out, *day, *sunrise, *sunset, *moonrise, *moonset;
237 
238     if (!astro)
239         return g_strdup("Astrodata: NULL.");
240 
241     day = format_date(astro->day, "%c", TRUE);
242     sunrise = format_date(astro->sunrise, "%c", TRUE);
243     sunset = format_date(astro->sunset, "%c", TRUE);
244     moonrise = format_date(astro->moonrise, "%c", TRUE);
245     moonset = format_date(astro->moonset, "%c", TRUE);
246 
247     out = g_strdup_printf("day=%s, sun={%s, %s, %s, %s}, "
248                           "moon={%s, %s, %s, %s, %s}\n",
249                           day,
250                           sunrise,
251                           sunset,
252                           YESNO(astro->sun_never_rises),
253                           YESNO(astro->sun_never_sets),
254                           moonrise,
255                           moonset,
256                           YESNO(astro->moon_never_rises),
257                           YESNO(astro->moon_never_sets),
258                           astro->moon_phase);
259 
260     g_free(day);
261     g_free(sunrise);
262     g_free(sunset);
263     g_free(moonrise);
264     g_free(moonset);
265     return out;
266 }
267 
268 
269 static gchar *
weather_dump_location(const xml_location * loc,const gboolean interval)270 weather_dump_location(const xml_location *loc,
271                       const gboolean interval)
272 {
273     gchar *out;
274 
275     if (!loc)
276         return g_strdup("No location data.");
277 
278     if (interval)
279         out =
280             g_strdup_printf("alt=%s, lat=%s, lon=%s, "
281                             "prec=%s %s, symid=%d (%s)",
282                             loc->altitude,
283                             loc->latitude,
284                             loc->longitude,
285                             loc->precipitation_value,
286                             loc->precipitation_unit,
287                             loc->symbol_id,
288                             loc->symbol);
289     else
290         out =
291             g_strdup_printf("alt=%s, lat=%s, lon=%s, temp=%s %s, "
292                             "wind=%s %s° %s m/s (%s bf), "
293                             "hum=%s %s, press=%s %s, fog=%s, cloudiness=%s, "
294                             "cl=%s, cm=%s, ch=%s)",
295                             loc->altitude,
296                             loc->latitude,
297                             loc->longitude,
298                             loc->temperature_value,
299                             loc->temperature_unit,
300                             loc->wind_dir_name,
301                             loc->wind_dir_deg,
302                             loc->wind_speed_mps,
303                             loc->wind_speed_beaufort,
304                             loc->humidity_value,
305                             loc->humidity_unit,
306                             loc->pressure_value,
307                             loc->pressure_unit,
308                             loc->fog_percent,
309                             loc->clouds_percent[CLOUDS_PERC_CLOUDINESS],
310                             loc->clouds_percent[CLOUDS_PERC_LOW],
311                             loc->clouds_percent[CLOUDS_PERC_MID],
312                             loc->clouds_percent[CLOUDS_PERC_HIGH]);
313     return out;
314 }
315 
316 
317 gchar *
weather_dump_units_config(const units_config * units)318 weather_dump_units_config(const units_config *units)
319 {
320     gchar *out;
321 
322     if (!units)
323         return g_strdup("No units configuration data.");
324 
325     out = g_strdup_printf("Units configuration data:\n"
326                           "  --------------------------------------------\n"
327                           "  Temperature: %d\n"
328                           "  Atmospheric pressure: %d\n"
329                           "  Windspeed: %d\n"
330                           "  Precipitation: %d\n"
331                           "  Altitude: %d\n"
332                           "  --------------------------------------------",
333                           units->temperature,
334                           units->pressure,
335                           units->windspeed,
336                           units->precipitation,
337                           units->altitude);
338     return out;
339 }
340 
341 
342 gchar *
weather_dump_timeslice(const xml_time * timeslice)343 weather_dump_timeslice(const xml_time *timeslice)
344 {
345     GString *out;
346     gchar *start, *end, *loc, *result;
347     gboolean is_interval;
348 
349     if (G_UNLIKELY(timeslice == NULL))
350         return g_strdup("No timeslice data.");
351 
352     out = g_string_sized_new(512);
353     start = format_date(timeslice->start, "%c", TRUE);
354     end = format_date(timeslice->end, "%c", TRUE);
355     is_interval = (gboolean) strcmp(start, end);
356     loc = weather_dump_location((timeslice) ? timeslice->location : NULL,
357                                 is_interval);
358     g_string_append_printf(out, "[%s %s %s] %s\n", start,
359                            is_interval ? "-" : "=", end, loc);
360     g_free(start);
361     g_free(end);
362     g_free(loc);
363 
364     /* Free GString only and return its character data */
365     result = out->str;
366     g_string_free(out, FALSE);
367     return result;
368 }
369 
370 
371 gchar *
weather_dump_weatherdata(const xml_weather * wd)372 weather_dump_weatherdata(const xml_weather *wd)
373 {
374     GString *out;
375     xml_time *timeslice;
376     gchar *result, *tmp;
377     guint i;
378 
379     if (G_UNLIKELY(wd == NULL))
380         return g_strdup("No weather data.");
381 
382     if (G_UNLIKELY(wd->timeslices == NULL))
383         return g_strdup("Weather data: No timeslices available.");
384 
385     out = g_string_sized_new(20480);
386     g_string_assign(out, "Timeslices (local time): ");
387     g_string_append_printf(out, "%d timeslices available.\n",
388                            wd->timeslices->len);
389     for (i = 0; i < wd->timeslices->len; i++) {
390         timeslice = g_array_index(wd->timeslices, xml_time *, i);
391         tmp = weather_dump_timeslice(timeslice);
392         g_string_append_printf(out, "  #%3d: %s", i + 1, tmp);
393         g_free(tmp);
394     }
395 
396     /* Remove trailing newline */
397     if (out->str[out->len - 1] == '\n')
398         out->str[--out->len] = '\0';
399 
400     /* Free GString only and return its character data */
401     result = out->str;
402     g_string_free(out, FALSE);
403     return result;
404 }
405 
406 
407 gchar *
weather_dump_plugindata(const plugin_data * data)408 weather_dump_plugindata(const plugin_data *data)
409 {
410     GString *out;
411     gchar *last_astro_update, *last_weather_update, *last_conditions_update;
412     gchar *next_astro_update, *next_weather_update, *next_conditions_update;
413     gchar *next_wakeup, *result;
414 
415     last_astro_update = format_date(data->astro_update->last, "%c", TRUE);
416     last_weather_update = format_date(data->weather_update->last, "%c", TRUE);
417     last_conditions_update =
418         format_date(data->conditions_update->last, "%c", TRUE);
419     next_astro_update = format_date(data->astro_update->next, "%c", TRUE);
420     next_weather_update = format_date(data->weather_update->next, "%c", TRUE);
421     next_conditions_update =
422         format_date(data->conditions_update->next, "%c", TRUE);
423     next_wakeup = format_date(data->next_wakeup, "%c", TRUE);
424 
425     out = g_string_sized_new(1024);
426     g_string_assign(out, "xfce_weatherdata:\n");
427     g_string_append_printf(out,
428                            "  --------------------------------------------\n"
429                            "  panel size: %d px\n"
430                            "  panel rows: %d px\n"
431                            "  single row: %s\n"
432                            "  panel orientation: %d\n"
433                            "  --------------------------------------------\n"
434 #ifdef HAVE_UPOWER_GLIB
435                            "  upower on battery: %s\n"
436 #endif
437                            "  power saving: %s\n"
438                            "  --------------------------------------------\n"
439                            "  last astro update: %s\n"
440                            "  next astro update: %s\n"
441                            "  astro download attempts: %d\n"
442                            "  last weather update: %s\n"
443                            "  next weather update: %s\n"
444                            "  weather download attempts: %d\n"
445                            "  last conditions update: %s\n"
446                            "  next conditions update: %s\n"
447                            "  next scheduled wakeup: %s\n"
448                            "  wakeup reason: %s\n"
449                            "  --------------------------------------------\n"
450                            "  geonames username set by user: %s\n"
451                            "  --------------------------------------------\n"
452                            "  location name: %s\n"
453                            "  latitude: %s\n"
454                            "  longitude: %s\n"
455                            "  msl: %d\n"
456                            "  timezone: %s\n"
457                            "  initial timezone: %s\n"
458                            "  night time: %s\n"
459                            "  --------------------------------------------\n"
460                            "  icon theme dir: %s\n"
461                            "  tooltip style: %d\n"
462                            "  forecast layout: %d\n"
463                            "  forecast days: %d\n"
464                            "  round values: %s\n"
465                            "  --------------------------------------------\n"
466                            "  show scrollbox: %s\n"
467                            "  scrollbox lines: %d\n"
468                            "  scrollbox font: %s\n"
469                            "  scrollbox color: %s\n"
470                            "  scrollbox use color: %s\n"
471                            "  animate scrollbox: %s\n"
472                            "  --------------------------------------------",
473                            data->panel_size,
474                            data->panel_rows,
475                            YESNO(data->single_row),
476                            data->panel_orientation,
477 #ifdef HAVE_UPOWER_GLIB
478                            YESNO(data->upower_on_battery),
479 #endif
480                            YESNO(data->power_saving),
481                            last_astro_update,
482                            next_astro_update,
483                            data->astro_update->attempt,
484                            last_weather_update,
485                            next_weather_update,
486                            data->weather_update->attempt,
487                            last_conditions_update,
488                            next_conditions_update,
489                            next_wakeup,
490                            data->next_wakeup_reason,
491                            YESNO(data->geonames_username),
492                            data->location_name,
493                            data->lat,
494                            data->lon,
495                            data->msl,
496                            data->timezone,
497                            data->timezone_initial,
498                            YESNO(data->night_time),
499                            (data->icon_theme) ? (data->icon_theme->dir) : NULL,
500                            data->tooltip_style,
501                            data->forecast_layout,
502                            data->forecast_days,
503                            YESNO(data->round),
504                            YESNO(data->show_scrollbox),
505                            data->scrollbox_lines,
506                            data->scrollbox_font,
507                            gdk_rgba_to_string(&(data->scrollbox_color)),
508                            YESNO(data->scrollbox_use_color),
509                            YESNO(data->scrollbox_animate));
510     g_free(next_wakeup);
511     g_free(next_astro_update);
512     g_free(next_weather_update);
513     g_free(next_conditions_update);
514     g_free(last_astro_update);
515     g_free(last_weather_update);
516     g_free(last_conditions_update);
517 
518     /* Free GString only and return its character data */
519     result = out->str;
520     g_string_free(out, FALSE);
521     return result;
522 }
523