gossip r2841 - in trunk: . libgossip
- From: mr svn gnome org
- To: svn-commits-list gnome org
- Subject: gossip r2841 - in trunk: . libgossip
- Date: Wed, 30 Jul 2008 08:51:51 +0000 (UTC)
Author: mr
Date: Wed Jul 30 08:51:51 2008
New Revision: 2841
URL: http://svn.gnome.org/viewvc/gossip?rev=2841&view=rev
Log:
Fixes bug 545451, Network traffic is incredibly high due to constant vcard requests
Modified:
trunk/ChangeLog
trunk/libgossip/gossip-avatar.c
trunk/libgossip/gossip-jabber.c
trunk/libgossip/gossip-jabber.h
trunk/libgossip/gossip-vcard.h
Modified: trunk/libgossip/gossip-avatar.c
==============================================================================
--- trunk/libgossip/gossip-avatar.c (original)
+++ trunk/libgossip/gossip-avatar.c Wed Jul 30 08:51:51 2008
@@ -20,6 +20,8 @@
#include "config.h"
+#include "string.h"
+
#include "gossip-avatar.h"
#define DEBUG_DOMAIN "Avatar"
@@ -32,10 +34,10 @@
static gboolean
avatar_pixbuf_is_opaque (GdkPixbuf *pixbuf)
{
- int width;
- int height;
- int rowstride;
- int i;
+ gint width;
+ gint height;
+ gint rowstride;
+ gint i;
unsigned char *pixels;
unsigned char *row;
@@ -76,9 +78,9 @@
static void
avatar_pixbuf_roundify (GdkPixbuf *pixbuf)
{
- int width;
- int height;
- int rowstride;
+ gint width;
+ gint height;
+ gint rowstride;
guchar *pixels;
if (!gdk_pixbuf_get_has_alpha(pixbuf)) {
@@ -159,20 +161,34 @@
static GdkPixbuf *
avatar_create_pixbuf (GossipAvatar *avatar, gint size)
{
- GdkPixbuf *tmp_pixbuf;
- GdkPixbuf *ret_pixbuf;
- GdkPixbufLoader *loader;
- GError *error = NULL;
- gint orig_width;
- gint orig_height;
- gint scale_width;
- gint scale_height;
+ GdkPixbuf *tmp_pixbuf;
+ GdkPixbuf *ret_pixbuf;
+ GdkPixbufLoader *loader;
+ GError *error = NULL;
+ gint orig_width;
+ gint orig_height;
+ gint scale_width;
+ gint scale_height;
if (!avatar) {
return NULL;
}
if (avatar->format) {
+ /* Some avatars are written by crap clients. This is just to
+ * help things along here.
+ */
+ if (G_UNLIKELY (!strchr (avatar->format, '/'))) {
+ gchar *old_format;
+
+ /* This is obviously wrong, so we try to
+ * correct it.
+ */
+ old_format = avatar->format;
+ avatar->format = g_strdup_printf ("image/%s", old_format);
+ g_free (old_format);
+ }
+
loader = gdk_pixbuf_loader_new_with_mime_type (avatar->format, &error);
if (error) {
Modified: trunk/libgossip/gossip-jabber.c
==============================================================================
--- trunk/libgossip/gossip-jabber.c (original)
+++ trunk/libgossip/gossip-jabber.c Wed Jul 30 08:51:51 2008
@@ -88,7 +88,6 @@
GossipAccount *account;
GossipPresence *presence;
- GossipVCard *vcard;
GHashTable *contact_list;
@@ -113,6 +112,8 @@
GHashTable *composing_timeouts;
GHashTable *composing_requests;
+ GHashTable *vcards;
+
/* Transport stuff... is this in the right place? */
#ifdef USE_TRANSPORTS
GossipTransportAccountList *account_list;
@@ -134,7 +135,8 @@
static void gossip_jabber_class_init (GossipJabberClass *klass);
static void gossip_jabber_init (GossipJabber *jabber);
-static void jabber_finalize (GObject *object);
+static void gossip_jabber_finalize (GObject *object);
+static void jabber_vcard_destroy_notify_func (gpointer data);
static gboolean jabber_login_timeout_cb (GossipJabber *jabber);
static gboolean jabber_logout_contact_foreach (gpointer key,
gpointer value,
@@ -152,18 +154,13 @@
LmSSLStatus status,
GossipJabber *jabber);
static gboolean jabber_composing_timeout_cb (JabberData *data);
-static void jabber_contact_is_avatar_latest_cb (GossipResult result,
- GossipVCard *vcard,
- JabberData *data);
static void jabber_contact_is_avatar_latest (GossipJabber *jabber,
GossipContact *contact,
LmMessageNode *m,
gboolean force_update);
-static void jabber_contact_vcard (GossipJabber *jabber,
- GossipContact *contact);
-static void jabber_contact_vcard_cb (GossipResult result,
- GossipVCard *vcard,
- JabberData *data);
+static void jabber_contact_get_vcard (GossipJabber *jabber,
+ GossipContact *contact,
+ gboolean force_update);
static void jabber_group_rename_foreach_cb (gpointer key,
gpointer value,
gpointer user_data);
@@ -297,7 +294,7 @@
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = jabber_finalize;
+ object_class->finalize = gossip_jabber_finalize;
signals[CONNECTING] =
g_signal_new ("connecting",
@@ -443,10 +440,16 @@
gossip_contact_equal,
g_object_unref,
NULL);
+
+ priv->vcards =
+ g_hash_table_new_full (gossip_contact_hash,
+ gossip_contact_equal,
+ g_object_unref,
+ jabber_vcard_destroy_notify_func);
}
static void
-jabber_finalize (GObject *object)
+gossip_jabber_finalize (GObject *object)
{
GossipJabber *jabber;
GossipJabberPriv *priv;
@@ -458,10 +461,6 @@
g_object_unref (priv->account);
}
- if (priv->vcard) {
- g_object_unref (priv->vcard);
- }
-
if (priv->presence) {
g_object_unref (priv->presence);
}
@@ -470,17 +469,19 @@
g_object_unref (priv->session);
}
- g_hash_table_unref (priv->contact_list);
-
/* finalize extended modules */
gossip_jabber_chatrooms_finalize (priv->chatrooms);
if (priv->fts) {
gossip_jabber_ft_finalize (priv->fts);
}
- g_hash_table_destroy (priv->composing_ids);
- g_hash_table_destroy (priv->composing_timeouts);
- g_hash_table_destroy (priv->composing_requests);
+ g_hash_table_unref (priv->vcards);
+
+ g_hash_table_unref (priv->composing_requests);
+ g_hash_table_unref (priv->composing_timeouts);
+ g_hash_table_unref (priv->composing_ids);
+
+ g_hash_table_unref (priv->contact_list);
if (priv->connection_timeout_id != 0) {
g_source_remove (priv->connection_timeout_id);
@@ -497,6 +498,19 @@
(G_OBJECT_CLASS (gossip_jabber_parent_class)->finalize) (object);
}
+static void
+jabber_vcard_destroy_notify_func (gpointer data)
+{
+ if (!data) {
+ /* Nothing to do, NULL was used as a place holder so
+ * we don't request the vcard more than once.
+ */
+ return;
+ }
+
+ g_object_unref (data);
+}
+
GossipJabber *
gossip_jabber_new (gpointer session)
{
@@ -1019,33 +1033,10 @@
FALSE,
FALSE);
- if (priv->vcard) {
- gchar *name;
-
- name = gossip_jabber_get_name_to_use
- (gossip_contact_get_id (own_contact),
- gossip_vcard_get_nickname (priv->vcard),
- gossip_vcard_get_name (priv->vcard),
- gossip_contact_get_name (own_contact));
-
- gossip_contact_set_name (own_contact, name);
- g_free (name);
-
- /* Set the vcard waiting to be sent to our jabber server once
- * connected.
- */
- gossip_jabber_vcard_set (jabber,
- priv->vcard,
- NULL, NULL, NULL);
-
- g_object_unref (priv->vcard);
- priv->vcard = NULL;
- } else {
- /* Request our vcard so we know what our nick name is to use
- * in chats windows, etc.
- */
- jabber_contact_vcard (jabber, own_contact);
- }
+ /* Request our vcard so we know what our nick name is to use
+ * in chats windows, etc.
+ */
+ jabber_contact_get_vcard (jabber, own_contact, TRUE);
}
static void
@@ -1815,68 +1806,16 @@
}
static void
-jabber_contact_is_avatar_latest_cb (GossipResult result,
- GossipVCard *vcard,
- JabberData *data)
-{
- if (result == GOSSIP_RESULT_OK) {
- GossipAvatar *avatar;
-
- avatar = gossip_vcard_get_avatar (vcard);
- gossip_contact_set_avatar (data->contact, avatar);
- gossip_contact_set_vcard (data->contact, vcard);
- }
-
- jabber_data_free (data);
-}
-
-static void
-jabber_contact_is_avatar_latest (GossipJabber *jabber,
- GossipContact *contact,
- LmMessageNode *m,
- gboolean force_update)
+jabber_contact_get_vcard_cb (GossipResult result,
+ GossipVCard *vcard,
+ gpointer user_data)
{
- JabberData *data;
- LmMessageNode *avatar_node;
- GossipAvatar *avatar;
- gchar *sha1;
- gboolean same;
-
- if (!force_update) {
- avatar_node = lm_message_node_find_child (m, "photo");
- if (!avatar_node || !avatar_node->value) {
- gossip_contact_set_avatar (contact, NULL);
- return;
- }
-
- avatar = gossip_contact_get_avatar (contact);
- if (avatar) {
- sha1 = gossip_sha_hash (avatar->data, avatar->len);
- } else {
- sha1 = gossip_sha_hash (NULL, 0);
- }
-
- same = g_ascii_strcasecmp (sha1, avatar_node->value) == 0;
- g_free (sha1);
-
- if (same) {
- return;
- }
- }
-
- data = jabber_data_new (jabber, contact, NULL);
- gossip_jabber_vcard_get (jabber,
- gossip_contact_get_id (contact),
- (GossipVCardCallback) jabber_contact_is_avatar_latest_cb,
- data,
- NULL);
-}
+ GossipJabberPriv *priv;
+ JabberData *data;
+
+ data = user_data;
+ priv = GET_PRIV (data->jabber);
-static void
-jabber_contact_vcard_cb (GossipResult result,
- GossipVCard *vcard,
- JabberData *data)
-{
if (result == GOSSIP_RESULT_OK) {
GossipContact *own_contact;
gchar *name;
@@ -1902,27 +1841,93 @@
if (gossip_contact_equal (own_contact, data->contact)) {
gossip_jabber_send_presence (data->jabber, NULL);
}
+
+ if (vcard) {
+ g_object_ref (vcard);
+ }
+
+ g_hash_table_replace (priv->vcards,
+ g_object_ref (data->contact),
+ vcard);
}
jabber_data_free (data);
}
static void
-jabber_contact_vcard (GossipJabber *jabber,
- GossipContact *contact)
+jabber_contact_get_vcard (GossipJabber *jabber,
+ GossipContact *contact,
+ gboolean force_update)
{
- JabberData *data;
+ GossipJabberPriv *priv;
+ JabberData *data;
+
+ priv = GET_PRIV (jabber);
+
+ if (!force_update) {
+ /* We use this instead of the regular lookup because
+ * the VCard can be NULL, i.e. if we have requested
+ * it already and are waiting for a response from the
+ * server.
+ */
+ if (g_hash_table_lookup_extended (priv->vcards, contact, NULL, NULL)) {
+ gossip_debug (DEBUG_DOMAIN,
+ "Already requested vcard for:'%s'",
+ gossip_contact_get_id (contact));
+ return;
+ }
+ }
+
+ g_hash_table_replace (priv->vcards,
+ g_object_ref (contact),
+ NULL);
data = jabber_data_new (jabber, contact, NULL);
gossip_jabber_vcard_get (jabber,
gossip_contact_get_id (contact),
- (GossipVCardCallback) jabber_contact_vcard_cb,
+ jabber_contact_get_vcard_cb,
data,
NULL);
}
static void
+jabber_contact_is_avatar_latest (GossipJabber *jabber,
+ GossipContact *contact,
+ LmMessageNode *m,
+ gboolean force_update)
+{
+ if (!force_update) {
+ LmMessageNode *avatar_node;
+ GossipAvatar *avatar;
+ gchar *sha1;
+ gboolean same;
+
+ avatar_node = lm_message_node_find_child (m, "photo");
+ if (!avatar_node || !avatar_node->value) {
+ gossip_contact_set_avatar (contact, NULL);
+ return;
+ }
+
+ avatar = gossip_contact_get_avatar (contact);
+ if (avatar) {
+ sha1 = gossip_sha_hash (avatar->data, avatar->len);
+ } else {
+ sha1 = gossip_sha_hash (NULL, 0);
+ }
+
+ same = g_ascii_strcasecmp (sha1, avatar_node->value) == 0;
+ g_free (sha1);
+
+ if (same) {
+ return;
+ }
+ }
+
+ jabber_contact_get_vcard (jabber, contact, force_update);
+}
+
+static void
jabber_group_rename_foreach_cb (gpointer key,
gpointer value,
gpointer user_data)
@@ -2151,7 +2156,9 @@
return gossip_jabber_vcard_get (jabber,
jid_str,
- callback, user_data, error);
+ callback,
+ user_data,
+ error);
}
gboolean
@@ -3332,7 +3339,7 @@
/* Request contacts VCard details so we can get the
* real name for them for chat windows, etc
*/
- jabber_contact_vcard (jabber, contact);
+ jabber_contact_get_vcard (jabber, contact, FALSE);
}
}
Modified: trunk/libgossip/gossip-jabber.h
==============================================================================
--- trunk/libgossip/gossip-jabber.h (original)
+++ trunk/libgossip/gossip-jabber.h Wed Jul 30 08:51:51 2008
@@ -35,7 +35,7 @@
#define GOSSIP_IS_JABBER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_JABBER))
#define GOSSIP_JABBER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_JABBER, GossipJabberClass))
-#define GOSSIP_JABBER_ERROR gnome_jabber_error_quark()
+#define GOSSIP_JABBER_ERROR gnome_jabber_error_quark ()
typedef struct _GossipJabber GossipJabber;
typedef struct _GossipJabberClass GossipJabberClass;
@@ -81,8 +81,8 @@
void gossip_jabber_subscription_allow_all (GossipJabber *jabber);
void gossip_jabber_subscription_disallow_all (GossipJabber *jabber);
GossipAccount *gossip_jabber_new_account (void);
-gchar * gossip_jabber_get_default_server (const gchar *username);
-guint gossip_jabber_get_default_port (gboolean use_ssl);
+gchar * gossip_jabber_get_default_server (const gchar *username);
+guint gossip_jabber_get_default_port (gboolean use_ssl);
gboolean gossip_jabber_is_ssl_supported (void);
gboolean gossip_jabber_is_connected (GossipJabber *jabber);
gboolean gossip_jabber_is_connecting (GossipJabber *jabber);
Modified: trunk/libgossip/gossip-vcard.h
==============================================================================
--- trunk/libgossip/gossip-vcard.h (original)
+++ trunk/libgossip/gossip-vcard.h Wed Jul 30 08:51:51 2008
@@ -47,36 +47,35 @@
GObjectClass parent_class;
};
-GType gossip_vcard_get_type (void) G_GNUC_CONST;
+GType gossip_vcard_get_type (void) G_GNUC_CONST;
-GossipVCard * gossip_vcard_new (void);
+GossipVCard * gossip_vcard_new (void);
-const gchar * gossip_vcard_get_name (GossipVCard *vcard);
-const gchar * gossip_vcard_get_nickname (GossipVCard *vcard);
-const gchar * gossip_vcard_get_birthday (GossipVCard *vcard);
-const gchar * gossip_vcard_get_email (GossipVCard *vcard);
-const gchar * gossip_vcard_get_url (GossipVCard *vcard);
-const gchar * gossip_vcard_get_country (GossipVCard *vcard);
-const gchar * gossip_vcard_get_description (GossipVCard *vcard);
-GossipAvatar *gossip_vcard_get_avatar (GossipVCard *vcard);
-GdkPixbuf * gossip_vcard_create_avatar_pixbuf (GossipVCard *vcard);
-
-void gossip_vcard_set_name (GossipVCard *vcard,
- const gchar *name);
-void gossip_vcard_set_nickname (GossipVCard *vcard,
- const gchar *nickname);
-void gossip_vcard_set_birthday (GossipVCard *vcard,
- const gchar *birthday);
-void gossip_vcard_set_email (GossipVCard *vcard,
- const gchar *email);
-void gossip_vcard_set_url (GossipVCard *vcard,
- const gchar *url);
-void gossip_vcard_set_country (GossipVCard *vcard,
- const gchar *country);
-void gossip_vcard_set_description (GossipVCard *vcard,
- const gchar *desc);
-void gossip_vcard_set_avatar (GossipVCard *vcard,
- GossipAvatar *avatar);
+const gchar * gossip_vcard_get_name (GossipVCard *vcard);
+const gchar * gossip_vcard_get_nickname (GossipVCard *vcard);
+const gchar * gossip_vcard_get_birthday (GossipVCard *vcard);
+const gchar * gossip_vcard_get_email (GossipVCard *vcard);
+const gchar * gossip_vcard_get_url (GossipVCard *vcard);
+const gchar * gossip_vcard_get_country (GossipVCard *vcard);
+const gchar * gossip_vcard_get_description (GossipVCard *vcard);
+GossipAvatar *gossip_vcard_get_avatar (GossipVCard *vcard);
+GdkPixbuf * gossip_vcard_create_avatar_pixbuf (GossipVCard *vcard);
+void gossip_vcard_set_name (GossipVCard *vcard,
+ const gchar *name);
+void gossip_vcard_set_nickname (GossipVCard *vcard,
+ const gchar *nickname);
+void gossip_vcard_set_birthday (GossipVCard *vcard,
+ const gchar *birthday);
+void gossip_vcard_set_email (GossipVCard *vcard,
+ const gchar *email);
+void gossip_vcard_set_url (GossipVCard *vcard,
+ const gchar *url);
+void gossip_vcard_set_country (GossipVCard *vcard,
+ const gchar *country);
+void gossip_vcard_set_description (GossipVCard *vcard,
+ const gchar *desc);
+void gossip_vcard_set_avatar (GossipVCard *vcard,
+ GossipAvatar *avatar);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]