changeset 26843:9ce0c5bc922c

Show when a user was last online (as seen by the server) when doing "Get Info" by issuing a jabber:iq:last to the bare JID
author Marcus Lundblad <ml@update.uu.se>
date Thu, 07 May 2009 19:24:02 +0000
parents 33f98d662db8
children 2760311c492a
files ChangeLog libpurple/protocols/jabber/buddy.c
diffstat 2 files changed, 64 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu May 07 17:04:59 2009 +0000
+++ b/ChangeLog	Thu May 07 19:24:02 2009 +0000
@@ -36,6 +36,8 @@
 	* Put section breaks between resources in "Get Info" to improve readability.
 	* XHTML markup is only included in outgoing messages when the message
 	  contains formatting.
+	* Show when the user was last logged in when doing "Get Info" on an offline
+	  buddy, provided the server supports it.
 
 	Yahoo:
 	* P2P file transfers. (Sulabh Mahajan)
--- a/libpurple/protocols/jabber/buddy.c	Thu May 07 17:04:59 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Thu May 07 19:24:02 2009 +0000
@@ -50,6 +50,8 @@
 	int timeout_handle;
 	GSList *vcard_imgids;
 	PurpleNotifyUserInfo *user_info;
+	long last_seconds;
+	gchar *last_message;
 } JabberBuddyInfo;
 
 void jabber_buddy_free(JabberBuddy *jb)
@@ -642,6 +644,7 @@
 
 	g_free(jbi->jid);
 	g_hash_table_destroy(jbi->resources);
+	g_free(jbi->last_message);
 	purple_notify_user_info_destroy(jbi->user_info);
 	g_free(jbi);
 }
@@ -1039,6 +1042,24 @@
 		}
 	}
 
+	if (!jbi->jb->resources) {
+		/* the buddy is offline */
+		gchar *status = 
+			g_strdup_printf("%s%s%s",	_("Offline"), 
+				jbi->last_message ? ": " : "",
+				jbi->last_message ? jbi->last_message : "");
+		if (jbi->last_seconds > 0) {
+			char *last = purple_str_seconds_to_string(jbi->last_seconds);
+			gchar *message = g_strdup_printf(_("%s ago"), last);
+			purple_notify_user_info_prepend_pair(user_info, 
+				_("Last logged in"), message);
+			g_free(last);
+			g_free(message);
+		}
+		purple_notify_user_info_prepend_pair(user_info, _("Status"), status);
+		g_free(status);
+	}
+
 	g_free(resource_name);
 
 	purple_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL);
@@ -1491,6 +1512,38 @@
 	jabber_buddy_info_show_if_ready(jbi);
 }
 
+static void jabber_last_offline_parse(JabberStream *js, const char *from,
+									  JabberIqType type, const char *id,
+									  xmlnode *packet, gpointer data)
+{
+	JabberBuddyInfo *jbi = data;
+	xmlnode *query;
+	const char *seconds;
+
+	g_return_if_fail(jbi != NULL);
+
+	jabber_buddy_info_remove_id(jbi, id);
+
+	if(!from)
+		return;
+
+	if (type == JABBER_IQ_RESULT) {
+		if((query = xmlnode_get_child(packet, "query"))) {
+			seconds = xmlnode_get_attrib(query, "seconds");
+			if(seconds) {
+				char *end = NULL;
+				long sec = strtol(seconds, &end, 10);
+				if(end != seconds) {
+					jbi->last_seconds = sec;
+				}
+			}
+			jbi->last_message = xmlnode_get_data(query);
+		}
+	}
+
+	jabber_buddy_info_show_if_ready(jbi);
+}
+
 static void jabber_time_parse(JabberStream *js, const char *from,
                               JabberIqType type, const char *id,
                               xmlnode *packet, gpointer data)
@@ -1688,6 +1741,15 @@
 		g_free(full_jid);
 	}
 
+	if (!jb->resources) {
+		/* user is offline, send a jabber:iq:last to find out last time online */
+		iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last");
+		xmlnode_set_attrib(iq->node, "to", jid);
+		jabber_iq_set_callback(iq, jabber_last_offline_parse, jbi);
+		jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
+		jabber_iq_send(iq);
+	}
+	
 	js->pending_buddy_info_requests = g_slist_prepend(js->pending_buddy_info_requests, jbi);
 	jbi->timeout_handle = purple_timeout_add_seconds(30, jabber_buddy_get_info_timeout, jbi);
 }