pidgin: 22937ab2: Patch from Zac West which performs perio...
evands at pidgin.im
evands at pidgin.im
Sun Feb 20 20:36:07 EST 2011
----------------------------------------------------------------------
Revision: 22937ab220c41cd0c4a3f9e21e3db687db80da75
Parent: e7c103fdfbc59bb2ca41a3c8813c4ff2847a673f
Author: evands at pidgin.im
Date: 02/20/11 20:25:28
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/22937ab220c41cd0c4a3f9e21e3db687db80da75
Changelog:
Patch from Zac West which performs periodic WHO updates on IRC channel participants in order to track 'away' status, userhost, and real name. Plucked from a series of im.pidgin.adium commits.
Changes against parent e7c103fdfbc59bb2ca41a3c8813c4ff2847a673f
patched libpurple/protocols/irc/irc.c
patched libpurple/protocols/irc/irc.h
patched libpurple/protocols/irc/msgs.c
patched libpurple/protocols/irc/parse.c
-------------- next part --------------
============================================================
--- libpurple/protocols/irc/irc.c 9824f680d433623dac1d94bb4e8b6fead8d0e597
+++ libpurple/protocols/irc/irc.c d8ff17c7e1fdddcde1c6720e7b220c49deb1c870
@@ -41,6 +41,8 @@ static void irc_ison_buddy_init(char *na
static void irc_ison_buddy_init(char *name, struct irc_buddy *ib, GList **list);
+static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc);
+
static const char *irc_blist_icon(PurpleAccount *a, PurpleBuddy *b);
static GList *irc_status_types(PurpleAccount *account);
static GList *irc_actions(PurplePlugin *plugin, gpointer context);
@@ -232,6 +234,26 @@ static void irc_ison_buddy_init(char *na
*list = g_list_append(*list, ib);
}
+
+gboolean irc_who_channel_timeout(struct irc_conn *irc)
+{
+ // WHO all of our channels.
+ g_list_foreach(purple_get_conversations(), (GFunc)irc_who_channel, (gpointer)irc);
+
+ return TRUE;
+}
+
+static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc)
+{
+ if (purple_conversation_get_account(conv) == irc->account && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ char *buf = irc_format(irc, "vc", "WHO", purple_conversation_get_name(conv));
+
+ purple_debug(PURPLE_DEBUG_INFO, "irc", "Performing periodic who on %s", purple_conversation_get_name(conv));
+ irc_send(irc, buf);
+ g_free(buf);
+ }
+}
+
static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib)
{
char *buf;
@@ -517,6 +539,8 @@ static void irc_close(PurpleConnection *
}
if (irc->timer)
purple_timeout_remove(irc->timer);
+ if (irc->who_channel_timer)
+ purple_timeout_remove(irc->who_channel_timer);
g_hash_table_destroy(irc->cmds);
g_hash_table_destroy(irc->msgs);
g_hash_table_destroy(irc->buddies);
============================================================
--- libpurple/protocols/irc/irc.h df6b06ec27843e6a773c86340988fbd1dddc30a7
+++ libpurple/protocols/irc/irc.h 7e52fe9ba8caa9d1f5a4055123b287b54ef3f599
@@ -55,6 +55,7 @@ struct irc_conn {
char *server;
int fd;
guint timer;
+ guint who_channel_timer;
GHashTable *buddies;
gboolean ison_outstanding;
@@ -106,6 +107,7 @@ gboolean irc_blist_timeout(struct irc_co
int irc_send(struct irc_conn *irc, const char *buf);
gboolean irc_blist_timeout(struct irc_conn *irc);
+gboolean irc_who_channel_timeout(struct irc_conn *irc);
void irc_buddy_query(struct irc_conn *irc);
char *irc_escape_privmsg(const char *text, gssize length);
@@ -164,6 +166,7 @@ void irc_msg_whois(struct irc_conn *irc,
void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args);
void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args);
void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args);
+void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args);
void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args);
============================================================
--- libpurple/protocols/irc/msgs.c b5f39963e57607dc76e1fc35371acaeb0bd1f72f
+++ libpurple/protocols/irc/msgs.c 58a11bfdfa8d0e944ca399e095ec92f999244623
@@ -110,6 +110,8 @@ static void irc_connected(struct irc_con
irc_blist_timeout(irc);
if (!irc->timer)
irc->timer = purple_timeout_add_seconds(45, (GSourceFunc)irc_blist_timeout, (gpointer)irc);
+ if (!irc->who_channel_timer)
+ irc->who_channel_timer = purple_timeout_add_seconds(300, (GSourceFunc)irc_who_channel_timeout, (gpointer)irc);
}
void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args)
@@ -400,6 +402,59 @@ void irc_msg_endwhois(struct irc_conn *i
memset(&irc->whois, 0, sizeof(irc->whois));
}
+void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args)
+{
+ if (!strcmp(name, "352")) {
+ PurpleConversation *conv;
+ PurpleConvChat *chat;
+ PurpleConvChatBuddy *cb;
+
+ char *userhost, *realname;
+
+ PurpleConvChatBuddyFlags flags;
+ GList *keys = NULL, *values = NULL;
+
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account);
+ if (!conv) {
+ purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a WHO response for %s, which doesn't exist\n", args[1]);
+ return;
+ }
+
+ cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), args[5]);
+ if (!cb) {
+ purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a WHO response for %s who isn't a buddy.\n", args[5]);
+ return;
+ }
+
+ chat = PURPLE_CONV_CHAT(conv);
+
+ userhost = g_strdup_printf("%s@%s", args[2], args[3]);
+ realname = g_strdup(args[8]);
+
+ keys = g_list_prepend(keys, "userhost");
+ values = g_list_prepend(values, userhost);
+
+ keys = g_list_prepend(keys, "realname");
+ values = g_list_prepend(values, realname);
+
+ purple_conv_chat_cb_set_attributes(chat, cb, keys, values);
+
+ g_list_free(keys);
+ g_list_free(values);
+
+ g_free(userhost);
+ g_free(realname);
+
+ flags = purple_conv_chat_user_get_flags(chat, cb->name);
+
+ if (args[6][0] == 'G' && !(flags & PURPLE_CBFLAGS_AWAY)) {
+ purple_conv_chat_user_set_flags(chat, cb->name, flags | PURPLE_CBFLAGS_AWAY);
+ } else if(args[6][0] == 'H' && (flags & PURPLE_CBFLAGS_AWAY)) {
+ purple_conv_chat_user_set_flags(chat, cb->name, flags & ~PURPLE_CBFLAGS_AWAY);
+ }
+ }
+}
+
void irc_msg_list(struct irc_conn *irc, const char *name, const char *from, char **args)
{
if (!irc->roomlist)
@@ -797,7 +852,10 @@ void irc_msg_join(struct irc_conn *irc,
{
PurpleConnection *gc = purple_account_get_connection(irc->account);
PurpleConversation *convo;
- char *nick = irc_mask_nick(from), *userhost;
+ PurpleConvChat *chat;
+ PurpleConvChatBuddy *cb;
+
+ char *nick = irc_mask_nick(from), *userhost, *buf;
struct irc_buddy *ib;
static int id = 1;
@@ -820,6 +878,12 @@ void irc_msg_join(struct irc_conn *irc,
}
purple_conversation_set_data(convo, IRC_NAMES_FLAG,
GINT_TO_POINTER(FALSE));
+
+ // Get the real name and user host for all participants.
+ buf = irc_format(irc, "vc", "WHO", args[0]);
+ irc_send(irc, buf);
+ g_free(buf);
+
/* Until purple_conversation_present does something that
* one would expect in Pidgin, this call produces buggy
* behavior both for the /join and auto-join cases. */
@@ -835,8 +899,16 @@ void irc_msg_join(struct irc_conn *irc,
}
userhost = irc_mask_userhost(from);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), nick, userhost, PURPLE_CBFLAGS_NONE, TRUE);
-
+ chat = PURPLE_CONV_CHAT(convo);
+
+ purple_conv_chat_add_user(chat, nick, userhost, PURPLE_CBFLAGS_NONE, TRUE);
+
+ cb = purple_conv_chat_cb_find(chat, nick);
+
+ if (cb) {
+ purple_conv_chat_cb_set_attribute(chat, cb, "userhost", userhost);
+ }
+
if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) {
ib->new_online_status = TRUE;
irc_buddy_status(nick, ib, irc);
============================================================
--- libpurple/protocols/irc/parse.c bef80be622ee6689a6c7cc26d8022584cfcfaa3d
+++ libpurple/protocols/irc/parse.c 7ba5e0c60a470adb5b676d9101bd56b8ebc11e74
@@ -65,6 +65,7 @@ static struct _irc_msg {
{ "319", "nn:", irc_msg_whois }, /* Whois channels */
{ "320", "nn:", irc_msg_whois }, /* Whois (fn ident) */
{ "314", "nnnvv:", irc_msg_whois }, /* Whowas user */
+ { "315", "nt:", irc_msg_who }, /* end of WHO channel */
{ "369", "nt:", irc_msg_endwhois }, /* End of WHOWAS */
{ "321", "*", irc_msg_list }, /* Start of list */
{ "322", "ncv:", irc_msg_list }, /* List. */
@@ -73,6 +74,7 @@ static struct _irc_msg {
{ "331", "nc:", irc_msg_topic }, /* No channel topic */
{ "332", "nc:", irc_msg_topic }, /* Channel topic */
{ "333", "*", irc_msg_ignore }, /* Topic setter stuff */
+ { "352", "nvcvnvvv:", irc_msg_who }, /* Channel WHO */
{ "353", "nvc:", irc_msg_names }, /* Names list */
{ "366", "nc:", irc_msg_names }, /* End of names */
{ "367", "ncnnv", irc_msg_ban }, /* Ban list */
More information about the Commits
mailing list