--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/geoloc.c Sun May 20 22:15:51 2012 +0300
@@ -0,0 +1,323 @@
+/*
+ * geoloc.c -- Pep geographical location events
+ *
+ * Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net>
+ *
+ * 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
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include <mcabber/commands.h>
+#include <mcabber/compl.h>
+#include <mcabber/utils.h>
+#include <mcabber/screen.h>
+#include <mcabber/logprint.h>
+#include <mcabber/hbuf.h> // HBUF_PREFIX_*
+#include <mcabber/roster.h>
+#include <mcabber/hooks.h>
+#include <mcabber/modules.h>
+
+#include "geoloc.h"
+
+#include "config.h"
+
+//
+// module description
+//
+
+void geoloc_init (void);
+void geoloc_uninit (void);
+
+#define DESCRIPTION ( \
+ "PEP geoloc event handling\n" \
+ "Provides command /geoloc" )
+
+static const gchar *deps[] = { "pep_geoloc", NULL };
+
+static module_info_t info_geoloc_dev = {
+ .branch = "dev",
+ .api = 20,
+ .version = PROJECT_VERSION,
+ .description = DESCRIPTION,
+ .requires = deps,
+ .init = geoloc_init,
+ .uninit = geoloc_uninit,
+ .next = NULL,
+};
+
+module_info_t info_geoloc = {
+ .branch = "0.10.1",
+ .api = 1,
+ .version = PROJECT_VERSION,
+ .description = DESCRIPTION,
+ .requires = deps,
+ .init = geoloc_init,
+ .uninit = geoloc_uninit,
+ .next = &info_geoloc_dev,
+};
+
+//
+// globals
+//
+
+#ifdef MCABBER_API_HAVE_CMD_ID
+static gpointer geoloc_cmid = NULL;
+static gboolean geoloc_set_safe = FALSE;
+#endif
+
+static guint geoloc_cid = 0;
+static guint geoloc_hid_geolocin = 0;
+
+//
+// code
+//
+
+static void do_geoloc (char *arg)
+{
+ geoloc_pair_t tags[] = {
+ { "accuracy", NULL },
+ { "alt", NULL },
+ { "area", NULL },
+ { "bearing", NULL },
+ { "building", NULL },
+ { "country", NULL },
+ { "countrycode", NULL },
+ { "datum", NULL },
+ { "description", NULL },
+ { "error", NULL },
+ { "floor", NULL },
+ { "lat", NULL },
+ { "locality", NULL },
+ { "lon", NULL },
+ { "postalcode", NULL },
+ { "region", NULL },
+ { "room", NULL },
+ { "speed", NULL },
+ { "street", NULL },
+ { "text", NULL },
+ { "timestamp", NULL },
+ { "uri", NULL },
+ { NULL, NULL },
+ };
+
+ if (!*arg) { // request
+
+ GError *error = NULL;
+
+ geoloc_request ( CURRENT_JID, &error );
+ if ( error ) {
+ scr_log_print ( LPRINT_NORMAL, "Error sending request: %s.", error -> message );
+ g_error_free ( error );
+ } else
+ scr_log_print ( LPRINT_NORMAL, "Request sent." );
+
+ return;
+
+ } else if (arg[0] != '-' || arg[1] != '\0') { // publish
+
+ char *p;
+ char *argstart = NULL;
+ char *argstop = NULL;
+ char *tagstart = NULL;
+ char *tagstop = NULL;
+ char *wordstart = arg;
+ gboolean proceed = TRUE;
+
+// pt = p, ws = wordstart, ts = tagstart, tt = tagstop, as = argstart, at = arstop
+// tag=value value tag=value
+// w p
+// s t
+// t ta
+// s t*
+// tag=value value tag=value
+// t ta p
+// s t* t
+// t ta aw
+// s ts ts
+// tag=value value tag=value
+// t ta aw p
+// s ts ts t
+// t ta aw
+// s ts ts
+// tag=value value tag=value
+// t ta aw p
+// s ts ts t
+// t ta
+// s t*
+// tag=value value tag=value
+// t ta p
+// s t* t
+// t ta a
+// s ts t
+
+ for (p = arg; proceed; ++p) {
+ switch (*p) {
+ case '=':
+ if (tagstart && tagstop - tagstart) {
+ // process previous args
+ geoloc_pair_t *tag;
+
+ for (tag = tags; tag->name; ++tag) {
+ if (!strncmp (tag->name, tagstart, tagstop - tagstart)) {
+ g_free ( (gchar *) tag -> value );
+ if (argstop - argstart) {
+ *argstop = '\0';
+ tag->value = to_utf8 (argstart);
+ }
+ break;
+ }
+ }
+ }
+
+ tagstart = wordstart;
+ tagstop = p;
+ argstop = p+1;
+ argstart = p+1;
+ break;
+
+ case '\0':
+ argstop = p;
+
+ if (tagstop - tagstart) {
+ // process previous args
+ geoloc_pair_t *tag;
+
+ for (tag = tags; tag->name; ++tag) {
+ if (!strncmp (tag->name, tagstart, tagstop - tagstart)) {
+ g_free ( (gchar *) tag -> value );
+ if (argstop - argstart)
+ tag->value = to_utf8 (argstart);
+ break;
+ }
+ }
+ }
+
+ proceed = FALSE;
+ break;
+
+ case ' ':
+ argstop = p;
+ wordstart = p+1;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ hk_run_handlers ( HOOK_GEOLOC_OUT, (hk_arg_t *) tags );
+
+ {
+ geoloc_pair_t *tag;
+
+ for ( tag = tags; tag -> name; ++ tag )
+ g_free ( (gchar *) tag -> value );
+ }
+}
+
+static guint geoloc_hgih ( const gchar *hid, hk_arg_t *args, gpointer userdata )
+{
+ GString *mesg = g_string_new (NULL);
+ const gchar *from = NULL;
+
+ {
+ hk_arg_t *arg;
+ for ( arg = args; arg -> name; ++ arg )
+ if ( arg -> value ) {
+ if ( ! strcmp ( arg -> name, "from" ) )
+ from = arg -> value;
+ else
+ g_string_append_printf ( mesg, "\n - %s: %s", arg -> name, arg -> value);
+ }
+ }
+
+ if (mesg->len)
+ g_string_prepend (mesg, "Now located at:");
+ else
+ g_string_overwrite (mesg, 0, "No location information.");
+
+ { // print to buddy's buffer
+ gchar *jid = jidtodisp (from);
+
+ scr_write_incoming_message (jid, mesg->str, 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
+
+ g_free (jid);
+ }
+
+ g_string_free (mesg, TRUE);
+
+ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
+
+void geoloc_init ( void )
+{
+ geoloc_cid = compl_new_category ();
+ if (geoloc_cid) {
+ compl_add_category_word (geoloc_cid, "accuracy=");
+ compl_add_category_word (geoloc_cid, "alt=");
+ compl_add_category_word (geoloc_cid, "area=");
+ compl_add_category_word (geoloc_cid, "bearing=");
+ compl_add_category_word (geoloc_cid, "building=");
+ compl_add_category_word (geoloc_cid, "country=");
+ compl_add_category_word (geoloc_cid, "countrycode=");
+ compl_add_category_word (geoloc_cid, "datum=");
+ compl_add_category_word (geoloc_cid, "description=");
+ compl_add_category_word (geoloc_cid, "error=");
+ compl_add_category_word (geoloc_cid, "floor=");
+ compl_add_category_word (geoloc_cid, "lat=");
+ compl_add_category_word (geoloc_cid, "locality=");
+ compl_add_category_word (geoloc_cid, "lon=");
+ compl_add_category_word (geoloc_cid, "postalcode=");
+ compl_add_category_word (geoloc_cid, "region=");
+ compl_add_category_word (geoloc_cid, "room=");
+ compl_add_category_word (geoloc_cid, "speed=");
+ compl_add_category_word (geoloc_cid, "street=");
+ compl_add_category_word (geoloc_cid, "text=");
+ compl_add_category_word (geoloc_cid, "timestamp=");
+ compl_add_category_word (geoloc_cid, "uri=");
+ }
+
+#ifndef MCABBER_API_HAVE_CMD_ID
+ cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL);
+#else
+ geoloc_cmid = cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL);
+ geoloc_set_safe = cmd_set_safe ("geoloc", TRUE);
+#endif
+
+ geoloc_hid_geolocin = hk_add_handler (geoloc_hgih, HOOK_GEOLOC_IN, G_PRIORITY_DEFAULT, NULL);
+}
+
+void geoloc_uninit ( void )
+{
+ hk_del_handler (HOOK_GEOLOC_IN, geoloc_hid_geolocin);
+
+#ifndef MCABBER_API_HAVE_CMD_ID
+ cmd_del ("geoloc");
+#else
+ if (geoloc_cmid)
+ cmd_del (geoloc_cmid);
+ if (geoloc_set_safe)
+ cmd_set_safe ("geoloc", FALSE);
+#endif
+
+ if (geoloc_cid)
+ compl_del_category (geoloc_cid);
+}
+
+/* vim: se ts=4 sw=4: */