merge of 'f78451b4a2f7106eb8f8fa7275a7a29230593449'
and '149d7d8284ccacaa774afaac83d3b5ee975c0372'
--- a/libpurple/protocols/myspace/markup.h Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/markup.h Tue Sep 18 01:02:55 2007 +0000
@@ -1,27 +1,27 @@
-/* MySpaceIM Protocol Plugin - markup
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-#ifndef _MYSPACE_MARKUP_H
-#define _MYSPACE_MARKUP_H
-/* High-level msim markup <=> Purple html conversion functions. */
-gchar *msim_markup_to_html(MsimSession *, const gchar *raw);
-gchar *html_to_msim_markup(MsimSession *, const gchar *raw);
-#endif /* !_MYSPACE_MARKUP_H */
+/* MySpaceIM Protocol Plugin - markup + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +#ifndef _MYSPACE_MARKUP_H +#define _MYSPACE_MARKUP_H +/* High-level msim markup <=> Purple html conversion functions. */ +gchar *msim_markup_to_html(MsimSession *, const gchar *raw); +gchar *html_to_msim_markup(MsimSession *, const gchar *raw); +#endif /* !_MYSPACE_MARKUP_H */ --- a/libpurple/protocols/myspace/session.c Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/session.c Tue Sep 18 01:02:55 2007 +0000
@@ -1,95 +1,95 @@
-/* MySpaceIM Protocol Plugin, session
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- * Create a new MSIM session.
- * @param acct The account to create the session from.
- * @return Pointer to a new session. Free with msim_session_destroy.
-msim_session_new(PurpleAccount *acct)
- g_return_val_if_fail(acct != NULL, NULL);
- session = g_new0(MsimSession, 1);
- session->magic = MSIM_SESSION_STRUCT_MAGIC;
- session->account = acct;
- session->gc = purple_account_get_connection(acct);
- session->username = NULL;
- session->user_lookup_cb = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, NULL); /* do NOT free function pointers! (values) */
- session->user_lookup_cb_data = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, NULL);/* TODO: we don't know what the values are,
- they could be integers inside gpointers
- or strings, so I don't freed them.
- Figure this out, once free cache. */
- /* Created in msim_process_server_info() */
- session->server_info = NULL;
- session->rxbuf = g_new0(gchar, MSIM_READ_BUF_SIZE);
- session->last_comm = time(NULL);
- session->inbox_status = 0;
- * @param session The session to destroy.
-msim_session_destroy(MsimSession *session)
- g_return_if_fail(MSIM_SESSION_VALID(session));
- g_free(session->rxbuf);
- g_free(session->username);
- g_hash_table_destroy(session->user_lookup_cb);
- g_hash_table_destroy(session->user_lookup_cb_data);
- if (session->server_info) {
- msim_msg_free(session->server_info);
+/* MySpaceIM Protocol Plugin, session + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * Create a new MSIM session. + * @param acct The account to create the session from. + * @return Pointer to a new session. Free with msim_session_destroy. +msim_session_new(PurpleAccount *acct) + g_return_val_if_fail(acct != NULL, NULL); + session = g_new0(MsimSession, 1); + session->magic = MSIM_SESSION_STRUCT_MAGIC; + session->account = acct; + session->gc = purple_account_get_connection(acct); + session->username = NULL; + session->user_lookup_cb = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, NULL); /* do NOT free function pointers! (values) */ + session->user_lookup_cb_data = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, NULL);/* TODO: we don't know what the values are, + they could be integers inside gpointers + or strings, so I don't freed them. + Figure this out, once free cache. */ + /* Created in msim_process_server_info() */ + session->server_info = NULL; + session->rxbuf = g_new0(gchar, MSIM_READ_BUF_SIZE); + session->last_comm = time(NULL); + session->inbox_status = 0; + * @param session The session to destroy. +msim_session_destroy(MsimSession *session) + g_return_if_fail(MSIM_SESSION_VALID(session)); + g_free(session->rxbuf); + g_free(session->username); + g_hash_table_destroy(session->user_lookup_cb); + g_hash_table_destroy(session->user_lookup_cb_data); + if (session->server_info) { + msim_msg_free(session->server_info); --- a/libpurple/protocols/myspace/session.h Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/session.h Tue Sep 18 01:02:55 2007 +0000
@@ -1,57 +1,57 @@
-/* MySpaceIM Protocol Plugin, session
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-#ifndef _MYSPACE_SESSION_H
-#define _MYSPACE_SESSION_H
-/* Random number in every MsimSession, to ensure it is valid. */
-#define MSIM_SESSION_STRUCT_MAGIC 0xe4a6752b
-/* Everything needed to keep track of a session (proto_data field in PurpleConnection) */
-typedef struct _MsimSession
- guint magic; /**< MSIM_SESSION_STRUCT_MAGIC */
- PurpleAccount *account;
- guint sesskey; /**< Session key from server */
- guint userid; /**< This user's numeric user ID */
- gchar *username; /**< This user's unique username */
- gint fd; /**< File descriptor to/from server */
- GHashTable *user_lookup_cb; /**< Username -> userid lookup callback */
- GHashTable *user_lookup_cb_data; /**< Username -> userid lookup callback data */
- MsimMessage *server_info; /**< Parameters from server */
- gchar *rxbuf; /**< Receive buffer */
- guint rxoff; /**< Receive buffer offset */
- guint next_rid; /**< Next request/response ID */
- time_t last_comm; /**< Time received last communication */
- guint inbox_status; /**< Bit field of inbox notifications */
-/* Check if an MsimSession is valid */
-#define MSIM_SESSION_VALID(s) (session != NULL && session->magic == MSIM_SESSION_STRUCT_MAGIC)
-MsimSession *msim_session_new(PurpleAccount *acct);
-void msim_session_destroy(MsimSession *session);
-#endif /* !_MYSPACE_SESSION_H */
+/* MySpaceIM Protocol Plugin, session + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +#ifndef _MYSPACE_SESSION_H +#define _MYSPACE_SESSION_H +/* Random number in every MsimSession, to ensure it is valid. */ +#define MSIM_SESSION_STRUCT_MAGIC 0xe4a6752b +/* Everything needed to keep track of a session (proto_data field in PurpleConnection) */ +typedef struct _MsimSession + guint magic; /**< MSIM_SESSION_STRUCT_MAGIC */ + PurpleAccount *account; + guint sesskey; /**< Session key from server */ + guint userid; /**< This user's numeric user ID */ + gchar *username; /**< This user's unique username */ + gint fd; /**< File descriptor to/from server */ + GHashTable *user_lookup_cb; /**< Username -> userid lookup callback */ + GHashTable *user_lookup_cb_data; /**< Username -> userid lookup callback data */ + MsimMessage *server_info; /**< Parameters from server */ + gchar *rxbuf; /**< Receive buffer */ + guint rxoff; /**< Receive buffer offset */ + guint next_rid; /**< Next request/response ID */ + time_t last_comm; /**< Time received last communication */ + guint inbox_status; /**< Bit field of inbox notifications */ +/* Check if an MsimSession is valid */ +#define MSIM_SESSION_VALID(s) (session != NULL && session->magic == MSIM_SESSION_STRUCT_MAGIC) +MsimSession *msim_session_new(PurpleAccount *acct); +void msim_session_destroy(MsimSession *session); +#endif /* !_MYSPACE_SESSION_H */ --- a/libpurple/protocols/myspace/user.c Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/user.c Tue Sep 18 01:02:55 2007 +0000
@@ -1,437 +1,437 @@
-/* MySpaceIM Protocol Plugin, header file
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user);
-static gchar *msim_format_now_playing(gchar *band, gchar *song);
-static void msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text,
- gsize len, const gchar *error_message);
-/** Format the "now playing" indicator, showing the artist and song.
- * @return Return a new string (must be g_free()'d), or NULL.
-msim_format_now_playing(gchar *band, gchar *song)
- if ((band && strlen(band)) || (song && strlen(song))) {
- return g_strdup_printf("%s - %s",
- (band && strlen(band)) ? band : "Unknown Artist",
- (song && strlen(song)) ? song : "Unknown Song");
-/** Get the MsimUser from a PurpleBuddy, creating it if needed. */
-msim_get_user_from_buddy(PurpleBuddy *buddy)
- if (!buddy->proto_data) {
- /* No MsimUser for this buddy; make one. */
- /* TODO: where is this freed? */
- user = g_new0(MsimUser, 1);
- buddy->proto_data = (gpointer)user;
- user = (MsimUser *)(buddy->proto_data);
-/** Find and return an MsimUser * representing a user on the buddy list, or NULL. */
-msim_find_user(MsimSession *session, const gchar *username)
- buddy = purple_find_buddy(session->account, username);
- user = msim_get_user_from_buddy(buddy);
-/** Append user information to a PurpleNotifyUserInfo, given an MsimUser.
- * Used by msim_tooltip_text() and msim_get_info_cb() to show a user's profile.
-msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full)
- /* Useful to identify the account the tooltip refers to.
- * Other prpls show this. */
- purple_notify_user_info_add_pair(user_info, _("User"), user->username);
- uid = purple_blist_node_get_int(&user->buddy->node, "UserID");
- /* TODO: link to username, if available */
- purple_notify_user_info_add_pair(user_info, _("Profile"),
- g_strdup_printf("<a href=\"http://myspace.com/%d\">http://myspace.com/%d</a>",
- /* a/s/l...the vitals */
- purple_notify_user_info_add_pair(user_info, _("Age"),
- g_strdup_printf("%d", user->age));
- if (user->gender && strlen(user->gender)) {
- purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender);
- if (user->location && strlen(user->location)) {
- purple_notify_user_info_add_pair(user_info, _("Location"), user->location);
- /* Other information */
- if (user->headline && strlen(user->headline)) {
- purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline);
- str = msim_format_now_playing(user->band_name, user->song_name);
- if (str && strlen(str)) {
- purple_notify_user_info_add_pair(user_info, _("Song"), str);
- /* Note: total friends only available if looked up by uid, not username. */
- if (user->total_friends) {
- purple_notify_user_info_add_pair(user_info, _("Total Friends"),
- g_strdup_printf("%d", user->total_friends));
- /* Client information */
- str = user->client_info;
- purple_notify_user_info_add_pair(user_info, _("Client Version"),
- g_strdup_printf("%s (build %d)", str, cv));
- purple_notify_user_info_add_pair(user_info, _("Client Version"),
- purple_notify_user_info_add_pair(user_info, _("Client Version"),
- g_strdup_printf("Build %d", cv));
-/** Store a field of information about a buddy. */
-msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user)
- if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) {
- /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */
- purple_debug_info("msim", "associating uid %s with username %s\n", key_str, user->buddy->name);
- purple_blist_node_set_int(&user->buddy->node, "UserID", atol(value_str));
- /* Need to store in MsimUser, too? What if not on blist? */
- } else if (g_str_equal(key_str, "Age")) {
- user->age = atol(value_str);
- } else if (g_str_equal(key_str, "Gender")) {
- user->gender = g_strdup(value_str);
- } else if (g_str_equal(key_str, "Location")) {
- user->location = g_strdup(value_str);
- } else if (g_str_equal(key_str, "TotalFriends")) {
- user->total_friends = atol(value_str);
- } else if (g_str_equal(key_str, "DisplayName")) {
- user->display_name = g_strdup(value_str);
- } else if (g_str_equal(key_str, "BandName")) {
- user->band_name = g_strdup(value_str);
- } else if (g_str_equal(key_str, "SongName")) {
- user->song_name = g_strdup(value_str);
- } else if (g_str_equal(key_str, "UserName") || g_str_equal(key_str, "IMName") || g_str_equal(key_str, "NickName")) {
- /* Ignore because PurpleBuddy knows this already */
- } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) {
- const gchar *previous_url;
- user->image_url = g_strdup(value_str);
- /* Instead of showing 'no photo' picture, show nothing. */
- if (g_str_equal(user->image_url, "http://x.myspace.com/images/no_pic.gif"))
- purple_buddy_icons_set_for_user(user->buddy->account,
- /* TODO: use ETag for checksum */
- previous_url = purple_buddy_icons_get_checksum_for_user(user->buddy);
- /* Only download if URL changed */
- if (!previous_url || !g_str_equal(previous_url, user->image_url)) {
- purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, msim_downloaded_buddy_icon, (gpointer)user);
- } else if (g_str_equal(key_str, "LastImageUpdated")) {
- /* TODO: use somewhere */
- user->last_image_updated = atol(value_str);
- } else if (g_str_equal(key_str, "Headline")) {
- user->headline = g_strdup(value_str);
- /* TODO: other fields in MsimUser */
- msg = g_strdup_printf("msim_store_user_info_each: unknown field %s=%s",
- msim_unrecognized(NULL, NULL, msg);
-/** Save buddy information to the buddy list from a user info reply message.
- * @param msg The user information reply, with any amount of information.
- * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data.
- * Variable information is saved to the passed MsimUser structure. Permanent
- * information (UserID) is stored in the blist node of the buddy list (and
- * ends up in blist.xml, persisted to disk) if it exists.
- * If the function has no buddy information, this function
- * is a no-op (and returns FALSE).
-msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user)
- MsimMessage *body, *body_node;
- g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE);
- g_return_val_if_fail(msg != NULL, FALSE);
- body = msim_msg_get_dictionary(msg, "body");
- username = msim_msg_get_string(body, "UserName");
- purple_debug_info("msim",
- "msim_process_reply: not caching body, no UserName\n");
- /* Null user = find and store in PurpleBuddy's proto_data */
- user = msim_find_user(session, username);
- /* TODO: make looping over MsimMessage's easier. */
- body_node = msim_msg_get_next_element_node(body_node))
- MsimMessageElement *elem;
- elem = (MsimMessageElement *)body_node->data;
- value_str = msim_msg_get_string_from_element(elem);
- msim_store_user_info_each(key_str, value_str, user);
- if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN &&
- msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) {
- /* TODO: do something with our own IM info, if we need it for some
- * specific purpose. Otherwise it is available on the buddy list,
- * if the user has themselves as their own buddy.
- * However, much of the info is already available in MsimSession,
- * stored in msim_we_are_logged_on(). */
- } else if (msim_msg_get_integer(msg, "dsn") == MG_OWN_MYSPACE_INFO_DSN &&
- msim_msg_get_integer(msg, "lid") == MG_OWN_MYSPACE_INFO_LID) {
- /* TODO: same as above, but for MySpace info. */
- * Asynchronously lookup user information, calling callback when receive result.
- * @param user The user id, email address, or username. Not freed.
- * @param cb Callback, called with user information when available.
- * @param data An arbitray data pointer passed to the callback.
-/* TODO: change to not use callbacks */
-msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data)
- guint rid, cmd, dsn, lid;
- g_return_if_fail(MSIM_SESSION_VALID(session));
- g_return_if_fail(user != NULL);
- /* Callback can be null to not call anything, just lookup & store information. */
- /*g_return_if_fail(cb != NULL);*/
- purple_debug_info("msim", "msim_lookup_userid: "
- "asynchronously looking up <%s>\n", user);
- msim_msg_dump("msim_lookup_user: data=%s\n", (MsimMessage *)data);
- /* Setup callback. Response will be associated with request using 'rid'. */
- rid = msim_new_reply_callback(session, cb, data);
- if (msim_is_userid(user)) {
- dsn = MG_MYSPACE_INFO_BY_ID_DSN;
- lid = MG_MYSPACE_INFO_BY_ID_LID;
- } else if (msim_is_email(user)) {
- dsn = MG_MYSPACE_INFO_BY_STRING_DSN;
- lid = MG_MYSPACE_INFO_BY_STRING_LID;
- field_name = "UserName";
- dsn = MG_MYSPACE_INFO_BY_STRING_DSN;
- lid = MG_MYSPACE_INFO_BY_STRING_LID;
- field_name, MSIM_TYPE_STRING, g_strdup(user),
- g_return_if_fail(msim_send(session,
- "persist", MSIM_TYPE_INTEGER, 1,
- "sesskey", MSIM_TYPE_INTEGER, session->sesskey,
- "cmd", MSIM_TYPE_INTEGER, 1,
- "dsn", MSIM_TYPE_INTEGER, dsn,
- "uid", MSIM_TYPE_INTEGER, session->userid,
- "lid", MSIM_TYPE_INTEGER, lid,
- "rid", MSIM_TYPE_INTEGER, rid,
- "body", MSIM_TYPE_DICTIONARY, body,
- * Check if a string is a userid (all numeric).
- * @param user The user id, email, or name.
- * @return TRUE if is userid, FALSE if not.
-msim_is_userid(const gchar *user)
- g_return_val_if_fail(user != NULL, FALSE);
- return strspn(user, "0123456789") == strlen(user);
- * Check if a string is an email address (contains an @).
- * @param user The user id, email, or name.
- * @return TRUE if is an email, FALSE if not.
- * This function is not intended to be used as a generic
- * means of validating email addresses, but to distinguish
- * between a user represented by an email address from
- * other forms of identification.
-msim_is_email(const gchar *user)
- g_return_val_if_fail(user != NULL, FALSE);
- return strchr(user, '@') != NULL;
-/** Callback for when a buddy icon finished being downloaded. */
-msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data,
- const gchar *error_message)
- user = (MsimUser *)user_data;
- purple_debug_info("msim_downloaded_buddy_icon",
- "Downloaded %d bytes\n", len);
- purple_debug_info("msim_downloaded_buddy_icon",
- "failed to download icon for %s",
- purple_buddy_icons_set_for_user(user->buddy->account,
- g_memdup((gchar *)url_text, len), len,
- /* Use URL itself as buddy icon "checksum" (TODO: ETag) */
- user->image_url); /* checksum */
+/* MySpaceIM Protocol Plugin, header file + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user); +static gchar *msim_format_now_playing(gchar *band, gchar *song); +static void msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, + gsize len, const gchar *error_message); +/** Format the "now playing" indicator, showing the artist and song. + * @return Return a new string (must be g_free()'d), or NULL. +msim_format_now_playing(gchar *band, gchar *song) + if ((band && strlen(band)) || (song && strlen(song))) { + return g_strdup_printf("%s - %s", + (band && strlen(band)) ? band : "Unknown Artist", + (song && strlen(song)) ? song : "Unknown Song"); +/** Get the MsimUser from a PurpleBuddy, creating it if needed. */ +msim_get_user_from_buddy(PurpleBuddy *buddy) + if (!buddy->proto_data) { + /* No MsimUser for this buddy; make one. */ + /* TODO: where is this freed? */ + user = g_new0(MsimUser, 1); + buddy->proto_data = (gpointer)user; + user = (MsimUser *)(buddy->proto_data); +/** Find and return an MsimUser * representing a user on the buddy list, or NULL. */ +msim_find_user(MsimSession *session, const gchar *username) + buddy = purple_find_buddy(session->account, username); + user = msim_get_user_from_buddy(buddy); +/** Append user information to a PurpleNotifyUserInfo, given an MsimUser. + * Used by msim_tooltip_text() and msim_get_info_cb() to show a user's profile. +msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full) + /* Useful to identify the account the tooltip refers to. + * Other prpls show this. */ + purple_notify_user_info_add_pair(user_info, _("User"), user->username); + uid = purple_blist_node_get_int(&user->buddy->node, "UserID"); + /* TODO: link to username, if available */ + purple_notify_user_info_add_pair(user_info, _("Profile"), + g_strdup_printf("<a href=\"http://myspace.com/%d\">http://myspace.com/%d</a>", + /* a/s/l...the vitals */ + purple_notify_user_info_add_pair(user_info, _("Age"), + g_strdup_printf("%d", user->age)); + if (user->gender && strlen(user->gender)) { + purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender); + if (user->location && strlen(user->location)) { + purple_notify_user_info_add_pair(user_info, _("Location"), user->location); + /* Other information */ + if (user->headline && strlen(user->headline)) { + purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline); + str = msim_format_now_playing(user->band_name, user->song_name); + if (str && strlen(str)) { + purple_notify_user_info_add_pair(user_info, _("Song"), str); + /* Note: total friends only available if looked up by uid, not username. */ + if (user->total_friends) { + purple_notify_user_info_add_pair(user_info, _("Total Friends"), + g_strdup_printf("%d", user->total_friends)); + /* Client information */ + str = user->client_info; + purple_notify_user_info_add_pair(user_info, _("Client Version"), + g_strdup_printf("%s (build %d)", str, cv)); + purple_notify_user_info_add_pair(user_info, _("Client Version"), + purple_notify_user_info_add_pair(user_info, _("Client Version"), + g_strdup_printf("Build %d", cv)); +/** Store a field of information about a buddy. */ +msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user) + if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) { + /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */ + purple_debug_info("msim", "associating uid %s with username %s\n", key_str, user->buddy->name); + purple_blist_node_set_int(&user->buddy->node, "UserID", atol(value_str)); + /* Need to store in MsimUser, too? What if not on blist? */ + } else if (g_str_equal(key_str, "Age")) { + user->age = atol(value_str); + } else if (g_str_equal(key_str, "Gender")) { + user->gender = g_strdup(value_str); + } else if (g_str_equal(key_str, "Location")) { + user->location = g_strdup(value_str); + } else if (g_str_equal(key_str, "TotalFriends")) { + user->total_friends = atol(value_str); + } else if (g_str_equal(key_str, "DisplayName")) { + user->display_name = g_strdup(value_str); + } else if (g_str_equal(key_str, "BandName")) { + user->band_name = g_strdup(value_str); + } else if (g_str_equal(key_str, "SongName")) { + user->song_name = g_strdup(value_str); + } else if (g_str_equal(key_str, "UserName") || g_str_equal(key_str, "IMName") || g_str_equal(key_str, "NickName")) { + /* Ignore because PurpleBuddy knows this already */ + } else if (g_str_equal(key_str, "ImageURL") || g_str_equal(key_str, "AvatarURL")) { + const gchar *previous_url; + user->image_url = g_strdup(value_str); + /* Instead of showing 'no photo' picture, show nothing. */ + if (g_str_equal(user->image_url, "http://x.myspace.com/images/no_pic.gif")) + purple_buddy_icons_set_for_user(user->buddy->account, + /* TODO: use ETag for checksum */ + previous_url = purple_buddy_icons_get_checksum_for_user(user->buddy); + /* Only download if URL changed */ + if (!previous_url || !g_str_equal(previous_url, user->image_url)) { + purple_util_fetch_url(user->image_url, TRUE, NULL, TRUE, msim_downloaded_buddy_icon, (gpointer)user); + } else if (g_str_equal(key_str, "LastImageUpdated")) { + /* TODO: use somewhere */ + user->last_image_updated = atol(value_str); + } else if (g_str_equal(key_str, "Headline")) { + user->headline = g_strdup(value_str); + /* TODO: other fields in MsimUser */ + msg = g_strdup_printf("msim_store_user_info_each: unknown field %s=%s", + msim_unrecognized(NULL, NULL, msg); +/** Save buddy information to the buddy list from a user info reply message. + * @param msg The user information reply, with any amount of information. + * @param user The structure to save to, or NULL to save in PurpleBuddy->proto_data. + * Variable information is saved to the passed MsimUser structure. Permanent + * information (UserID) is stored in the blist node of the buddy list (and + * ends up in blist.xml, persisted to disk) if it exists. + * If the function has no buddy information, this function + * is a no-op (and returns FALSE). +msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user) + MsimMessage *body, *body_node; + g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); + g_return_val_if_fail(msg != NULL, FALSE); + body = msim_msg_get_dictionary(msg, "body"); + username = msim_msg_get_string(body, "UserName"); + purple_debug_info("msim", + "msim_process_reply: not caching body, no UserName\n"); + /* Null user = find and store in PurpleBuddy's proto_data */ + user = msim_find_user(session, username); + /* TODO: make looping over MsimMessage's easier. */ + body_node = msim_msg_get_next_element_node(body_node)) + MsimMessageElement *elem; + elem = (MsimMessageElement *)body_node->data; + value_str = msim_msg_get_string_from_element(elem); + msim_store_user_info_each(key_str, value_str, user); + if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN && + msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) { + /* TODO: do something with our own IM info, if we need it for some + * specific purpose. Otherwise it is available on the buddy list, + * if the user has themselves as their own buddy. + * However, much of the info is already available in MsimSession, + * stored in msim_we_are_logged_on(). */ + } else if (msim_msg_get_integer(msg, "dsn") == MG_OWN_MYSPACE_INFO_DSN && + msim_msg_get_integer(msg, "lid") == MG_OWN_MYSPACE_INFO_LID) { + /* TODO: same as above, but for MySpace info. */ + * Asynchronously lookup user information, calling callback when receive result. + * @param user The user id, email address, or username. Not freed. + * @param cb Callback, called with user information when available. + * @param data An arbitray data pointer passed to the callback. +/* TODO: change to not use callbacks */ +msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data) + guint rid, cmd, dsn, lid; + g_return_if_fail(MSIM_SESSION_VALID(session)); + g_return_if_fail(user != NULL); + /* Callback can be null to not call anything, just lookup & store information. */ + /*g_return_if_fail(cb != NULL);*/ + purple_debug_info("msim", "msim_lookup_userid: " + "asynchronously looking up <%s>\n", user); + msim_msg_dump("msim_lookup_user: data=%s\n", (MsimMessage *)data); + /* Setup callback. Response will be associated with request using 'rid'. */ + rid = msim_new_reply_callback(session, cb, data); + if (msim_is_userid(user)) { + dsn = MG_MYSPACE_INFO_BY_ID_DSN; + lid = MG_MYSPACE_INFO_BY_ID_LID; + } else if (msim_is_email(user)) { + dsn = MG_MYSPACE_INFO_BY_STRING_DSN; + lid = MG_MYSPACE_INFO_BY_STRING_LID; + field_name = "UserName"; + dsn = MG_MYSPACE_INFO_BY_STRING_DSN; + lid = MG_MYSPACE_INFO_BY_STRING_LID; + field_name, MSIM_TYPE_STRING, g_strdup(user), + g_return_if_fail(msim_send(session, + "persist", MSIM_TYPE_INTEGER, 1, + "sesskey", MSIM_TYPE_INTEGER, session->sesskey, + "cmd", MSIM_TYPE_INTEGER, 1, + "dsn", MSIM_TYPE_INTEGER, dsn, + "uid", MSIM_TYPE_INTEGER, session->userid, + "lid", MSIM_TYPE_INTEGER, lid, + "rid", MSIM_TYPE_INTEGER, rid, + "body", MSIM_TYPE_DICTIONARY, body, + * Check if a string is a userid (all numeric). + * @param user The user id, email, or name. + * @return TRUE if is userid, FALSE if not. +msim_is_userid(const gchar *user) + g_return_val_if_fail(user != NULL, FALSE); + return strspn(user, "0123456789") == strlen(user); + * Check if a string is an email address (contains an @). + * @param user The user id, email, or name. + * @return TRUE if is an email, FALSE if not. + * This function is not intended to be used as a generic + * means of validating email addresses, but to distinguish + * between a user represented by an email address from + * other forms of identification. +msim_is_email(const gchar *user) + g_return_val_if_fail(user != NULL, FALSE); + return strchr(user, '@') != NULL; +/** Callback for when a buddy icon finished being downloaded. */ +msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, + const gchar *error_message) + user = (MsimUser *)user_data; + purple_debug_info("msim_downloaded_buddy_icon", + "Downloaded %d bytes\n", len); + purple_debug_info("msim_downloaded_buddy_icon", + "failed to download icon for %s", + purple_buddy_icons_set_for_user(user->buddy->account, + g_memdup((gchar *)url_text, len), len, + /* Use URL itself as buddy icon "checksum" (TODO: ETag) */ + user->image_url); /* checksum */ --- a/libpurple/protocols/myspace/user.h Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/user.h Tue Sep 18 01:02:55 2007 +0000
@@ -1,55 +1,55 @@
-/* MySpaceIM Protocol Plugin, header file
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-/* Hold ephemeral information about buddies, for proto_data of PurpleBuddy. */
-typedef struct _MsimUser
- /* Note: uid is in &buddy->node (set_blist_node_int), since it never changes */
- gchar *band_name, *song_name;
- guint last_image_updated;
-/* Callback function pointer type for when a user's information is received,
- * initiated from a user lookup. */
-typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, MsimMessage *userinfo, gpointer data);
-MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy);
-MsimUser *msim_find_user(MsimSession *session, const gchar *username);
-void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full);
-gboolean msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user);
-gboolean msim_is_userid(const gchar *user);
-gboolean msim_is_email(const gchar *user);
-void msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data);
-#endif /* !_MYSPACE_USER_H */
+/* MySpaceIM Protocol Plugin, header file + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +/* Hold ephemeral information about buddies, for proto_data of PurpleBuddy. */ +typedef struct _MsimUser + /* Note: uid is in &buddy->node (set_blist_node_int), since it never changes */ + gchar *band_name, *song_name; + guint last_image_updated; +/* Callback function pointer type for when a user's information is received, + * initiated from a user lookup. */ +typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, MsimMessage *userinfo, gpointer data); +MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy); +MsimUser *msim_find_user(MsimSession *session, const gchar *username); +void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full); +gboolean msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user); +gboolean msim_is_userid(const gchar *user); +gboolean msim_is_email(const gchar *user); +void msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data); +#endif /* !_MYSPACE_USER_H */ --- a/libpurple/protocols/myspace/zap.c Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/zap.c Tue Sep 18 01:02:55 2007 +0000
@@ -1,208 +1,208 @@
-/* MySpaceIM Protocol Plugin - zap support
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-static gboolean msim_send_zap(MsimSession *session, const gchar *username, guint code);
-static void msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr);
-msim_attention_types(PurpleAccount *acct)
- static GList *types = NULL;
- MsimAttentionType* attn;
-#define _MSIM_ADD_NEW_ATTENTION(icn, nme, incoming, outgoing) \
- attn = g_new0(MsimAttentionType, 1); \
- attn->icon_name = icn; \
- attn->incoming_description = incoming; \
- attn->outgoing_description = outgoing; \
- types = g_list_append(types, attn);
- /* TODO: icons for each zap */
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Zap"), _("%s has zapped you!"), _("Zapping %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Whack"), _("%s has whacked you!"), _("Whacking %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Torch"), _("%s has torched you!"), _("Torching %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Smooch"), _("%s has smooched you!"), _("Smooching %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Hug"), _("%s has hugged you!"), _("Hugging %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Slap"), _("%s has slapped you!"), _("Slapping %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Goose"), _("%s has goosed you!"), _("Goosing %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("High-five"), _("%s has high-fived you!"), _("High-fiving %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Punk"), _("%s has punk'd you!"), _("Punking %s..."));
- _MSIM_ADD_NEW_ATTENTION(NULL, _("Raspberry"), _("%s has raspberried you!"), _("Raspberrying %s..."));
-msim_send_attention(PurpleConnection *gc, const gchar *username, guint code)
- MsimAttentionType *attn;
- session = (MsimSession *)gc->proto_data;
- /* Look for this attention type, by the code index given. */
- types = msim_attention_types(gc->account);
- attn = (MsimAttentionType *)g_list_nth_data(types, code);
- purple_debug_info("msim_send_attention", "got invalid zap code %d\n", code);
- buddy = purple_find_buddy(session->account, username);
- msim_send_zap(session, username, code);
-/** Send a zap to a user. */
-msim_send_zap(MsimSession *session, const gchar *username, guint code)
- g_return_val_if_fail(session != NULL, FALSE);
- g_return_val_if_fail(username != NULL, FALSE);
- /* Construct and send the actual zap command. */
- zap_string = g_strdup_printf("!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", code);
- if (!msim_send_bm(session, username, zap_string, MSIM_BM_ACTION)) {
- purple_debug_info("msim_send_zap_from_menu", "msim_send_bm failed: zapping %s with %s\n",
-/** Zap someone. Callback from msim_blist_node_menu zap menu. */
-msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr)
- PurpleAccount *account;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- /* Only know about buddies for now. */
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- buddy = (PurpleBuddy *)node;
- account = buddy->account;
- gc = purple_account_get_connection(account);
- session = (MsimSession *)gc->proto_data;
- zap = GPOINTER_TO_INT(zap_num_ptr);
- serv_send_attention(session->gc, buddy->name, zap);
-/** Return menu, if any, for a buddy list node. */
-msim_blist_node_menu(PurpleBlistNode *node)
- GList *menu, *zap_menu;
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- /* Only know about buddies for now. */
- /* TODO: get rid of once is accessible directly in GUI */
- types = msim_attention_types(NULL);
- MsimAttentionType *attn;
- attn = (MsimAttentionType *)types->data;
- act = purple_menu_action_new(attn->name, PURPLE_CALLBACK(msim_send_zap_from_menu),
- GUINT_TO_POINTER(i), NULL);
- zap_menu = g_list_append(zap_menu, act);
- } while ((types = g_list_next(types)));
- act = purple_menu_action_new(_("Zap"), NULL, NULL, zap_menu);
- menu = g_list_append(NULL, act);
-/** Process an incoming zap. */
-msim_incoming_zap(MsimSession *session, MsimMessage *msg)
- gchar *msg_text, *username;
- msg_text = msim_msg_get_string(msg, "msg");
- username = msim_msg_get_string(msg, "_username");
- g_return_val_if_fail(msg_text != NULL, FALSE);
- g_return_val_if_fail(username != NULL, FALSE);
- g_return_val_if_fail(sscanf(msg_text, "!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", &zap) == 1, FALSE);
- zap = CLAMP(zap, 0, 9);
- serv_got_attention(session->gc, username, zap);
+/* MySpaceIM Protocol Plugin - zap support + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +static gboolean msim_send_zap(MsimSession *session, const gchar *username, guint code); +static void msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr); +msim_attention_types(PurpleAccount *acct) + static GList *types = NULL; + MsimAttentionType* attn; +#define _MSIM_ADD_NEW_ATTENTION(icn, nme, incoming, outgoing) \ + attn = g_new0(MsimAttentionType, 1); \ + attn->icon_name = icn; \ + attn->incoming_description = incoming; \ + attn->outgoing_description = outgoing; \ + types = g_list_append(types, attn); + /* TODO: icons for each zap */ + _MSIM_ADD_NEW_ATTENTION(NULL, _("Zap"), _("%s has zapped you!"), _("Zapping %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Whack"), _("%s has whacked you!"), _("Whacking %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Torch"), _("%s has torched you!"), _("Torching %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Smooch"), _("%s has smooched you!"), _("Smooching %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Hug"), _("%s has hugged you!"), _("Hugging %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Slap"), _("%s has slapped you!"), _("Slapping %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Goose"), _("%s has goosed you!"), _("Goosing %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("High-five"), _("%s has high-fived you!"), _("High-fiving %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Punk"), _("%s has punk'd you!"), _("Punking %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, _("Raspberry"), _("%s has raspberried you!"), _("Raspberrying %s...")); +msim_send_attention(PurpleConnection *gc, const gchar *username, guint code) + MsimAttentionType *attn; + session = (MsimSession *)gc->proto_data; + /* Look for this attention type, by the code index given. */ + types = msim_attention_types(gc->account); + attn = (MsimAttentionType *)g_list_nth_data(types, code); + purple_debug_info("msim_send_attention", "got invalid zap code %d\n", code); + buddy = purple_find_buddy(session->account, username); + msim_send_zap(session, username, code); +/** Send a zap to a user. */ +msim_send_zap(MsimSession *session, const gchar *username, guint code) + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(username != NULL, FALSE); + /* Construct and send the actual zap command. */ + zap_string = g_strdup_printf("!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", code); + if (!msim_send_bm(session, username, zap_string, MSIM_BM_ACTION)) { + purple_debug_info("msim_send_zap_from_menu", "msim_send_bm failed: zapping %s with %s\n", +/** Zap someone. Callback from msim_blist_node_menu zap menu. */ +msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr) + PurpleAccount *account; + if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) { + /* Only know about buddies for now. */ + g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); + buddy = (PurpleBuddy *)node; + account = buddy->account; + gc = purple_account_get_connection(account); + session = (MsimSession *)gc->proto_data; + zap = GPOINTER_TO_INT(zap_num_ptr); + serv_send_attention(session->gc, buddy->name, zap); +/** Return menu, if any, for a buddy list node. */ +msim_blist_node_menu(PurpleBlistNode *node) + GList *menu, *zap_menu; + if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) { + /* Only know about buddies for now. */ + /* TODO: get rid of once is accessible directly in GUI */ + types = msim_attention_types(NULL); + MsimAttentionType *attn; + attn = (MsimAttentionType *)types->data; + act = purple_menu_action_new(attn->name, PURPLE_CALLBACK(msim_send_zap_from_menu), + GUINT_TO_POINTER(i), NULL); + zap_menu = g_list_append(zap_menu, act); + } while ((types = g_list_next(types))); + act = purple_menu_action_new(_("Zap"), NULL, NULL, zap_menu); + menu = g_list_append(NULL, act); +/** Process an incoming zap. */ +msim_incoming_zap(MsimSession *session, MsimMessage *msg) + gchar *msg_text, *username; + msg_text = msim_msg_get_string(msg, "msg"); + username = msim_msg_get_string(msg, "_username"); + g_return_val_if_fail(msg_text != NULL, FALSE); + g_return_val_if_fail(username != NULL, FALSE); + g_return_val_if_fail(sscanf(msg_text, "!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", &zap) == 1, FALSE); + zap = CLAMP(zap, 0, 9); + serv_got_attention(session->gc, username, zap); --- a/libpurple/protocols/myspace/zap.h Tue Sep 18 01:02:45 2007 +0000
+++ b/libpurple/protocols/myspace/zap.h Tue Sep 18 01:02:55 2007 +0000
@@ -1,28 +1,28 @@
-/* MySpaceIM Protocol Plugin - zap support
- * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-GList *msim_attention_types(PurpleAccount *acct);
-gboolean msim_send_attention(PurpleConnection *gc, const gchar *username, guint code);
-GList *msim_blist_node_menu(PurpleBlistNode *node);
-gboolean msim_incoming_zap(MsimSession *session, MsimMessage *msg);
-#endif /* !_MYSPACE_ZAP_H */
+/* MySpaceIM Protocol Plugin - zap support + * Copyright (C) 2007, Jeff Connelly <jeff2@soc.pidgin.im> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +GList *msim_attention_types(PurpleAccount *acct); +gboolean msim_send_attention(PurpleConnection *gc, const gchar *username, guint code); +GList *msim_blist_node_menu(PurpleBlistNode *node); +gboolean msim_incoming_zap(MsimSession *session, MsimMessage *msg); +#endif /* !_MYSPACE_ZAP_H */