/*
* 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 "pep_geoloc.h"
#include "config.h"
//
// module description
//
void geoloc_init (void);
void geoloc_uninit (void);
#define DESCRIPTION ( GEOLOC_DESCRIPTION )
static const gchar *deps[] = { "pep_geoloc", NULL };
module_info_t info_geoloc = {
.branch = MCABBER_BRANCH,
.api = MCABBER_API_VERSION,
.version = PROJECT_VERSION,
.description = DESCRIPTION,
.requires = deps,
.init = geoloc_init,
.uninit = geoloc_uninit,
.next = NULL,
};
//
// 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;
pep_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 )
{
#ifdef HAVE_MCABBER_COMPLETION_FLAGS
geoloc_cid = compl_new_category (COMPL_FLAGS_SORT);
#else
geoloc_cid = compl_new_category ();
#endif
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: */