cpw.malu.xmpp.idle: 4def8227: A first stab at supporting the upcoming ...
malu at pidgin.im
malu at pidgin.im
Sun Nov 16 17:30:35 EST 2008
-----------------------------------------------------------------
Revision: 4def82270f4601da28a42de74b29d1ab0046be3e
Ancestor: f3891f3348abfe90fbe60a054833c12075aa8df4
Author: malu at pidgin.im
Date: 2008-11-16T22:29:00
Branch: im.pidgin.cpw.malu.xmpp.idle
URL: http://d.pidgin.im/viewmtn/revision/info/4def82270f4601da28a42de74b29d1ab0046be3e
Modified files:
libpurple/protocols/jabber/buddy.c
libpurple/protocols/jabber/buddy.h
libpurple/protocols/jabber/disco.c
libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/presence.c
libpurple/protocols/jabber/presence.h
libpurple/protocols/jabber/roster.c
ChangeLog:
A first stab at supporting the upcoming new use-case in XMPP XEP-0012
to provide info on idleness in <presence/> stanzas, which allows to track
idle times without polling.
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/buddy.c b687d1cce701f26584534067479bb48e29893101
+++ libpurple/protocols/jabber/buddy.c ba0c5e278c9fd7a40af3c1b4b734f1b65496ca23
@@ -627,7 +627,7 @@ void jabber_set_buddy_icon(PurpleConnect
gpresence = purple_account_get_presence(gc->account);
status = purple_presence_get_active_status(gpresence);
- jabber_presence_send(gc->account, status);
+ jabber_presence_send(gc->account, status, FALSE);
}
/*
============================================================
--- libpurple/protocols/jabber/buddy.h b72ccdfffb3ac98b1f2cab34a3fddfef59c086e5
+++ libpurple/protocols/jabber/buddy.h 202840b79a776232124f348b43d9b02dec0dcdb4
@@ -69,6 +69,7 @@ typedef struct _JabberBuddyResource {
int priority;
JabberBuddyState state;
char *status;
+ time_t idle;
JabberCapabilities capabilities;
char *thread_id;
enum {
============================================================
--- libpurple/protocols/jabber/disco.c 7f85a8a092ed6670ee147af38b8482042416e2ee
+++ libpurple/protocols/jabber/disco.c 7a7045489884ae4fcd1b2ab6e76b1da0f4bf0148
@@ -348,7 +348,7 @@ jabber_disco_finish_server_info_result_c
}
/* Send initial presence; this will trigger receipt of presence for contacts on the roster */
- jabber_presence_send(js->gc->account, NULL);
+ jabber_presence_send(js->gc->account, NULL, FALSE);
if (js->server_caps & JABBER_CAP_ADHOC) {
/* The server supports ad-hoc commands, so let's request the list */
============================================================
--- libpurple/protocols/jabber/jabber.c 7ae43cf5a01de166b8e02df1e8f6f4ec195540b4
+++ libpurple/protocols/jabber/jabber.c 07dcd63dd716adf23b5b19743564bfe7a5d47682
@@ -1434,8 +1434,14 @@ void jabber_idle_set(PurpleConnection *g
void jabber_idle_set(PurpleConnection *gc, int idle)
{
JabberStream *js = gc->proto_data;
-
+ PurpleAccount *account = purple_connection_get_account(gc);
+ PurpleStatus *status = purple_account_get_active_status(account);
+
js->idle = idle ? time(NULL) - idle : idle;
+
+ /* send out an updated prescence */
+ purple_debug_info("jabber", "sending updated presence for idle\n");
+ jabber_presence_send(account, status, TRUE);
}
void jabber_add_feature(const char *shortname, const char *namespace, JabberFeatureEnabled cb) {
============================================================
--- libpurple/protocols/jabber/presence.c 1bb6fa1483cacef7ba9da2c4f3dcecff39c2eeb3
+++ libpurple/protocols/jabber/presence.c 386e5b34c3882ed4a0b9524c84a6956fe36c2ee1
@@ -95,7 +95,8 @@ void jabber_presence_fake_to_self(Jabber
}
-void jabber_presence_send(PurpleAccount *account, PurpleStatus *status)
+void jabber_presence_send(PurpleAccount *account, PurpleStatus *status,
+ gboolean update_idle)
{
PurpleConnection *gc = NULL;
JabberStream *js = NULL;
@@ -150,7 +151,7 @@ void jabber_presence_send(PurpleAccount
#define CHANGED(a,b) ((!a && b) || (a && a[0] == '\0' && b && b[0] != '\0') || \
(a && !b) || (a && a[0] != '\0' && b && b[0] == '\0') || (a && b && strcmp(a,b)))
/* check if there are any differences to the <presence> and send them in that case */
- if (allowBuzz != js->allowBuzz || js->old_state != state || CHANGED(js->old_msg, stripped) ||
+ if (update_idle || allowBuzz != js->allowBuzz || js->old_state != state || CHANGED(js->old_msg, stripped) ||
js->old_priority != priority || CHANGED(js->old_avatarhash, js->avatar_hash)) {
js->allowBuzz = allowBuzz;
@@ -260,6 +261,15 @@ xmlnode *jabber_presence_create_js(Jabbe
g_free(pstr);
}
+ /* if we are idle and not offline, include idle */
+ if (js->idle && state != JABBER_BUDDY_STATE_UNAVAILABLE) {
+ xmlnode *query = xmlnode_new_child(presence, "query");
+ gchar *seconds = g_strdup_printf("%d", (int) (time(NULL) - js->idle));
+
+ xmlnode_set_namespace(query, "jabber:iq:last");
+ xmlnode_set_attrib(query, "seconds", seconds);
+ }
+
/* JEP-0115 */
c = xmlnode_new_child(presence, "c");
xmlnode_set_namespace(c, "http://jabber.org/protocol/caps");
@@ -412,6 +422,42 @@ static void jabber_presence_set_capabili
g_free(userdata);
}
+static void
+jabber_presence_update_buddy_idle(PurpleAccount *account, const gchar *who,
+ JabberBuddy *jb)
+{
+ const GList *iter = NULL;
+ gboolean idle = TRUE;
+ time_t last_idle = 0;
+
+ purple_debug_info("jabber", "updating idle for buddy %s\n", who);
+
+ if (!jb->resources) {
+ idle = FALSE;
+ }
+
+ for (iter = jb->resources ; iter ; iter = g_list_next(iter)) {
+ JabberBuddyResource *jbr = (JabberBuddyResource *) iter->data;
+
+ purple_debug_info("jabber", "resource %s has an idle set to %d\n",
+ jbr->name, jbr->idle);
+
+ if (!jbr->idle) {
+ idle = FALSE;
+ break;
+ }
+ if (jbr->idle > last_idle) {
+ last_idle = jbr->idle;
+ }
+ }
+
+ if (idle) {
+ purple_prpl_got_user_idle(account, who, TRUE, last_idle);
+ } else {
+ purple_prpl_got_user_idle(account, who, FALSE, 0);
+ }
+}
+
void jabber_presence_parse(JabberStream *js, xmlnode *packet)
{
const char *from = xmlnode_get_attrib(packet, "from");
@@ -434,7 +480,8 @@ void jabber_presence_parse(JabberStream
gboolean muc = FALSE;
char *avatar_hash = NULL;
xmlnode *caps = NULL;
-
+ int idle = 0;
+
if(!(jb = jabber_buddy_find(js, from, TRUE)))
return;
@@ -570,6 +617,14 @@ void jabber_presence_parse(JabberStream
avatar_hash = xmlnode_get_data(photo);
}
}
+ } else if (!strcmp(y->name, "query") &&
+ !strcmp(xmlnode_get_namespace(y), "jabber:iq:last")) {
+ /* resource has specified idle */
+ const gchar *seconds = xmlnode_get_attrib(y, "seconds");
+ if (seconds) {
+ /* we may need to take "delayed" into account here */
+ idle = atoi(seconds);
+ }
}
}
@@ -747,6 +802,12 @@ void jabber_presence_parse(JabberStream
} else {
jbr = jabber_buddy_track_resource(jb, jid->resource, priority,
state, status);
+ if (idle) {
+ jbr->idle = time(NULL) - idle;
+ } else {
+ jbr->idle = 0;
+ }
+
if(caps) {
const char *node = xmlnode_get_attrib(caps,"node");
const char *ver = xmlnode_get_attrib(caps,"ver");
@@ -768,6 +829,7 @@ void jabber_presence_parse(JabberStream
} else {
purple_prpl_got_user_status(js->gc->account, buddy_name, "offline", status ? "message" : NULL, status, NULL);
}
+ jabber_presence_update_buddy_idle(js->gc->account, buddy_name, jb);
g_free(buddy_name);
}
g_free(status);
============================================================
--- libpurple/protocols/jabber/presence.h a77bd82d513655a2ba4eef03d8c9f2d70e7e7e3d
+++ libpurple/protocols/jabber/presence.h d9060c67c048b365eb8c9edc4bec60b58c371cfa
@@ -26,7 +26,8 @@
#include "jabber.h"
#include "xmlnode.h"
-void jabber_presence_send(PurpleAccount *account, PurpleStatus *status);
+void jabber_presence_send(PurpleAccount *account, PurpleStatus *status,
+ gboolean update_idle);
xmlnode *jabber_presence_create(JabberBuddyState state, const char *msg, int priority); /* DEPRECATED */
xmlnode *jabber_presence_create_js(JabberStream *js, JabberBuddyState state, const char *msg, int priority);
void jabber_presence_parse(JabberStream *js, xmlnode *packet);
============================================================
--- libpurple/protocols/jabber/roster.c a384763565f91ecfa641f97f9ba59f697fa9169a
+++ libpurple/protocols/jabber/roster.c 89f92e6dd7b9b26035b253670fefa8bbdf42bad7
@@ -261,7 +261,7 @@ void jabber_roster_parse(JabberStream *j
if(!js->roster_parsed) {
js->roster_parsed = TRUE;
- jabber_presence_send(js->gc->account, NULL);
+ jabber_presence_send(js->gc->account, NULL, FALSE);
}
}
More information about the Commits
mailing list