geoloc.c
changeset 29 23fa36d480fb
child 31 e404cd1c7077
equal deleted inserted replaced
28:c035fbbab184 29:23fa36d480fb
       
     1 /*
       
     2  * geoloc.c             -- Pep geographical location events
       
     3  *
       
     4  * Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net>
       
     5  *
       
     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 (at
       
     9  * your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful, but
       
    12  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  * General Public License for more details.
       
    15  *
       
    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
       
    19  * USA
       
    20  */
       
    21 
       
    22 #include <glib.h>
       
    23 #include <string.h>
       
    24 
       
    25 #include <mcabber/commands.h>
       
    26 #include <mcabber/compl.h>
       
    27 #include <mcabber/utils.h>
       
    28 #include <mcabber/screen.h>
       
    29 #include <mcabber/logprint.h>
       
    30 #include <mcabber/hbuf.h>        // HBUF_PREFIX_*
       
    31 #include <mcabber/roster.h>
       
    32 #include <mcabber/hooks.h>
       
    33 #include <mcabber/modules.h>
       
    34 
       
    35 #include "geoloc.h"
       
    36 
       
    37 #include "config.h"
       
    38 
       
    39 //
       
    40 //  module description
       
    41 //
       
    42 
       
    43 void geoloc_init   (void);
       
    44 void geoloc_uninit (void);
       
    45 
       
    46 #define DESCRIPTION ( \
       
    47 	"PEP geoloc event handling\n" \
       
    48 	"Provides command /geoloc" )
       
    49 
       
    50 static const gchar *deps[] = { "pep_geoloc", NULL };
       
    51 
       
    52 static module_info_t info_geoloc_dev = {
       
    53 	.branch      = "dev",
       
    54 	.api         = 20,
       
    55 	.version     = PROJECT_VERSION,
       
    56 	.description = DESCRIPTION,
       
    57 	.requires    = deps,
       
    58 	.init        = geoloc_init,
       
    59 	.uninit      = geoloc_uninit,
       
    60 	.next        = NULL,
       
    61 };
       
    62 
       
    63 module_info_t info_geoloc = {
       
    64 	.branch      = "0.10.1",
       
    65 	.api         = 1,
       
    66 	.version     = PROJECT_VERSION,
       
    67 	.description = DESCRIPTION,
       
    68 	.requires    = deps,
       
    69 	.init        = geoloc_init,
       
    70 	.uninit      = geoloc_uninit,
       
    71 	.next        = &info_geoloc_dev,
       
    72 };
       
    73 
       
    74 //
       
    75 //  globals
       
    76 //
       
    77 
       
    78 #ifdef MCABBER_API_HAVE_CMD_ID
       
    79 static gpointer geoloc_cmid     = NULL;
       
    80 static gboolean geoloc_set_safe = FALSE;
       
    81 #endif
       
    82 
       
    83 static guint geoloc_cid          = 0;
       
    84 static guint geoloc_hid_geolocin = 0;
       
    85 
       
    86 //
       
    87 //  code
       
    88 //
       
    89 
       
    90 static void do_geoloc (char *arg)
       
    91 {
       
    92 	geoloc_pair_t tags[] = {
       
    93 		{ "accuracy",    NULL },
       
    94 		{ "alt",         NULL },
       
    95 		{ "area",        NULL },
       
    96 		{ "bearing",     NULL },
       
    97 		{ "building",    NULL },
       
    98 		{ "country",     NULL },
       
    99 		{ "countrycode", NULL },
       
   100 		{ "datum",       NULL },
       
   101 		{ "description", NULL },
       
   102 		{ "error",       NULL },
       
   103 		{ "floor",       NULL },
       
   104 		{ "lat",         NULL },
       
   105 		{ "locality",    NULL },
       
   106 		{ "lon",         NULL },
       
   107 		{ "postalcode",  NULL },
       
   108 		{ "region",      NULL },
       
   109 		{ "room",        NULL },
       
   110 		{ "speed",       NULL },
       
   111 		{ "street",      NULL },
       
   112 		{ "text",        NULL },
       
   113 		{ "timestamp",   NULL },
       
   114 		{ "uri",         NULL },
       
   115 		{ NULL,          NULL },
       
   116 	};
       
   117 
       
   118 	if (!*arg) { // request
       
   119 
       
   120 		GError *error = NULL;
       
   121 
       
   122 		geoloc_request ( CURRENT_JID, &error );
       
   123 		if ( error ) {
       
   124 			scr_log_print ( LPRINT_NORMAL, "Error sending request: %s.", error -> message );
       
   125 			g_error_free ( error );
       
   126 		} else
       
   127 			scr_log_print ( LPRINT_NORMAL, "Request sent." );
       
   128 
       
   129 		return;
       
   130 
       
   131 	} else if (arg[0] != '-' || arg[1] != '\0') { // publish
       
   132 
       
   133 		char          *p;
       
   134 		char          *argstart  = NULL;
       
   135 		char          *argstop   = NULL;
       
   136 		char          *tagstart  = NULL;
       
   137 		char          *tagstop   = NULL;
       
   138 		char          *wordstart = arg;
       
   139 		gboolean       proceed   = TRUE;
       
   140 
       
   141 // pt = p, ws = wordstart, ts = tagstart, tt = tagstop, as = argstart, at = arstop
       
   142 // tag=value value tag=value
       
   143 // w  p
       
   144 // s  t
       
   145 // t  ta
       
   146 // s  t*
       
   147 // tag=value value tag=value
       
   148 // t  ta    p
       
   149 // s  t*    t
       
   150 // t  ta    aw
       
   151 // s  ts    ts
       
   152 // tag=value value tag=value
       
   153 // t  ta    aw    p
       
   154 // s  ts    ts    t
       
   155 // t  ta          aw
       
   156 // s  ts          ts
       
   157 // tag=value value tag=value
       
   158 // t  ta          aw  p
       
   159 // s  ts          ts  t
       
   160 //                 t  ta
       
   161 //                 s  t*
       
   162 // tag=value value tag=value
       
   163 //                 t  ta    p
       
   164 //                 s  t*    t
       
   165 //                 t  ta    a
       
   166 //                 s  ts    t
       
   167 
       
   168 		for (p = arg; proceed; ++p) {
       
   169 			switch (*p) {
       
   170 			case '=':
       
   171 				if (tagstart && tagstop - tagstart) {
       
   172 					// process previous args
       
   173 					geoloc_pair_t *tag;
       
   174 
       
   175 					for (tag = tags; tag->name; ++tag) {
       
   176 						if (!strncmp (tag->name, tagstart, tagstop - tagstart)) {
       
   177 							g_free ( (gchar *) tag -> value );
       
   178 							if (argstop - argstart) {
       
   179 								*argstop = '\0';
       
   180 								tag->value = to_utf8 (argstart);
       
   181 							}
       
   182 							break;
       
   183 						}
       
   184 					}
       
   185 				}
       
   186 
       
   187 				tagstart = wordstart;
       
   188 				tagstop = p;
       
   189 				argstop = p+1;
       
   190 				argstart = p+1;
       
   191 				break;
       
   192 
       
   193 			case '\0':
       
   194 				argstop = p;
       
   195 
       
   196 				if (tagstop - tagstart) {
       
   197 					// process previous args
       
   198 					geoloc_pair_t *tag;
       
   199 
       
   200 					for (tag = tags; tag->name; ++tag) {
       
   201 						if (!strncmp (tag->name, tagstart, tagstop - tagstart)) {
       
   202 							g_free ( (gchar *) tag -> value );
       
   203 							if (argstop - argstart)
       
   204 								tag->value = to_utf8 (argstart);
       
   205 							break;
       
   206 						}
       
   207 					}
       
   208 				}
       
   209 
       
   210 				proceed = FALSE;
       
   211 				break;
       
   212 
       
   213 			case ' ':
       
   214 				argstop = p;
       
   215 				wordstart = p+1;
       
   216 				break;
       
   217 
       
   218 			default:
       
   219 				break;
       
   220 			}
       
   221 		}
       
   222 	}
       
   223 
       
   224 	hk_run_handlers ( HOOK_GEOLOC_OUT, (hk_arg_t *) tags );
       
   225 
       
   226 	{
       
   227 		geoloc_pair_t *tag;
       
   228 
       
   229 		for ( tag = tags; tag -> name; ++ tag )
       
   230 			g_free ( (gchar *) tag -> value );
       
   231 	}
       
   232 }
       
   233 
       
   234 static guint geoloc_hgih ( const gchar *hid, hk_arg_t *args, gpointer userdata )
       
   235 {
       
   236 	GString     *mesg = g_string_new (NULL);
       
   237 	const gchar *from = NULL;
       
   238 
       
   239 	{
       
   240 		hk_arg_t *arg;
       
   241 		for ( arg = args; arg -> name; ++ arg )
       
   242 			if ( arg -> value ) {
       
   243 				if ( ! strcmp ( arg -> name, "from" ) )
       
   244 					from = arg -> value;
       
   245 				else
       
   246 					g_string_append_printf ( mesg, "\n - %s: %s", arg -> name, arg -> value);
       
   247 			}
       
   248 	}
       
   249 
       
   250 	if (mesg->len)
       
   251 		g_string_prepend (mesg, "Now located at:");
       
   252 	else
       
   253 		g_string_overwrite (mesg, 0, "No location information.");
       
   254 
       
   255 	{ // print to buddy's buffer
       
   256 		gchar *jid = jidtodisp (from);
       
   257 
       
   258 		scr_write_incoming_message (jid, mesg->str, 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
       
   259 
       
   260 		g_free (jid);
       
   261 	}
       
   262 
       
   263 	g_string_free (mesg, TRUE);
       
   264 
       
   265 	return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   266 }
       
   267 
       
   268 void geoloc_init ( void )
       
   269 {
       
   270 	geoloc_cid = compl_new_category ();
       
   271 	if (geoloc_cid) {
       
   272 		compl_add_category_word (geoloc_cid, "accuracy=");
       
   273 		compl_add_category_word (geoloc_cid, "alt=");
       
   274 		compl_add_category_word (geoloc_cid, "area=");
       
   275 		compl_add_category_word (geoloc_cid, "bearing=");
       
   276 		compl_add_category_word (geoloc_cid, "building=");
       
   277 		compl_add_category_word (geoloc_cid, "country=");
       
   278 		compl_add_category_word (geoloc_cid, "countrycode=");
       
   279 		compl_add_category_word (geoloc_cid, "datum=");
       
   280 		compl_add_category_word (geoloc_cid, "description=");
       
   281 		compl_add_category_word (geoloc_cid, "error=");
       
   282 		compl_add_category_word (geoloc_cid, "floor=");
       
   283 		compl_add_category_word (geoloc_cid, "lat=");
       
   284 		compl_add_category_word (geoloc_cid, "locality=");
       
   285 		compl_add_category_word (geoloc_cid, "lon=");
       
   286 		compl_add_category_word (geoloc_cid, "postalcode=");
       
   287 		compl_add_category_word (geoloc_cid, "region=");
       
   288 		compl_add_category_word (geoloc_cid, "room=");
       
   289 		compl_add_category_word (geoloc_cid, "speed=");
       
   290 		compl_add_category_word (geoloc_cid, "street=");
       
   291 		compl_add_category_word (geoloc_cid, "text=");
       
   292 		compl_add_category_word (geoloc_cid, "timestamp=");
       
   293 		compl_add_category_word (geoloc_cid, "uri=");
       
   294 	}
       
   295 
       
   296 #ifndef MCABBER_API_HAVE_CMD_ID
       
   297 	cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL);
       
   298 #else
       
   299 	geoloc_cmid     = cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL);
       
   300 	geoloc_set_safe = cmd_set_safe ("geoloc", TRUE);
       
   301 #endif
       
   302 
       
   303 	geoloc_hid_geolocin = hk_add_handler (geoloc_hgih, HOOK_GEOLOC_IN, G_PRIORITY_DEFAULT, NULL);
       
   304 }
       
   305 
       
   306 void geoloc_uninit ( void )
       
   307 {
       
   308 	hk_del_handler (HOOK_GEOLOC_IN, geoloc_hid_geolocin);
       
   309 
       
   310 #ifndef MCABBER_API_HAVE_CMD_ID
       
   311 	cmd_del ("geoloc");
       
   312 #else
       
   313 	if (geoloc_cmid)
       
   314 		cmd_del (geoloc_cmid);
       
   315 	if (geoloc_set_safe)
       
   316 		cmd_set_safe ("geoloc", FALSE);
       
   317 #endif
       
   318 
       
   319 	if (geoloc_cid)
       
   320 		compl_del_category (geoloc_cid);
       
   321 }
       
   322 
       
   323 /* vim: se ts=4 sw=4: */