libpurple/plugins/idle/idle.c

changeset 41663
301b7d002cf1
parent 41453
380febc4aae7
child 41974
9ad66abc9356
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/plugins/idle/idle.c	Mon Sep 12 04:49:23 2022 -0500
@@ -0,0 +1,332 @@
+/*
+ * idle.c - I'dle Mak'er plugin for Purple
+ *
+ * This file is part of Purple.
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include <glib/gi18n-lib.h>
+
+#include <gplugin.h>
+#include <gplugin-native.h>
+
+#include <purple.h>
+
+/* This plugin no longer depends on gtk */
+#define IDLE_PLUGIN_ID "core-idle"
+
+static GList *idled_accts = NULL;
+
+static gboolean
+unidle_filter(PurpleAccount *acct)
+{
+	if (g_list_find(idled_accts, acct))
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+idleable_filter(PurpleAccount *account)
+{
+	PurpleProtocol *protocol;
+
+	protocol = purple_account_get_protocol(account);
+	g_return_val_if_fail(protocol != NULL, FALSE);
+
+	return PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, set_idle);
+}
+
+static void
+set_idle_time(PurpleAccount *acct, int mins_idle)
+{
+	time_t t;
+	PurpleConnection *gc = purple_account_get_connection(acct);
+	PurplePresence *presence = purple_account_get_presence(acct);
+
+	if (!gc)
+		return;
+
+	purple_debug_info("idle",
+			"setting idle time for %s to %d\n",
+			purple_account_get_username(acct), mins_idle);
+
+	if (mins_idle)
+		t = time(NULL) - (60 * mins_idle); /* subtract seconds idle from current time */
+	else
+		t = 0; /* time idle is irrelevant */
+
+	purple_presence_set_idle(presence, mins_idle ? TRUE : FALSE, t);
+}
+
+static void
+idle_action_ok(void *ignored, PurpleRequestFields *fields)
+{
+	int tm = purple_request_fields_get_integer(fields, "mins");
+	PurpleAccount *acct = purple_request_fields_get_account(fields, "acct");
+
+	/* only add the account to the GList if it's not already been idled */
+	if (!unidle_filter(acct))
+	{
+		purple_debug_misc("idle",
+				"%s hasn't been idled yet; adding to list.\n",
+				purple_account_get_username(acct));
+		idled_accts = g_list_append(idled_accts, acct);
+	}
+
+	set_idle_time(acct, tm);
+}
+
+static void
+idle_all_action_ok(void *ignored, PurpleRequestFields *fields)
+{
+	PurpleAccountManager *manager = NULL;
+	PurpleAccount *acct = NULL;
+	GList *list, *iter;
+	int tm = purple_request_fields_get_integer(fields, "mins");
+
+	manager = purple_account_manager_get_default();
+	list = purple_account_manager_get_enabled(manager);
+	for(iter = list; iter; iter = iter->next) {
+		acct = (PurpleAccount *)(iter->data);
+
+		if(acct && idleable_filter(acct)) {
+			purple_debug_misc("idle", "Idling %s.\n",
+					purple_account_get_username(acct));
+
+			set_idle_time(acct, tm);
+
+			if(!g_list_find(idled_accts, acct))
+				idled_accts = g_list_append(idled_accts, acct);
+		}
+	}
+
+	g_list_free(list);
+}
+
+static void
+unidle_action_ok(void *ignored, PurpleRequestFields *fields)
+{
+	PurpleAccount *acct = purple_request_fields_get_account(fields, "acct");
+
+	set_idle_time(acct, 0); /* unidle the account */
+
+	/* once the account has been unidled it shouldn't be in the list */
+	idled_accts = g_list_remove(idled_accts, acct);
+}
+
+static void
+signing_off_cb(PurpleConnection *gc, void *data)
+{
+	PurpleAccount *account;
+
+	account = purple_connection_get_account(gc);
+	idled_accts = g_list_remove(idled_accts, account);
+}
+
+/******************************************************************************
+ * Actions
+ *****************************************************************************/
+static void
+purple_idle_set_account_idle_time(G_GNUC_UNUSED GSimpleAction *action,
+                                  G_GNUC_UNUSED GVariant *parameter,
+                                  gpointer data)
+{
+	/* Use the super fancy request API */
+
+	PurpleRequestFields *request;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+
+	group = purple_request_field_group_new(NULL);
+
+	field = purple_request_field_account_new("acct", _("Account"), NULL);
+	purple_request_field_account_set_filter(field, idleable_filter);
+	purple_request_field_account_set_show_all(field, FALSE);
+	purple_request_field_group_add_field(group, field);
+
+	field = purple_request_field_int_new("mins", _("Minutes"), 10, 0, 9999);
+	purple_request_field_group_add_field(group, field);
+
+	request = purple_request_fields_new();
+	purple_request_fields_add_group(request, group);
+
+	purple_request_fields(data,
+			N_("I'dle Mak'er"),
+			_("Set Account Idle Time"),
+			NULL,
+			request,
+			_("_Set"), G_CALLBACK(idle_action_ok),
+			_("_Cancel"), NULL,
+			NULL, NULL);
+}
+
+static void
+purple_idle_unset_account_idle_time(G_GNUC_UNUSED GSimpleAction *action,
+                                    G_GNUC_UNUSED GVariant *parameter,
+                                    gpointer data)
+{
+	PurpleRequestFields *request;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+
+	if (idled_accts == NULL)
+	{
+		purple_notify_info(NULL, NULL, _("None of your accounts are idle."), NULL, NULL);
+		return;
+	}
+
+	group = purple_request_field_group_new(NULL);
+
+	field = purple_request_field_account_new("acct", _("Account"), NULL);
+	purple_request_field_account_set_filter(field, unidle_filter);
+	purple_request_field_account_set_show_all(field, FALSE);
+	purple_request_field_group_add_field(group, field);
+
+	request = purple_request_fields_new();
+	purple_request_fields_add_group(request, group);
+
+	purple_request_fields(data,
+			N_("I'dle Mak'er"),
+			_("Unset Account Idle Time"),
+			NULL,
+			request,
+			_("_Unset"), G_CALLBACK(unidle_action_ok),
+			_("_Cancel"), NULL,
+			NULL, NULL);
+}
+
+static void
+purple_idle_set_all_accounts_idle_time(G_GNUC_UNUSED GSimpleAction *action,
+                                       G_GNUC_UNUSED GVariant *parameter,
+                                       gpointer data)
+{
+	PurpleRequestFields *request;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+
+	group = purple_request_field_group_new(NULL);
+
+	field = purple_request_field_int_new("mins", _("Minutes"), 10, 0, 9999);
+	purple_request_field_group_add_field(group, field);
+
+	request = purple_request_fields_new();
+	purple_request_fields_add_group(request, group);
+
+	purple_request_fields(data,
+			N_("I'dle Mak'er"),
+			_("Set Idle Time for All Accounts"),
+			NULL,
+			request,
+			_("_Set"), G_CALLBACK(idle_all_action_ok),
+			_("_Cancel"), NULL,
+			NULL, NULL);
+}
+
+static void
+purple_idle_unset_all_accounts_idle_time(G_GNUC_UNUSED GSimpleAction *action,
+                                         G_GNUC_UNUSED GVariant *parameter,
+                                         G_GNUC_UNUSED gpointer data)
+{
+	/* freeing the list here will cause segfaults if the user idles an account
+	 * after the list is freed */
+	g_list_foreach(idled_accts, (GFunc)set_idle_time, GINT_TO_POINTER(0));
+	g_list_free(idled_accts);
+	idled_accts = NULL;
+}
+
+/******************************************************************************
+ * GPlugin Exports
+ *****************************************************************************/
+static GPluginPluginInfo *
+idle_query(GError **error)
+{
+	GSimpleActionGroup *group = NULL;
+	GActionEntry entries[] = {
+		{
+			.name = "set-account-idle-time",
+			.activate = purple_idle_set_account_idle_time,
+		}, {
+			.name = "unset-account-idle-time",
+			.activate = purple_idle_unset_account_idle_time,
+		}, {
+			.name = "set-all-accounts-idle-time",
+			.activate = purple_idle_set_all_accounts_idle_time,
+		}, {
+			.name = "unset-all-accounts-idle-time",
+			.activate = purple_idle_unset_all_accounts_idle_time,
+		}
+	};
+	GMenu *menu = NULL;
+	const gchar * const authors[] = {
+		"Eric Warmenhoven <eric@warmenhoven.org>",
+		NULL
+	};
+
+	group = g_simple_action_group_new();
+	g_action_map_add_action_entries(G_ACTION_MAP(group), entries,
+	                                G_N_ELEMENTS(entries), NULL);
+
+	menu = g_menu_new();
+	g_menu_append(menu, _("Set Account Idle Time"), "set-account-idle-time");
+	g_menu_append(menu, _("Unset Account Idle Time"),
+	              "unset-account-idle-time");
+	g_menu_append(menu, _("Set Idle Time for All Accounts"),
+	              "set-all-accounts-idle-time");
+	g_menu_append(menu, _("Unset Idle Time for All Idled Accounts"),
+	              "unset-all-accounts-idle-time");
+
+	return purple_plugin_info_new(
+		"id",           IDLE_PLUGIN_ID,
+		/* This is a cultural reference.  Dy'er Mak'er is a song by Led Zeppelin.
+		   If that doesn't translate well into your language, drop the 's before translating. */
+		"name",         N_("I'dle Mak'er"),
+		"version",      DISPLAY_VERSION,
+		"category",     N_("Utility"),
+		"summary",      N_("Allows you to hand-configure how long you've been idle"),
+		"description",  N_("Allows you to hand-configure how long you've been idle"),
+		"authors",      authors,
+		"website",      PURPLE_WEBSITE,
+		"abi-version",  PURPLE_ABI_VERSION,
+		"action-group", group,
+		"action-menu",  menu,
+		NULL
+	);
+}
+
+static gboolean
+idle_load(GPluginPlugin *plugin, GError **error)
+{
+	purple_signal_connect(purple_connections_get_handle(), "signing-off",
+						plugin,
+						G_CALLBACK(signing_off_cb), NULL);
+
+	return TRUE;
+}
+
+static gboolean
+idle_unload(GPluginPlugin *plugin, gboolean shutdown, GError **error)
+{
+	purple_idle_unset_all_accounts_idle_time(NULL, NULL, NULL);
+
+	return TRUE;
+}
+
+GPLUGIN_NATIVE_PLUGIN_DECLARE(idle);

mercurial