libgweather r144 - in trunk: . data libgweather po po-locations
- From: vuntz svn gnome org
- To: svn-commits-list gnome org
- Subject: libgweather r144 - in trunk: . data libgweather po po-locations
- Date: Mon, 7 Apr 2008 09:53:31 +0100 (BST)
Author: vuntz
Date: Mon Apr 7 09:53:31 2008
New Revision: 144
URL: http://svn.gnome.org/viewvc/libgweather?rev=144&view=rev
Log:
Deprecate libgweather/ChangeLog.
Add svn:ignore.
And:
2008-04-07 Vincent Untz <vuntz gnome org>
Add gweather-xml API. Patch by Dan Winship <danw gnome org>.
Fix bug #526015.
* configure.in: find libxml libs/cflags
* libgweather/gweather-xml.c: move this here from gweather/clock-applet
and fix the XML parser to skip over unrecognized close tags as well as
unrecognized open tags
* libgweather/Makefile.am (libgweather_la_SOURCES): add gweather-xml.c
(libgweatherinc_HEADERS): add gweather-xml.h
Added:
trunk/libgweather/gweather-xml.c
trunk/libgweather/gweather-xml.h
Modified:
trunk/ (props changed)
trunk/ChangeLog
trunk/configure.in
trunk/data/ (props changed)
trunk/libgweather/ (props changed)
trunk/libgweather/ChangeLog
trunk/libgweather/Makefile.am
trunk/po/ (props changed)
trunk/po-locations/ (props changed)
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Mon Apr 7 09:53:31 2008
@@ -8,6 +8,7 @@
GLIB_REQUIRED=2.13.0
GNOME_VFS_REQUIRED=2.15.4
GCONF_REQUIRED=2.8.0
+LIBXML_REQUIRED=2.6.0
AM_MAINTAINER_MODE
@@ -66,6 +67,11 @@
AC_SUBST(GTK_FLAGS)
AC_SUBST(GTK_LIBS)
+dnl -- Check for libxml (required) ------------------------------------------
+PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= $LIBXML_REQUIRED)
+AC_SUBST(LIBXML_FLAGS)
+AC_SUBST(LIBXML_LIBS)
+
dnl -- check for gnome-vfs (optional) -----------------------------------------
PKG_CHECK_MODULES(GNOME_VFS_APPLETS,
[gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED])
Modified: trunk/libgweather/Makefile.am
==============================================================================
--- trunk/libgweather/Makefile.am (original)
+++ trunk/libgweather/Makefile.am Mon Apr 7 09:53:31 2008
@@ -3,7 +3,7 @@
lib_LTLIBRARIES = libgweather.la
libgweatherincdir = $(includedir)/libgweather
-libgweatherinc_HEADERS = weather.h gweather-gconf.h gweather-prefs.h
+libgweatherinc_HEADERS = weather.h gweather-gconf.h gweather-prefs.h gweather-xml.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gweather.pc
@@ -14,20 +14,23 @@
weather-bom.c weather-wx.c \
weather-sun.c \
gweather-prefs.c gweather-prefs.h \
- gweather-gconf.c gweather-gconf.h
+ gweather-gconf.c gweather-gconf.h \
+ gweather-xml.c gweather-xml.h
libgweather_la_CFLAGS = \
-I$(top_srcdir) \
-I$(srcdir) \
$(WARN_CFLAGS) \
$(GTK_CFLAGS) \
+ $(LIBXML_CFLAGS) \
$(GNOME_VFS_APPLETS_CFLAGS) \
- $(GNOME_APPLETS_CFLAGS) \
-DG_LOG_DOMAIN=\"GWeather\" \
- -DGNOMELOCALEDIR=\""$(datadir)/locale"\"
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ -DGWEATHER_XML_LOCATION=\""$(pkgdatadir)/Locations.xml"\"
libgweather_la_LIBADD = \
$(GTK_LIBS) \
+ $(LIBXML_LIBS) \
$(GNOME_VFS_APPLETS_LIBS)
libgweather_la_LDFLAGS = \
@@ -40,12 +43,10 @@
-I$(srcdir) \
$(WARN_CFLAGS) \
$(GTK_CFLAGS) \
- $(GNOME_APPLETS_CFLAGS) \
$(GNOME_VFS_APPLETS_CFLAGS) \
-DG_LOG_DOMAIN=\"GWeather\"
test_metar_LDADD = \
- $(GNOME_APPLETS_LIB) \
$(GNOME_VFS_APPLETS_LIB) \
libgweather.la
Added: trunk/libgweather/gweather-xml.c
==============================================================================
--- (empty file)
+++ trunk/libgweather/gweather-xml.c Mon Apr 7 09:53:31 2008
@@ -0,0 +1,400 @@
+/* gweather-xml.c - Locations.xml parsing code
+ *
+ * Copyright (C) 2005 Ryan Lortie, 2004 Gareth Owen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/* There is very little error checking in the parsing code below, it relies
+ * heavily on the locations file being in the correct format. If you have
+ * <name> elements within a parent element, they must come first and be
+ * grouped together.
+ * The format is as follows:
+ *
+ * <gweather format="1.0">
+ * <region>
+ * <name>Name of the region</name>
+ * <name xml:lang="xx">Translated Name</name>
+ * <name xml:lang="zz">Another Translated Name</name>
+ * <country>
+ * <name>Name of the country</name>
+ * <location>
+ * <name>Name of the location</name>
+ * <code>IWIN code</code>
+ * <zone>Forecast code (North America, Australia, UK only)</zone>
+ * <radar>Weather.com radar map code (North America only)</radar>
+ * <coordinates>Latitude and longitude as DD-MM[-SS][H] pair</coordinates>
+ * </location>
+ * <state>
+ * <location>
+ * ....
+ * </location>
+ * <city>
+ * <name>Name of city with multiple locations</city>
+ * <zone>Forecast code</zone>
+ * <radar>Radar Map code</radar>
+ * <location>
+ * ...
+ * </location>
+ * </city>
+ * </state>
+ * </country>
+ * </region>
+ * <gweather>
+ *
+ * The thing to note is that each country can either contain different locations
+ * or be split into "states" which in turn contain a list of locations.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <locale.h>
+#include <gtk/gtk.h>
+#include <libxml/xmlreader.h>
+
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "gweather-xml.h"
+
+static gint
+gweather_xml_location_sort_func( GtkTreeModel *model, GtkTreeIter *a,
+ GtkTreeIter *b, gpointer user_data )
+{
+ gint res;
+ gchar *name_a, *name_b;
+ gchar *fold_a, *fold_b;
+
+ gtk_tree_model_get (model, a, GWEATHER_XML_COL_LOC, &name_a, -1);
+ gtk_tree_model_get (model, b, GWEATHER_XML_COL_LOC, &name_b, -1);
+
+ fold_a = g_utf8_casefold(name_a, -1);
+ fold_b = g_utf8_casefold(name_b, -1);
+
+ res = g_utf8_collate(fold_a, fold_b);
+
+ g_free(name_a);
+ g_free(name_b);
+ g_free(fold_a);
+ g_free(fold_b);
+
+ return res;
+}
+
+static char*
+gweather_xml_get_value( xmlTextReaderPtr xml )
+{
+ char* value;
+
+ /* check for null node */
+ if ( xmlTextReaderIsEmptyElement( xml ) )
+ return NULL;
+
+ /* the next "node" is the text node containing the value we want to get */
+ if( xmlTextReaderRead( xml ) != 1 )
+ return NULL;
+
+ value = (char *) xmlTextReaderValue( xml );
+
+ /* move on to the end of this node */
+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_END_ELEMENT )
+ if( xmlTextReaderRead( xml ) != 1 )
+ {
+ xmlFree( value );
+ return NULL;
+ }
+
+ /* consume the end element too */
+ if( xmlTextReaderRead( xml ) != 1 )
+ {
+ xmlFree( value );
+ return NULL;
+ }
+
+ return value;
+}
+
+static char *
+gweather_xml_parse_name( xmlTextReaderPtr xml )
+{
+ const char * const *locales;
+ const char *this_language;
+ int best_match = INT_MAX;
+ char *lang, *tagname;
+ gboolean keep_going;
+ char *name = NULL;
+ int i;
+
+ locales = g_get_language_names();
+
+ do
+ {
+ /* First let's get the language */
+ lang = (char *) xmlTextReaderXmlLang( xml );
+
+ if( lang == NULL )
+ this_language = "C";
+ else
+ this_language = lang;
+
+ /* the next "node" is text node containing the actual name */
+ if( xmlTextReaderRead( xml ) != 1 )
+ {
+ xmlFree( lang );
+ return NULL;
+ }
+
+ for( i = 0; locales[i] && i < best_match; i++ )
+ if( !strcmp( locales[i], this_language ) )
+ {
+ /* if we've already encounted a less accurate
+ translation, then free it */
+ xmlFree( name );
+
+ name = (char *) xmlTextReaderValue( xml );
+ best_match = i;
+
+ break;
+ }
+
+ xmlFree( lang );
+
+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT )
+ if( xmlTextReaderRead( xml ) != 1 )
+ {
+ xmlFree( name );
+ return NULL;
+ }
+
+ /* if the next tag is another <name> then keep going */
+ tagname = (char *) xmlTextReaderName( xml );
+ keep_going = !strcmp( tagname, "name" );
+ xmlFree( tagname );
+
+ } while( keep_going );
+
+ return name;
+}
+
+static gboolean
+gweather_xml_parse_node (xmlTextReaderPtr xml,
+ GtkTreeStore *store, GtkTreeIter *parent,
+ const char *dflt_radar, const char *dflt_zone,
+ const char *cityname)
+{
+ char *name, *code, *zone, *radar, *coordinates;
+ char **city, *nocity = NULL;
+ GtkTreeIter iter, *self;
+ gboolean is_location;
+ char *tagname;
+ gboolean ret = FALSE;
+ int tagtype;
+
+ if( (tagname = (char *) xmlTextReaderName( xml )) == NULL )
+ return FALSE;
+
+ if( !strcmp( tagname, "city" ) )
+ city = &name;
+ else
+ city = &nocity;
+
+ is_location = !strcmp( tagname, "location" );
+
+ /* if we're processing the top-level, then don't create a new iter */
+ if( !strcmp( tagname, "gweather" ) )
+ self = NULL;
+ else
+ {
+ self = &iter;
+ /* insert this node into the tree */
+ gtk_tree_store_append( store, self, parent );
+ }
+
+ xmlFree( tagname );
+
+ coordinates = NULL;
+ radar = NULL;
+ zone = NULL;
+ code = NULL;
+ name = NULL;
+
+ /* absorb the start tag */
+ if( xmlTextReaderRead( xml ) != 1 )
+ goto error_out;
+
+ /* start parsing the actual contents of the node */
+ while( (tagtype = xmlTextReaderNodeType( xml )) !=
+ XML_READER_TYPE_END_ELEMENT )
+ {
+
+ /* skip non-element types */
+ if( tagtype != XML_READER_TYPE_ELEMENT )
+ {
+ if( xmlTextReaderRead( xml ) != 1 )
+ goto error_out;
+
+ continue;
+ }
+
+ tagname = (char *) xmlTextReaderName( xml );
+
+ if( !strcmp( tagname, "region" ) || !strcmp( tagname, "country" ) ||
+ !strcmp( tagname, "state" ) || !strcmp( tagname, "city" ) ||
+ !strcmp( tagname, "location" ) )
+ {
+ /* recursively handle sub-sections */
+ if( !gweather_xml_parse_node( xml, store, self, radar, zone, *city ) )
+ goto error_out;
+ }
+ else if ( !strcmp( tagname, "name" ) )
+ {
+ xmlFree( name );
+ if( (name = gweather_xml_parse_name( xml )) == NULL )
+ goto error_out;
+ }
+ else if ( !strcmp( tagname, "code" ) )
+ {
+ xmlFree( code );
+ if( (code = gweather_xml_get_value( xml )) == NULL )
+ goto error_out;
+ }
+ else if ( !strcmp( tagname, "zone" ) )
+ {
+ xmlFree( zone );
+ if( (zone = gweather_xml_get_value( xml )) == NULL )
+ goto error_out;
+ }
+ else if ( !strcmp( tagname, "radar" ) )
+ {
+ xmlFree( radar );
+ if( (radar = gweather_xml_get_value( xml )) == NULL )
+ goto error_out;
+ }
+ else if ( !strcmp( tagname, "coordinates" ) )
+ {
+ xmlFree( coordinates );
+ if( (coordinates = gweather_xml_get_value( xml )) == NULL )
+ goto error_out;
+ }
+ else /* some strange tag */
+ {
+ /* skip past it */
+ char *junk;
+ junk = gweather_xml_get_value( xml );
+ if( junk )
+ xmlFree( junk );
+ }
+
+ xmlFree( tagname );
+ }
+
+ if( self )
+ gtk_tree_store_set( store, self, GWEATHER_XML_COL_LOC, name, -1 );
+
+ /* absorb the end tag. in the case of processing a <gweather> then 'self'
+ is NULL. In this case, we let this fail since we might be at EOF */
+ if( xmlTextReaderRead( xml ) != 1 && self )
+ goto error_out;
+
+ /* if this is an actual location, setup the WeatherLocation for it */
+ if( is_location )
+ {
+ WeatherLocation *new_loc;
+
+ if( cityname == NULL )
+ cityname = name;
+
+ if( radar != NULL )
+ dflt_radar = radar;
+
+ if( zone != NULL )
+ dflt_zone = zone;
+
+ new_loc = weather_location_new( cityname, code, dflt_zone,
+ dflt_radar, coordinates);
+
+ gtk_tree_store_set( store, &iter, GWEATHER_XML_COL_POINTER, new_loc, -1 );
+ }
+
+ ret = TRUE;
+
+error_out:
+ xmlFree( name );
+ xmlFree( code );
+ xmlFree( zone );
+ xmlFree( radar );
+ xmlFree( coordinates );
+
+ return ret;
+}
+
+GtkTreeModel *
+gweather_xml_load_locations( void )
+{
+ char *tagname, *format;
+ GtkTreeSortable *sortable;
+ GtkTreeStore *store = NULL;
+ xmlTextReaderPtr xml;
+ int keep_going;
+
+ /* Open the xml file containing the different locations */
+ xml = xmlNewTextReaderFilename (GWEATHER_XML_LOCATION);
+ if( xml == NULL )
+ return NULL;
+
+ /* fast forward to the first element */
+ do
+ {
+ /* if we encounter a problem here, exit right away */
+ if( xmlTextReaderRead( xml ) != 1 )
+ goto error_out;
+ } while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT );
+
+ /* check the name and format */
+ tagname = (char *) xmlTextReaderName( xml );
+ keep_going = tagname && !strcmp( tagname, "gweather" );
+ xmlFree( tagname );
+
+ if( !keep_going )
+ goto error_out;
+
+ format = (char *) xmlTextReaderGetAttribute( xml, (xmlChar *) "format" );
+ keep_going = format && !strcmp( format, "1.0" );
+ xmlFree( format );
+
+ if( !keep_going )
+ goto error_out;
+
+ store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
+
+ if (!gweather_xml_parse_node( xml, store, NULL, NULL, NULL, NULL ))
+ {
+ g_object_unref( store );
+ store = NULL;
+ goto error_out;
+ }
+
+ /* Sort the tree */
+ sortable = GTK_TREE_SORTABLE( store );
+ gtk_tree_sortable_set_default_sort_func( sortable,
+ &gweather_xml_location_sort_func,
+ NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id( sortable,
+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+ GTK_SORT_ASCENDING );
+error_out:
+ xmlFreeTextReader( xml );
+
+ return (GtkTreeModel *)store;
+}
Added: trunk/libgweather/gweather-xml.h
==============================================================================
--- (empty file)
+++ trunk/libgweather/gweather-xml.h Mon Apr 7 09:53:31 2008
@@ -0,0 +1,35 @@
+/* gweather-xml.h
+ *
+ * Copyright (C) 2004 Gareth Owen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __GWEATHER_XML_H__
+#define __GWEATHER_XML_H__
+
+#include <gtk/gtk.h>
+#include <libgweather/weather.h>
+
+enum
+{
+ GWEATHER_XML_COL_LOC = 0,
+ GWEATHER_XML_COL_POINTER,
+ GWEATHER_XML_NUM_COLUMNS
+};
+
+GtkTreeModel *gweather_xml_load_locations( void );
+
+#endif /* __GWEATHER_XML_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]