grim/purple-plugin-pack
--leaks
org.guifications.plugins
2009-04-15, darkrain42
/*--------------------------------------------------------------------------* * A Purple away message and profile manager that supports dynamic text * * AutoProfile is the legal property of its developers. Please refer to * * the COPYRIGHT file distributed with this source distribution. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *--------------------------------------------------------------------------*/ #include "conversation.h" #define SECS_BEFORE_RESENDING_AUTORESPONSE 600 #define SEX_BEFORE_RESENDING_AUTORESPONSE "Only after you're married" #define MILLISECS_BEFORE_PROCESSING_MSG 100 static GSList *last_auto_responses = NULL; struct last_auto_response { static time_t response_timeout = 0; /*--------------------------------------------------------------------------* * Auto-response utility functions * *--------------------------------------------------------------------------*/ expire_last_auto_responses(gpointer data) struct last_auto_response *lar; tmp = last_auto_responses; lar = (struct last_auto_response *)cur->data; if ((time(NULL) - lar->sent) > SECS_BEFORE_RESENDING_AUTORESPONSE) { last_auto_responses = g_slist_remove(last_auto_responses, lar); return FALSE; /* do not run again */ static struct last_auto_response * get_last_auto_response(PurpleConnection *gc, const char *name) struct last_auto_response *lar; /* because we're modifying or creating a lar, schedule the * function to expire them as the pref dictates */ purple_timeout_add((SECS_BEFORE_RESENDING_AUTORESPONSE + 5) * 1000, expire_last_auto_responses, NULL); tmp = last_auto_responses; lar = (struct last_auto_response *)tmp->data; if (gc == lar->gc && !strncmp(name, lar->name, sizeof(lar->name))) lar = (struct last_auto_response *)g_new0(struct last_auto_response, 1); g_snprintf(lar->name, sizeof(lar->name), "%s", name); last_auto_responses = g_slist_append(last_auto_responses, lar); /*--------------------------------------------------------------------------* * Message send/receive general functionality * *--------------------------------------------------------------------------*/ /* Detecting sent message stuff */ static void sent_im_msg_cb (PurpleAccount *account, const char *receiver, PurplePresence *presence; const gchar *auto_reply_pref; gc = purple_account_get_connection (account); presence = purple_account_get_presence (account); * FIXME - If "only auto-reply when away & idle" is set, then shouldn't * this only reset lar->sent if we're away AND idle? purple_prefs_get_string ("/plugins/gtk/autoprofile/autorespond/auto_reply"); if ((gc->flags & PURPLE_CONNECTION_AUTO_RESP) && !purple_presence_is_available(presence) && strcmp(auto_reply_pref, "never")) struct last_auto_response *lar; lar = get_last_auto_response(gc, receiver); /* Detecting received message stuff */ static gint process_received_im_msg (gpointer data) struct received_im_msg *received_im; PurpleConversation *conv; received_im = (struct received_im_msg *) data; account = received_im->account; sender = received_im->sender; message = received_im->message; gc = purple_account_get_connection (account); /* search for conversation again in case it was created by other handlers */ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); * - it's not supported on this connection * - or we're not idle and the 'only auto respond if idle' pref if (gc->flags & PURPLE_CONNECTION_AUTO_RESP) PurplePresence *presence; PurpleStatusType *status_type; PurpleStatusPrimitive primitive; const gchar *auto_reply_pref; auto_reply_pref = purple_prefs_get_string( "/plugins/gtk/autoprofile/autorespond/auto_reply"); presence = purple_account_get_presence(account); status = purple_presence_get_active_status(presence); status_type = purple_status_get_type(status); primitive = purple_status_type_get_primitive(status_type); if ((primitive == PURPLE_STATUS_AVAILABLE) || (primitive == PURPLE_STATUS_INVISIBLE) || (primitive == PURPLE_STATUS_MOBILE) || !strcmp(auto_reply_pref, "never") || (!purple_presence_is_idle(presence) && !strcmp(auto_reply_pref, "awayidle"))) away_msg = ap_get_sample_status_message (account); if ((away_msg != NULL) && (*away_msg != '\0')) { struct last_auto_response *lar; gboolean autorespond_enable; autorespond_enable = purple_prefs_get_bool ( "/plugins/gtk/autoprofile/autorespond/enable"); * This used to be based on the conversation window. But um, if * you went away, and someone sent you a message and got your * auto-response, and then you closed the window, and then they * sent you another one, they'd get the auto-response back too * soon. Besides that, we need to keep track of this even if we've * got a queue. So the rest of this block is just the auto-response, lar = get_last_auto_response(gc, sender); if ((now - lar->sent) >= SECS_BEFORE_RESENDING_AUTORESPONSE) { // Send basic autoresponse serv_send_im (gc, sender, away_msg, PURPLE_MESSAGE_AUTO_RESP); purple_conv_im_write (PURPLE_CONV_IM(conv), NULL, away_msg, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_AUTO_RESP, // Send additional hint if enabled if (autorespond_enable) { const gchar *query = purple_prefs_get_string ( "/plugins/gtk/autoprofile/autorespond/text"); serv_send_im (gc, sender, query, PURPLE_MESSAGE_AUTO_RESP); purple_conv_im_write (PURPLE_CONV_IM (conv), NULL, query, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_AUTO_RESP, } else if (autorespond_enable && difftime (time(NULL), response_timeout) > purple_prefs_get_int ("/plugins/gtk/autoprofile/autorespond/delay")) { gchar *text = purple_markup_strip_html (message); if (match_start (text, purple_prefs_get_string ( "/plugins/gtk/autoprofile/autorespond/trigger")) == 1) { serv_send_im (gc, sender, away_msg, PURPLE_MESSAGE_AUTO_RESP); purple_conv_im_write (PURPLE_CONV_IM (conv), NULL, away_msg, PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_AUTO_RESP, response_timeout = time (NULL); ap_debug ("autorespond", "string matched, responding"); static void received_im_msg_cb (PurpleAccount *account, char *sender, char *message, PurpleConversation *conv, PurpleMessageFlags flags) struct received_im_msg *received_im; (struct received_im_msg *) malloc (sizeof (struct received_im_msg)); received_im->account = account; received_im->sender = strdup (sender); received_im->message = strdup (message); purple_timeout_add (MILLISECS_BEFORE_PROCESSING_MSG, process_received_im_msg, static void auto_pref_cb ( const char *name, PurplePrefType type, gconstpointer val, gpointer data) if (!strcmp (purple_prefs_get_string ("/purple/away/auto_reply"), "never")) purple_notify_error (NULL, NULL, N_("This preference is disabled"), N_("This preference currently has no effect because AutoProfile is in " "use. To modify this behavior, use the AutoProfile configuration " purple_prefs_set_string ("/purple/away/auto_reply", "never"); /*--------------------------------------------------------------------------* *--------------------------------------------------------------------------*/ void ap_autoreply_start () purple_prefs_set_string ("/purple/away/auto_reply", "never"); purple_signal_connect (purple_conversations_get_handle (), "sent-im-msg", ap_get_plugin_handle (), PURPLE_CALLBACK(sent_im_msg_cb), NULL); purple_signal_connect (purple_conversations_get_handle (), "received-im-msg", ap_get_plugin_handle (), PURPLE_CALLBACK(received_im_msg_cb), NULL); pref_cb = purple_prefs_connect_callback (ap_get_plugin_handle (), "/purple/away/auto_reply", auto_pref_cb, NULL); void ap_autoreply_finish () // Assumes signals are disconnected globally purple_prefs_disconnect_callback (pref_cb); purple_prefs_set_string ("/purple/away/auto_reply", purple_prefs_get_string ( "/plugins/gtk/autoprofile/autorespond/auto_reply")); while (last_auto_responses) { tmp = last_auto_responses->next; g_free (last_auto_responses->data); g_slist_free_1 (last_auto_responses); last_auto_responses = tmp;