tune.c
changeset 29 23fa36d480fb
child 31 e404cd1c7077
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tune.c	Sun May 20 22:15:51 2012 +0300
@@ -0,0 +1,302 @@
+
+/* Copyright 2009-2012 Myhailo Danylenko
+ *
+ * This file is part of mcabber-pep
+ *
+ * mcabber-pep 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, see <http://www.gnu.org/licenses/>. */
+
+#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/roster.h>
+#include <mcabber/hbuf.h>      // HBUF_PREFIX_*
+#include <mcabber/hooks.h>
+#include <mcabber/modules.h>
+
+#include "tune.h"
+
+#include "config.h"
+
+//
+//  module description
+//
+
+void tune_init   (void);
+void tune_uninit (void);
+
+#define DESCRIPTION ( \
+	"User interface for PEP tune events\n" \
+	"Prints incoming notifications into buddies buffers\n" \
+	"Provides command /tune" )
+
+static const gchar *deps[] = { "pep_tune", NULL };
+
+static module_info_t info_tune_dev = {
+	.branch      = "dev",
+	.api         = 20,
+	.version     = PROJECT_VERSION,
+	.description = DESCRIPTION,
+	.requires    = deps,
+	.init        = tune_init,
+	.uninit      = tune_uninit,
+	.next        = NULL,
+};
+
+static module_info_t info_tune_0_10_0 = {
+	.branch      = "0.10.0",
+	.api         = 1,
+	.version     = PROJECT_VERSION,
+	.description = DESCRIPTION,
+	.requires    = deps,
+	.init        = tune_init,
+	.uninit      = tune_uninit,
+	.next        = &info_tune_dev,
+};
+
+module_info_t info_tune = {
+	.branch      = "0.10.1",
+	.api         = 1,
+	.version     = PROJECT_VERSION,
+	.description = DESCRIPTION,
+	.requires    = deps,
+	.init        = tune_init,
+	.uninit      = tune_uninit,
+	.next        = &info_tune_0_10_0,
+};
+
+//
+//  globals
+//
+
+#ifdef MCABBER_API_HAVE_CMD_ID
+static gpointer tune_cmid     = NULL;
+static gboolean tune_set_safe = FALSE;
+#endif
+
+static guint tune_cid        = 0;
+static guint tune_hid_tunein = 0;
+
+//
+//  code
+//
+
+static void do_tune (char *arg)
+{
+	hk_arg_t tags[] = {
+		{ "artist", NULL },
+		{ "length", NULL },
+		{ "rating", NULL },
+		{ "source", NULL },
+		{ "title",  NULL },
+		{ "track",  NULL },
+		{ "uri",    NULL },
+		{ NULL,     NULL },
+	};
+
+	if (!*arg) { // request
+
+		GError *error = NULL;
+
+		tune_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." ); // XXX
+
+		return;
+
+	} else if (arg[0] != '-' || arg[1] != '\0') { 
+
+		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 = argstop
+// 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
+					hk_arg_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
+					hk_arg_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_TUNE_OUT, tags );
+
+	{
+		hk_arg_t *tag;
+
+		for (tag = tags; tag->name; ++tag)
+			g_free ( (gchar *) tag->value );
+	}
+}
+
+static guint tune_htih ( const gchar *htype, hk_arg_t *args, gpointer udata )
+{
+	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 listens to:");
+	else
+		g_string_overwrite (mesg, 0, "Now listening to nothing");
+
+	{ // 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 tune_init(void)
+{
+	tune_cid = compl_new_category ();
+	if (tune_cid) {
+		compl_add_category_word (tune_cid, "artist=");
+		compl_add_category_word (tune_cid, "length=");
+		compl_add_category_word (tune_cid, "rating=");
+		compl_add_category_word (tune_cid, "source=");
+		compl_add_category_word (tune_cid, "title=");
+		compl_add_category_word (tune_cid, "track=");
+		compl_add_category_word (tune_cid, "uri=");
+	}
+
+#ifndef MCABBER_API_HAVE_CMD_ID
+	cmd_add ("tune", "", tune_cid, tune_cid, do_tune, NULL);
+#else
+	tune_cmid     = cmd_add ("tune", "", tune_cid, tune_cid, do_tune, NULL);
+	tune_set_safe = cmd_set_safe ("tune", TRUE);
+#endif
+
+	tune_hid_tunein = hk_add_handler (tune_htih, HOOK_TUNE_IN, G_PRIORITY_DEFAULT, NULL);
+}
+
+void tune_uninit(void)
+{
+	hk_del_handler (HOOK_TUNE_IN, tune_hid_tunein);
+
+#ifndef MCABBER_API_HAVE_CMD_ID
+	cmd_del ("tune");
+#else
+	if (tune_cmid)
+		cmd_del (tune_cmid);
+	if (tune_set_safe)
+		cmd_set_safe ("tune", FALSE);
+#endif
+
+	if (tune_cid)
+		compl_del_category (tune_cid);
+}
+
+/* vim: se ts=4 sw=4: */