changeset 1004:b57a01ffeed6

Use existing conference bookmarks Add support for XEP-0048 (Bookmark Storage). The bookmarks are retrieved when we connect and the conference bookmarks are used.
author Mikael Berthe <mikael@lilotux.net>
date Wed, 08 Nov 2006 22:26:27 +0100
parents c8b1a52b2fd6
children e5c10cc29660
files mcabber/src/commands.c mcabber/src/jab_iq.c mcabber/src/settings.c mcabber/src/settings.h
diffstat 4 files changed, 119 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/commands.c	Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/commands.c	Wed Nov 08 22:26:27 2006 +0100
@@ -1568,7 +1568,6 @@
 {
   char **paramlst;
   char *roomname, *nick, *pass, *roomname_tmp;
-  char *tmpnick = NULL;
   char *pass_utf8;
 
   paramlst = split_arg(arg, 3, 0); // roomid, nickname, password
@@ -1597,25 +1596,15 @@
   }
 
   // If no nickname is provided with the /join command,
-  // we try the "nickname" option, then the username part of the jid.
-  if (!nick || !*nick) {
-    nick = (char*)settings_opt_get("nickname");
-    if (!nick) {
-      nick = (char*)settings_opt_get("username");
-      if (nick && (strchr(nick, JID_DOMAIN_SEPARATOR) > nick)) {
-        char *p;
-        nick = tmpnick = g_strdup(nick);
-        p = strchr(nick, JID_DOMAIN_SEPARATOR);
-        *p = 0;
-      }
-    }
-  } else {
-    nick = tmpnick = to_utf8(nick);
-  }
+  // we try to get a default nickname.
+  if (!nick || !*nick)
+    nick = default_muc_nickname();
+  else
+    nick = to_utf8(nick);
   // If we still have no nickname, give up
   if (!nick || !*nick) {
     scr_LogPrint(LPRINT_NORMAL, "Please specify a nickname.");
-    g_free(tmpnick);
+    g_free(nick);
     free_arg_lst(paramlst);
     return;
   }
@@ -1632,7 +1621,7 @@
   scr_LogPrint(LPRINT_LOGNORM, "Sent a join request to <%s>...", roomname);
 
   g_free(roomname);
-  g_free(tmpnick);
+  g_free(nick);
   g_free(pass_utf8);
   buddylist_build();
   update_roster = TRUE;
--- a/mcabber/src/jab_iq.c	Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/jab_iq.c	Wed Nov 08 22:26:27 2006 +0100
@@ -481,6 +481,93 @@
   g_free(barejid);
 }
 
+static void storage_bookmarks_parse_conference(xmlnode xmldata)
+{
+  const char *jid, *name, *autojoin;
+  char *bjid;
+  GSList *room_elt;
+
+  jid = xmlnode_get_attrib(xmldata, "jid");
+  if (!jid)
+    return;
+  name = xmlnode_get_attrib(xmldata, "name");
+  autojoin = xmlnode_get_attrib(xmldata, "autojoin");
+
+  bjid = jidtodisp(jid); // Bare jid
+
+  // Make sure this is a room (it can be a conversion user->room)
+  room_elt = roster_find(bjid, jidsearch, 0);
+  if (!room_elt) {
+    room_elt = roster_add_user(bjid, name, NULL, ROSTER_TYPE_ROOM, sub_none);
+  } else {
+    buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+    /*
+    // If the name is available, should we use it?
+    // I don't think so, it would be confusing because this item is already
+    // in the roster.
+    if (name)
+      buddy_setname(room_elt->data, name);
+    */
+  }
+
+  // Is autojoin set?
+  // If it is, we'll look up for more information (nick? password?) and
+  // try to join the room.
+  if (autojoin && !strcmp(autojoin, "1")) {
+    char *nick, *passwd;
+    char *tmpnick = NULL;
+    nick = xmlnode_get_tag_data(xmldata, "nick");
+    passwd = xmlnode_get_tag_data(xmldata, "password");
+    if (!nick || !*nick)
+      nick = tmpnick = default_muc_nickname();
+    // Let's join now
+    scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid);
+    jb_room_join(bjid, nick, passwd);
+    g_free(tmpnick);
+  }
+  g_free(bjid);
+}
+
+static void iqscallback_storage_bookmarks(eviqs *iqp, xmlnode xml_result,
+                                          guint iqcontext)
+{
+  xmlnode x, ansqry;
+  char *p;
+
+  // Leave now if we cannot process xml_result
+  if (!xml_result || iqcontext) return;
+
+  ansqry = xmlnode_get_tag(xml_result, "query");
+  ansqry = xmlnode_get_tag(ansqry, "storage");
+  if (!ansqry) {
+    scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)");
+    return;
+  }
+
+  // Walk through the storage tags
+  x = xmlnode_get_firstchild(ansqry);
+  for ( ; x; x = xmlnode_get_nextsibling(x)) {
+    p = xmlnode_get_name(x);
+    // If the current node is a conference item, parse it and update the roster
+    if (p && !strcmp(p, "conference"))
+      storage_bookmarks_parse_conference(x);
+  }
+}
+
+static void request_storage_bookmarks(void)
+{
+  eviqs *iqn;
+  xmlnode x;
+
+  iqn = iqs_new(JPACKET__GET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
+
+  x = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "storage");
+  xmlnode_put_attrib(x, "xmlns", "storage:bookmarks");
+
+  iqn->callback = &iqscallback_storage_bookmarks;
+  jab_send(jc, iqn->xmldata);
+}
+
 void iqscallback_auth(eviqs *iqp, xmlnode xml_result)
 {
   if (jstate == STATE_GETAUTH) {
@@ -499,6 +586,7 @@
     jstate = STATE_SENDAUTH;
   } else if (jstate == STATE_SENDAUTH) {
     request_roster();
+    request_storage_bookmarks();
     jstate = STATE_LOGGED;
   }
 }
--- a/mcabber/src/settings.c	Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/settings.c	Wed Nov 08 22:26:27 2006 +0100
@@ -345,4 +345,26 @@
   }
 }
 
+
+//  default_muc_nickname()
+// Return the user's default nickname
+// The caller should free the string after use
+char *default_muc_nickname(void)
+{
+  char *nick;
+
+  // We try the "nickname" option, then the username part of the jid.
+  nick = (char*)settings_opt_get("nickname");
+  if (nick)
+    return g_strdup(nick);
+
+  nick = g_strdup(settings_opt_get("username"));
+  if (nick) {
+    char *p = strchr(nick, JID_DOMAIN_SEPARATOR);
+    if (p > nick)
+      *p = 0;
+  }
+  return nick;
+}
+
 /* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/settings.h	Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/settings.h	Wed Nov 08 22:26:27 2006 +0100
@@ -35,6 +35,8 @@
                          void (*pfunc)(void *param, char *k, char *v),
                          void *param);
 
+char *default_muc_nickname(void);
+
 const gchar *isbound(int key);
 
 #endif /* __SETTINGS_H__ */