Map gstreamer over dbus tags into xmpp tune tags.
[cascardo/pubsub-bot.git] / status.c
index db14f74..2c78898 100644 (file)
--- a/status.c
+++ b/status.c
@@ -23,6 +23,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 static char * server = "vespa.holoscopio.com";
 static char * username = "pubsub";
@@ -30,7 +32,7 @@ static char * password = "pubsub";
 static char * pbservice = "pubsub.vespa.holoscopio.com";
 static char * authed_jid = "vespa";
 
-iks *
+static iks *
 createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
 {
   static int id = 0;
@@ -46,7 +48,7 @@ createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
   return iq;
 }
 
-void
+static void
 catnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -59,7 +61,7 @@ catnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 listnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -72,7 +74,7 @@ listnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 createnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -84,7 +86,7 @@ createnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 getnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -96,7 +98,7 @@ getnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 vcard (iksparser *parser)
 {
   iks *iq;
@@ -106,7 +108,7 @@ vcard (iksparser *parser)
   iks_delete (iq);
 }
 
-iks *
+static iks *
 createmood (char *line)
 {
   iks *mood;
@@ -116,7 +118,7 @@ createmood (char *line)
   return mood;
 }
 
-void
+static void
 pushmood (iksparser *parser, char *node, char *line)
 {
   iks *iq;
@@ -135,7 +137,7 @@ pushmood (iksparser *parser, char *node, char *line)
   iks_delete (iq);
 }
 
-iks *
+static iks *
 createtune (char *line)
 {
   iks *tune;
@@ -145,7 +147,7 @@ createtune (char *line)
   return tune;
 }
 
-void
+static void
 pushtune (iksparser *parser, char *node, iks *tune)
 {
   iks *iq;
@@ -164,7 +166,7 @@ pushtune (iksparser *parser, char *node, iks *tune)
 }
 
 
-void
+static void
 process_mood (iksparser *parser, char *cmdline)
 {
   char *cmd;
@@ -198,7 +200,7 @@ process_mood (iksparser *parser, char *cmdline)
   free (orig_cmdline);
 }
 
-int
+static int
 xmpp_session_hook (iksparser *parser, iks *node)
 {
   iks *iq;
@@ -212,7 +214,7 @@ xmpp_session_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_initial_presence_hook (iksparser *parser, iks *node)
 {
   iks *pres;
@@ -222,7 +224,7 @@ xmpp_initial_presence_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_id_hook (iksparser *parser, iks *node, char *id)
 {
   if (!iks_strcmp (id, "bind1"))
@@ -242,13 +244,13 @@ xmpp_id_hook (iksparser *parser, iks *node, char *id)
   return 1;
 }
 
-int
+static int
 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
 {
   return 1;
 }
 
-int
+static int
 xmpp_iq_error (iksparser *parser, iks *node)
 {
   iks *enode;
@@ -275,21 +277,21 @@ xmpp_iq_error (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_tls_hook (iksparser *parser, iks *node)
 {
   iks_start_tls (parser);
   return 0;
 }
 
-int
+static int
 xmpp_sasl_hook (iksparser *parser, iks* node)
 {
   iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
   return 0;
 }
 
-int
+static int
 xmpp_bind_hook (iksparser *parser, iks *node)
 {
   iks *iq;
@@ -303,7 +305,7 @@ xmpp_bind_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_features_hook (iksparser *parser, iks *node)
 {
   iks *feat;
@@ -330,7 +332,7 @@ xmpp_features_hook (iksparser *parser, iks *node)
   return 1;
 }
 
-int
+static int
 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
 {
   if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
@@ -407,7 +409,7 @@ hook (void *data, int type, iks *node)
   return IKS_OK;
 }
 
-gboolean
+static gboolean
 handler (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
   iksparser *parser = data;
@@ -415,12 +417,114 @@ handler (GIOChannel *channel, GIOCondition cond, gpointer data)
   return TRUE;
 }
 
-void
+struct
+  { char * key; char * val; } keymaps[] =
+{
+  { "artist", "artist" },
+  { "duration", "length" },
+  { "album", "source" },
+  { "title", "title" },
+  { "track-number", "track" },
+  { "location", "uri" },
+  { NULL, NULL }
+};
+
+static char *
+map_key (char *orig)
+{
+  int i;
+  for (i = 0; keymaps[i].key != NULL; i++)
+    if (strcmp (orig, keymaps[i].key) == 0)
+      return keymaps[i].val;
+  return NULL;
+}
+
+static void
+tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
+{
+  DBusMessageIter entry;
+  DBusMessageIter var;
+  char *strkey = NULL;
+  char *strval = NULL;
+  dbus_message_iter_recurse (args, &entry);
+  if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_STRING)
+    {
+      dbus_message_iter_get_basic (&entry, &strkey);
+      dbus_message_iter_next (&entry);
+      if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_VARIANT)
+        {
+          dbus_message_iter_recurse (&entry, &var);
+          if (dbus_message_iter_get_arg_type (&var) == DBUS_TYPE_STRING)
+            {
+              dbus_message_iter_get_basic (&var, &strval);
+            }
+        }
+    }
+  else
+    printf ("%c\n", dbus_message_iter_get_arg_type (&entry));
+  strkey = map_key (strkey);
+  if (strkey && strval)
+    {
+      iks_insert_cdata (iks_insert (tune, strkey), strval, 0);
+    }
+}
+
+static iks *
+tune_from_dbus (DBusMessage *msg)
+{
+  DBusMessageIter args;
+  iks *tune;
+  tune = iks_new ("tune");
+  iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
+  dbus_message_iter_init (msg, &args);
+  if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_ARRAY)
+    {
+      DBusMessageIter dict;
+      dbus_message_iter_recurse (&args, &dict);
+      while (dbus_message_iter_get_arg_type (&dict) ==
+             DBUS_TYPE_DICT_ENTRY)
+        {
+          tune_add_dbus_arg (tune, &dict);
+          dbus_message_iter_next (&dict);
+        }
+    }
+  return tune;
+}
+
+static DBusHandlerResult
+gettune (DBusConnection *conn, DBusMessage *msg, void *data)
+{
+  iks *tune;
+  if (dbus_message_is_signal (msg, "org.MetaPlayer.tag", "playing"))
+    {
+      tune = tune_from_dbus (msg);
+      pushtune (data, "http://jabber.org/protocol/tune", tune);
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
+  else
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void
+prepare_dbus (gpointer parser)
+{
+  DBusConnection *conn;
+  conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+  dbus_bus_register (conn, NULL);
+  dbus_bus_add_match (conn,
+                      "type='signal'", NULL);
+  dbus_connection_flush (conn);
+  dbus_connection_setup_with_g_main (conn, g_main_context_default ());
+  dbus_connection_add_filter (conn, gettune, parser, NULL);
+}
+
+static void
 loop (iksparser *parser)
 {
   GIOChannel *channel;
   channel = g_io_channel_unix_new (iks_fd (parser));
   g_io_add_watch (channel, G_IO_IN, handler, parser);
+  prepare_dbus (parser);
   g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE));
 }