#include "internal.h" #include "version.h" #include "pidginstock.h" #include "gtkblist.h" #include "gtkplugin.h" #include "gtkutils.h" #include "dbus-maybe.h" #define MEEBO_PLUGIN_ID "gtk-meebo" static void *request_authorize; const char *meebo_guests_group = "Meebo Guests"; static void add_meebo_guest(PurpleAccount *account, const char *username, const char *group, const char *alias) { PurpleGroup *g; PurpleBuddy *b; PurpleConversation *c; group = meebo_guests_group; if (username == NULL) username = "meebo guest"; if ((g = purple_find_group(group)) == NULL) { g = purple_group_new(group); purple_blist_add_group(g, NULL); } b = purple_buddy_new(account, username, alias); purple_blist_add_buddy(b, NULL, g, NULL); purple_account_add_buddy(account, b); c = purple_find_conversation_with_account( PURPLE_CONV_TYPE_IM, username, account); if (c != NULL) { PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(c)); if (icon != NULL) purple_buddy_icon_update(icon); } } struct auth_and_add { PurpleAccountRequestAuthorizationCb auth_cb; PurpleAccountRequestAuthorizationCb deny_cb; void *data; char *username; char *alias; PurpleAccount *account; }; static void authorize_and_add_cb(struct auth_and_add *aa) { aa->auth_cb(aa->data); purple_blist_request_add_buddy(aa->account, aa->username, NULL, aa->alias); g_free(aa->username); g_free(aa->alias); g_free(aa); } static void authorize_and_add_cb_meebo(struct auth_and_add *aa) { aa->auth_cb(aa->data); add_meebo_guest(aa->account, aa->username, NULL, aa->alias); g_free(aa->username); g_free(aa->alias); g_free(aa); } static void deny_no_add_cb(struct auth_and_add *aa) { aa->deny_cb(aa->data); g_free(aa->username); g_free(aa->alias); g_free(aa); } static void * my_pidgin_accounts_request_authorization(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, const char *message, gboolean on_list, GCallback auth_cb, GCallback deny_cb, void *user_data) { char *buffer; PurpleConnection *gc; GtkWidget *alert; PurplePluginProtocolInfo *prpl_info; const char* protoname; gc = purple_account_get_connection(account); if (message != NULL && *message == '\0') message = NULL; prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); protoname = prpl_info->list_icon(account, NULL); if(!strcmp(protoname, "jabber") && strstr(g_strdup(remote_user),"@guest") != NULL && strstr(g_strdup(remote_user),".meebo.org") != NULL) { struct auth_and_add *aa = g_new0(struct auth_and_add, 1); aa->auth_cb = (PurpleAccountRequestAuthorizationCb)auth_cb; aa->deny_cb = (PurpleAccountRequestAuthorizationCb)deny_cb; aa->data = user_data; aa->username = g_strdup(remote_user); aa->alias = g_strdup(alias); aa->account = account; authorize_and_add_cb_meebo(aa); } else { buffer = g_strdup_printf(_("%s%s%s%s wants to add %s to his or her buddy list%s%s"), remote_user, (alias != NULL ? " (" : ""), (alias != NULL ? alias : ""), (alias != NULL ? ")" : ""), (id != NULL ? id : (purple_connection_get_display_name(gc) != NULL ? purple_connection_get_display_name(gc) : purple_account_get_username(account))), (message != NULL ? ": " : "."), (message != NULL ? message : "")); if (!on_list) { struct auth_and_add *aa = g_new0(struct auth_and_add, 1); aa->auth_cb = (PurpleAccountRequestAuthorizationCb)auth_cb; aa->deny_cb = (PurpleAccountRequestAuthorizationCb)deny_cb; aa->data = user_data; aa->username = g_strdup(remote_user); aa->alias = g_strdup(alias); aa->account = account; alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION, _("Authorize buddy?"), buffer, aa, _("Authorize"), authorize_and_add_cb, _("Deny"), deny_no_add_cb, NULL); } else { alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION, _("Authorize buddy?"), buffer, user_data, _("Authorize"), auth_cb, _("Deny"), deny_cb, NULL); } pidgin_blist_add_alert(alert); g_free(buffer); } return NULL; } static void remove_group(PurpleGroup *group) { PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); PurpleBuddyList *purplebuddylist = purple_get_blist(); PurpleBlistNode *node; GList *l; g_return_if_fail(group != NULL); node = (PurpleBlistNode *)group; /* Remove the node from its parent */ if (purplebuddylist->root == node) purplebuddylist->root = node->next; if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; purple_blist_schedule_save(); /* Update the UI */ if (ops && ops->remove) ops->remove(purplebuddylist, node); /* Remove the group from all accounts that are online */ for (l = purple_connections_get_all(); l != NULL; l = l->next) { PurpleConnection *gc = (PurpleConnection *)l->data; if (purple_connection_get_state(gc) == PURPLE_CONNECTED) purple_account_remove_group(purple_connection_get_account(gc), group); } /* Delete the node */ g_hash_table_destroy(group->node.settings); g_free(group->name); PURPLE_DBUS_UNREGISTER_POINTER(group); g_free(group); } static void remove_meebo_buddy(PurpleBuddy *buddy) { PurpleGroup *group = purple_buddy_get_group(buddy); purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group); purple_blist_remove_buddy(buddy); if(!((PurpleBlistNode*)group)->child) { remove_group(group); } } static void buddy_signoff_cb(PurpleBuddy *buddy) { PurplePlugin *plugin = purple_plugins_find_with_id(purple_account_get_protocol_id(buddy->account)); PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); const char* protoname = prpl_info->list_icon(purple_buddy_get_account(buddy), NULL); const char* name = purple_buddy_get_name(buddy); if(!strcmp(protoname, "jabber") && strstr(name,"@guest") != NULL && strstr(name,".meebo.org") != NULL) { purple_timeout_add(10000,(GSourceFunc)remove_meebo_buddy, buddy); } } static void sign_on_cb(PurpleConnection *gc, PurpleBuddyList *blist) { PurpleGroup *group; group = purple_find_group(meebo_guests_group); remove_group(group); } static void xmlnode_received_cb(PurpleConnection *gc, xmlnode **packet, gpointer null) { char *nick; PurpleBuddy * buddy; const char *from = xmlnode_get_attrib(*packet, "from"); if(from != NULL && strstr(g_strdup(from),"@guest") != NULL && strstr(g_strdup(from),".meebo.org") != NULL) { nick = xmlnode_get_data(xmlnode_get_child(*packet, "nick")); if(nick != NULL) { buddy = purple_find_buddy(gc->account, from); purple_blist_server_alias_buddy(buddy, nick); } } } static gboolean plugin_load(PurplePlugin *plugin) { void *gtk_blist_handle; PurpleAccountUiOps *ui_ops; PurplePlugin *jabber; jabber = purple_find_prpl("prpl-jabber"); if (!jabber) return FALSE; purple_signal_connect(jabber, "jabber-receiving-xmlnode", plugin, PURPLE_CALLBACK(xmlnode_received_cb), NULL); ui_ops = purple_accounts_get_ui_ops(); request_authorize = ui_ops->request_authorize; ui_ops->request_authorize = my_pidgin_accounts_request_authorization; gtk_blist_handle = pidgin_blist_get_handle(); purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", gtk_blist_handle, PURPLE_CALLBACK(buddy_signoff_cb), NULL); purple_signal_connect(purple_connections_get_handle(), "signed-on", gtk_blist_handle, PURPLE_CALLBACK(sign_on_cb), NULL); return TRUE; } static gboolean plugin_unload(PurplePlugin *plugin) { void *gtk_blist_handle; PurpleAccountUiOps *ui_ops; ui_ops = purple_accounts_get_ui_ops(); ui_ops->request_authorize = request_authorize; gtk_blist_handle = pidgin_blist_get_handle(); purple_signal_disconnect(purple_blist_get_handle(), "buddy-signed-off", gtk_blist_handle, PURPLE_CALLBACK(buddy_signoff_cb)); return TRUE; } static PurplePluginInfo info = { PURPLE_PLUGIN_MAGIC, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_PLUGIN_STANDARD, PIDGIN_PLUGIN_TYPE, 0, NULL, PURPLE_PRIORITY_DEFAULT, MEEBO_PLUGIN_ID, N_("Meebo Guest Auto Add/Remove"), "2.0.2", N_("Allows automatic adding and removal of meebo widget guests."), N_("This plugin was created for use with the meebo me widget. When " "people visit the web page on which your widget is placed, a buddy " "will automatically be added to your list in a group titled Meebo " "Guests. When they leave the site, the buddy will automatically be " "removed from your list."), "Justin Pomeroy ", "http://jrpomeroy.com/pidgin", plugin_load, plugin_unload, NULL, NULL, NULL, NULL, NULL, /* padding */ NULL, NULL, NULL, NULL }; static void init_plugin(PurplePlugin *plugin) { } PURPLE_INIT_PLUGIN(meebo, init_plugin, info)