Add generic XML earch code
[viking/guyou.git] / src / vikxmlsearchtool.c
bloba38b34033b73d5094c7b89539b6675c7115d7c10
1 /*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Created by Quy Tonthat <qtonthat@gmail.com>
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <glib.h>
29 #include <glib/gstdio.h>
30 #include <glib/gprintf.h>
31 #include <glib/gi18n.h>
33 #include "viking.h"
34 #include "util.h"
35 #include "curl_download.h"
37 #include "vikxmlsearchtool.h"
40 static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass );
41 static void vik_xml_search_tool_init ( VikXmlSearchTool *vwd );
43 static void vik_xml_search_tool_finalize ( GObject *gob );
45 static int vik_xml_search_tool_get_coord ( VikSearchTool *self, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord );
47 typedef struct _VikXmlSearchToolPrivate VikXmlSearchToolPrivate;
49 struct _VikXmlSearchToolPrivate
51 gchar *url_format;
52 gchar *lat_path;
53 gchar *lon_path;
55 struct LatLon ll;
58 #define XML_SEARCH_TOOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
59 VIK_XML_SEARCH_TOOL_TYPE, \
60 VikXmlSearchToolPrivate))
62 GType vik_xml_search_tool_get_type()
64 static GType w_type = 0;
66 if (!w_type)
68 static const GTypeInfo w_info =
70 sizeof (VikXmlSearchToolClass),
71 NULL, /* base_init */
72 NULL, /* base_finalize */
73 (GClassInitFunc) vik_xml_search_tool_class_init,
74 NULL, /* class_finalize */
75 NULL, /* class_data */
76 sizeof (VikXmlSearchTool),
78 (GInstanceInitFunc) vik_xml_search_tool_init,
80 w_type = g_type_register_static ( VIK_SEARCH_TOOL_TYPE, "VikXmlSearchTool", &w_info, 0 );
83 return w_type;
86 enum
88 PROP_0,
90 PROP_URL_FORMAT,
91 PROP_LAT_PATH,
92 PROP_LON_PATH,
95 static void
96 xml_search_tool_set_property (GObject *object,
97 guint property_id,
98 const GValue *value,
99 GParamSpec *pspec)
101 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
102 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
104 switch (property_id)
106 case PROP_URL_FORMAT:
107 g_free (priv->url_format);
108 priv->url_format = g_value_dup_string (value);
109 break;
111 case PROP_LAT_PATH:
112 g_free (priv->lat_path);
113 priv->lat_path = g_value_dup_string (value);
114 break;
116 case PROP_LON_PATH:
117 g_free (priv->lon_path);
118 priv->lon_path = g_value_dup_string (value);
119 break;
121 default:
122 /* We don't have any other property... */
123 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
124 break;
128 static void
129 xml_search_tool_get_property (GObject *object,
130 guint property_id,
131 GValue *value,
132 GParamSpec *pspec)
134 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
135 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
137 switch (property_id)
139 case PROP_URL_FORMAT:
140 g_value_set_string (value, priv->url_format);
141 break;
143 case PROP_LAT_PATH:
144 g_value_set_string (value, priv->lat_path);
145 break;
147 case PROP_LON_PATH:
148 g_value_set_string (value, priv->lon_path);
149 break;
151 default:
152 /* We don't have any other property... */
153 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
154 break;
158 static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass )
160 GObjectClass *object_class;
161 VikSearchToolClass *parent_class;
162 GParamSpec *pspec;
164 object_class = G_OBJECT_CLASS (klass);
166 object_class->finalize = vik_xml_search_tool_finalize;
167 object_class->set_property = xml_search_tool_set_property;
168 object_class->get_property = xml_search_tool_get_property;
171 pspec = g_param_spec_string ("url-format",
172 "URL format",
173 "The format of the URL",
174 "<no-set>" /* default value */,
175 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
176 g_object_class_install_property (object_class,
177 PROP_URL_FORMAT,
178 pspec);
180 pspec = g_param_spec_string ("lat-path",
181 "Lat path",
182 "XPath of the latitude",
183 "<no-set>" /* default value */,
184 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
185 g_object_class_install_property (object_class,
186 PROP_LAT_PATH,
187 pspec);
189 pspec = g_param_spec_string ("lon-path",
190 "Lon path",
191 "XPath of the longitude",
192 "<no-set>" /* default value */,
193 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
194 g_object_class_install_property (object_class,
195 PROP_LON_PATH,
196 pspec);
198 parent_class = VIK_SEARCH_TOOL_CLASS (klass);
200 parent_class->get_coord = vik_xml_search_tool_get_coord;
202 g_type_class_add_private (klass, sizeof (VikXmlSearchToolPrivate));
205 VikXmlSearchTool *vik_xml_search_tool_new ()
207 return VIK_XML_SEARCH_TOOL ( g_object_new ( VIK_XML_SEARCH_TOOL_TYPE, "label", "Google", NULL ) );
210 static void vik_xml_search_tool_init ( VikXmlSearchTool *self )
212 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
213 priv->url_format = NULL;
214 priv->lat_path = NULL;
215 priv->lon_path = NULL;
218 static void vik_xml_search_tool_finalize ( GObject *gob )
220 G_OBJECT_GET_CLASS(gob)->finalize(gob);
223 static gboolean
224 stack_is_path (const GSList *stack,
225 const gchar *path)
227 gboolean equal = FALSE;
228 // TODO
229 return equal;
232 /* Called for character data */
233 /* text is not nul-terminated */
234 static void
235 _text (GMarkupParseContext *context,
236 const gchar *text,
237 gsize text_len,
238 gpointer user_data,
239 GError **error)
241 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (user_data);
242 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
243 const GSList *stack = g_markup_parse_context_get_element_stack (context);
244 if (stack_is_path (stack, priv->lat_path))
246 // TODO priv->ll.lat = g_ascii_strtod(text, NULL);
248 if (stack_is_path (stack, priv->lon_path))
250 // TODO priv->ll.lon = g_ascii_strtod(text, NULL);
254 static gboolean
255 parse_file_for_latlon(VikXmlSearchTool *self, gchar *filename, struct LatLon *ll)
257 GMarkupParser xml_parser;
258 GMarkupParseContext *xml_context;
259 GError *error;
261 FILE *file = g_fopen (filename, "r");
262 if (file == NULL)
263 /* TODO emit warning */
264 return FALSE;
266 /* setup context parse (ie callbacks) */
267 xml_parser.start_element = NULL;
268 xml_parser.end_element = NULL;
269 xml_parser.text = &_text;
270 xml_parser.passthrough = NULL;
271 xml_parser.error = NULL;
273 xml_context = g_markup_parse_context_new(&xml_parser, 0, self, NULL);
275 gchar buff[BUFSIZ];
276 size_t nb;
277 while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
279 if (!g_markup_parse_context_parse(xml_context, buff, nb, &error))
280 printf("read_xml() : parsing error.\n");
282 /* cleanup */
283 if (!g_markup_parse_context_end_parse(xml_context, &error))
284 printf("read_xml() : errors occurred reading file.\n");
286 g_markup_parse_context_free(xml_context);
287 fclose (file);
289 if (ll != NULL)
291 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
292 *ll = priv->ll;
295 return TRUE;
298 static int vik_xml_search_tool_get_coord ( VikSearchTool *object, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord )
300 FILE *tmp_file;
301 int tmp_fd;
302 gchar *tmpname;
303 gchar *uri;
304 gchar *escaped_srch_str;
305 int ret = 0; /* OK */
306 struct LatLon ll;
308 g_debug("%s: raw search: %s", __FUNCTION__, srch_str);
310 escaped_srch_str = uri_escape(srch_str);
312 g_debug("%s: escaped search: %s", __FUNCTION__, escaped_srch_str);
314 if ((tmp_fd = g_file_open_tmp ("vikxmlsearch.XXXXXX", &tmpname, NULL)) == -1) {
315 g_critical(_("couldn't open temp file"));
316 exit(1);
319 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
320 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
322 tmp_file = fdopen(tmp_fd, "r+");
323 uri = g_strdup_printf(priv->url_format, escaped_srch_str);
325 /* TODO: curl may not be available */
326 if (curl_download_uri(uri, tmp_file, NULL)) { /* error */
327 fclose(tmp_file);
328 tmp_file = NULL;
329 ret = -1;
330 goto done;
333 fclose(tmp_file);
334 tmp_file = NULL;
335 if (!parse_file_for_latlon(self, tmpname, &ll)) {
336 ret = -1;
337 goto done;
340 vik_coord_load_from_latlon ( coord, vik_viewport_get_coord_mode(vvp), &ll );
342 done:
343 g_free(escaped_srch_str);
344 g_free(uri);
345 g_remove(tmpname);
346 g_free(tmpname);
347 return ret;