changeset 1003:c8b1a52b2fd6

Initial VCard retrieval support
author Mikael Berthe <mikael@lilotux.net>
date Tue, 07 Nov 2006 22:43:17 +0100
parents dd9e7eb5f8a8
children b57a01ffeed6
files mcabber/src/commands.c mcabber/src/jab_iq.c mcabber/src/jab_priv.h mcabber/src/jabglue.c mcabber/src/jabglue.h
diffstat 5 files changed, 144 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/commands.c	Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/commands.c	Tue Nov 07 22:43:17 2006 +0100
@@ -212,6 +212,7 @@
 
   // Request (query) category
   compl_add_category_word(COMPL_REQUEST, "time");
+  compl_add_category_word(COMPL_REQUEST, "vcard");
   compl_add_category_word(COMPL_REQUEST, "version");
 
   // Events category
@@ -2217,6 +2218,8 @@
       numtype = iqreq_version;
     else if (!strcasecmp(type, "time"))
       numtype = iqreq_time;
+    else if (!strcasecmp(type, "vcard"))
+      numtype = iqreq_vcard;
     else if (!strcasecmp(type, "show_list")) {
       // Undocumented command, for debugging purposes only
       jb_iqs_display_list();
@@ -2260,6 +2263,7 @@
     switch (numtype) {
       case iqreq_version:
       case iqreq_time:
+      case iqreq_vcard:
           jb_request(jid, numtype);
           break;
       default:
--- a/mcabber/src/jab_iq.c	Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jab_iq.c	Tue Nov 07 22:43:17 2006 +0100
@@ -355,6 +355,132 @@
   jab_send(jc, iqn->xmldata);
 }
 
+static void handle_vcard_node(const char *barejid, xmlnode vcardnode)
+{
+  xmlnode x;
+  const char *p;
+  char *buf;
+
+  x = xmlnode_get_firstchild(vcardnode);
+  for ( ; x; x = xmlnode_get_nextsibling(x)) {
+    const char *title, *data;
+    p = xmlnode_get_name(x);
+    data = xmlnode_get_data(x);
+    if (p && data) {
+      title = NULL;
+      if (!strcmp(p, "FN"))
+        title = "Name";
+      else if (!strcmp(p, "NICKNAME"))
+        title = "Nickname";
+      else if (!strcmp(p, "URL"))
+        title = "URL";
+      else if (!strcmp(p, "BDAY"))
+        title = "Birthday";
+      else if (!strcmp(p, "TZ"))
+        title = "Timezone";
+      else if (!strcmp(p, "TITLE"))
+        title = "Title";
+      else if (!strcmp(p, "ROLE"))
+        title = "Role";
+      else if (!strcmp(p, "DESC"))
+        title = "Comment";
+      else if (!strcmp(p, "N")) {
+        data = xmlnode_get_tag_data(x, "FAMILY");
+        if (data) {
+          buf = g_strdup_printf("Family Name: %s", data);
+          scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+          g_free(buf);
+        }
+        data = xmlnode_get_tag_data(x, "GIVEN");
+        if (data) {
+          buf = g_strdup_printf("Given Name: %s", data);
+          scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+          g_free(buf);
+        }
+        data = xmlnode_get_tag_data(x, "MIDDLE");
+        if (data) {
+          buf = g_strdup_printf("Middle Name: %s", data);
+          scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+          g_free(buf);
+        }
+      } else if (!strcmp(p, "ADR")) {   // TODO
+      } else if (!strcmp(p, "TEL")) {   // TODO
+      } else if (!strcmp(p, "EMAIL")) {
+        data = xmlnode_get_tag_data(x, "USERID");
+        if (data)
+          title = "Email"; // XXX
+      } else if (!strcmp(p, "ORG")) {   // TODO
+      }
+
+      if (title) {
+        buf = g_strdup_printf("%s: %s", title, data);
+        scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+        g_free(buf);
+      }
+    }
+  }
+}
+
+static void iqscallback_vcard(eviqs *iqp, xmlnode xml_result, guint iqcontext)
+{
+  xmlnode ansqry;
+  char *p;
+  char *bjid;
+  char *buf;
+
+  // Leave now if we cannot process xml_result
+  if (!xml_result || iqcontext) return;
+
+  // Display IQ result sender...
+  p = xmlnode_get_attrib(xml_result, "from");
+  if (!p) {
+    scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name).");
+    return;
+  }
+  bjid = p;
+
+  buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid);
+  scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+  // Get the vCard node
+  ansqry = xmlnode_get_tag(xml_result, "vCard");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!");
+    return;
+  }
+
+  // bjid should really be the "bare JID", let's strip the resource
+  p = strchr(bjid, JID_RESOURCE_SEPARATOR);
+  if (p) *p = '\0';
+
+  scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO);
+  g_free(buf);
+
+  // Get result data...
+  handle_vcard_node(bjid, ansqry);
+}
+
+void request_vcard(const char *jid)
+{
+  eviqs *iqn;
+  char *barejid;
+
+  barejid = jidtodisp(jid);
+
+  // Create a new IQ structure.  We use NULL for the namespace because
+  // we'll have to use a special tag, not the usual "query" one.
+  iqn = iqs_new(JPACKET__GET, NULL, "vcard", IQS_DEFAULT_TIMEOUT);
+  xmlnode_put_attrib(iqn->xmldata, "to", barejid);
+  // Remove the useless <query/> tag, and insert a vCard one.
+  xmlnode_hide(xmlnode_get_tag(iqn->xmldata, "query"));
+  xmlnode_put_attrib(xmlnode_insert_tag(iqn->xmldata, "vCard"),
+                     "xmlns", NS_VCARD);
+  iqn->callback = &iqscallback_vcard;
+  jab_send(jc, iqn->xmldata);
+
+  g_free(barejid);
+}
+
 void iqscallback_auth(eviqs *iqp, xmlnode xml_result)
 {
   if (jstate == STATE_GETAUTH) {
@@ -392,19 +518,6 @@
   if (!iqs_callback(id, xmldata, IQS_CONTEXT_RESULT))
     return;
 
-  /*
-  if (!strcmp(id, "VCARDreq")) {
-    x = xmlnode_get_firstchild(xmldata);
-    if (!x) x = xmldata;
-
-    scr_LogPrint(LPRINT_LOGNORM, "Got VCARD");    // TODO
-    return;
-  } else if (!strcmp(id, "versionreq")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Got version");  // TODO
-    return;
-  }
-  */
-
   x = xmlnode_get_tag(xmldata, "query");
   if (!x) return;
 
--- a/mcabber/src/jab_priv.h	Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jab_priv.h	Tue Nov 07 22:43:17 2006 +0100
@@ -43,6 +43,7 @@
 void iqscallback_auth(eviqs *iqp, xmlnode xml_result);
 void request_version(const char *fulljid);
 void request_time(const char *fulljid);
+void request_vcard(const char *barejid);
 
 #endif /* __JAB_PRIV_H__ */
 
--- a/mcabber/src/jabglue.c	Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jabglue.c	Tue Nov 07 22:43:17 2006 +0100
@@ -925,9 +925,20 @@
   } else if (reqtype == iqreq_time) {
     request_fn = &request_time;
     strreqtype = "time";
+  } else if (reqtype == iqreq_vcard) {
+    // Special case
   } else
     return;
 
+  // vCard request
+  if (reqtype == iqreq_vcard) {
+    char *bjid = jidtodisp(jid);
+    request_vcard(bjid);
+    scr_LogPrint(LPRINT_NORMAL, "Sent vCard request to <%s>", bjid);
+    g_free(bjid);
+    return;
+  }
+
   if (strchr(jid, JID_RESOURCE_SEPARATOR)) {
     // This is a full JID
     (*request_fn)(jid);
--- a/mcabber/src/jabglue.h	Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jabglue.h	Tue Nov 07 22:43:17 2006 +0100
@@ -29,7 +29,8 @@
 enum iqreq_type {
   iqreq_none,
   iqreq_version,
-  iqreq_time
+  iqreq_time,
+  iqreq_vcard
 };
 
 char *compose_jid(const char *username, const char *servername,