libpurple/plugins/purple-toast/purple-toast.c

changeset 41663
301b7d002cf1
parent 41314
0dc72eacd8bf
child 41876
984f389775cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/plugins/purple-toast/purple-toast.c	Mon Sep 12 04:49:23 2022 -0500
@@ -0,0 +1,239 @@
+/* pidgin
+ *
+ * Pidgin 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.h>
+#include <gmodule.h>
+
+#include <gplugin.h>
+#include <gplugin-native.h>
+
+#include <purple.h>
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static GApplication *
+purple_toast_get_application(void) {
+	static GApplication *application = NULL;
+
+	if(G_UNLIKELY(application == NULL)) {
+		application = g_application_get_default();
+
+		if(application == NULL) {
+			application = g_application_new(NULL, G_APPLICATION_FLAGS_NONE);
+			g_application_register(application, NULL, NULL);
+		}
+	}
+
+	return application;
+}
+
+static void
+purple_toast_show_notification(const gchar *title,
+                               const gchar *body,
+                               GIcon *icon)
+{
+	GNotification *notification = g_notification_new(title);
+	gchar *stripped = purple_markup_strip_html(body);
+
+	g_notification_set_body(notification, stripped);
+	g_free(stripped);
+
+	if(G_IS_ICON(icon)) {
+		g_notification_set_icon(notification, icon);
+	}
+
+	g_application_send_notification(purple_toast_get_application(),
+	                                NULL,
+	                                notification);
+
+	g_object_unref(G_OBJECT(notification));
+}
+
+static GIcon *
+purple_toast_find_icon(PurpleAccount *account,
+                       PurpleBuddy *buddy,
+                       const gchar *sender)
+{
+	GIcon *icon = NULL;
+
+	if(PURPLE_IS_BUDDY(buddy)) {
+		PurpleBuddyIcon *buddy_icon = purple_buddy_get_icon(buddy);
+
+		if(buddy_icon) {
+			const gchar *filename = NULL;
+
+			filename = purple_buddy_icon_get_full_path(buddy_icon);
+			if(filename != NULL) {
+				GFile *file = g_file_new_for_path(filename);
+
+				icon = g_file_icon_new(file);
+
+				g_object_unref(file);
+			}
+		}
+	} else {
+		PurpleImage *image = NULL;
+		const gchar *path = NULL;
+
+		image = purple_buddy_icons_find_account_icon(account);
+		if(PURPLE_IS_IMAGE(image)) {
+			path = purple_image_get_path(image);
+
+			if(path) {
+				GFile *file = g_file_new_for_path(path);
+
+				icon = g_file_icon_new(file);
+
+				g_object_unref(G_OBJECT(file));
+			}
+			g_object_unref(G_OBJECT(image));
+		}
+	}
+
+	/* We should probably have a fallback, but we need a libpurple or
+	 * pidgin icon or something to make that happen.
+	 */
+
+	return icon;
+}
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+purple_toast_im_message_received(PurpleAccount *account,
+                                 const gchar *sender,
+                                 const gchar *message,
+                                 PurpleConversation *conv,
+                                 PurpleMessageFlags flags,
+                                 gpointer data)
+{
+	PurpleBuddy *buddy = NULL;
+	GIcon *icon = NULL;
+	const gchar *title = NULL;
+
+	buddy = purple_blist_find_buddy(account, sender);
+	title = PURPLE_IS_BUDDY(buddy) ? purple_buddy_get_alias(buddy) : sender;
+	icon = purple_toast_find_icon(account, buddy, sender);
+
+	purple_toast_show_notification(title, message, icon);
+
+	if(G_IS_ICON(icon)) {
+		g_object_unref(G_OBJECT(icon));
+	}
+}
+
+static void
+purple_toast_chat_message_received(PurpleAccount *account,
+                                   gchar *sender,
+                                   gchar *message,
+                                   PurpleConversation *conv,
+                                   PurpleMessageFlags flags,
+                                   gpointer data)
+{
+	PurpleBuddy *buddy = NULL;
+	GIcon *icon = NULL;
+	gchar *title = NULL;
+	const gchar *chat_name = NULL, *from = NULL;
+
+	/* figure out the title */
+	chat_name = purple_conversation_get_name(PURPLE_CONVERSATION(conv));
+	if(chat_name) {
+		PurpleChat *chat = purple_blist_find_chat(account, chat_name);
+
+		if(chat) {
+			chat_name = purple_chat_get_name(chat);
+		}
+	}
+
+	from = sender;
+	buddy = purple_blist_find_buddy(account, sender);
+	if(PURPLE_IS_BUDDY(buddy)) {
+		from = purple_buddy_get_alias(buddy);
+	}
+
+	title = g_strdup_printf("%s : %s", chat_name, from);
+
+	/* figure out the icon */
+	icon = purple_toast_find_icon(account, buddy, sender);
+
+	/* show the notification */
+	purple_toast_show_notification(title, message, icon);
+
+	/* clean up our memory */
+	g_free(title);
+
+	if(G_IS_ICON(icon)) {
+		g_object_unref(G_OBJECT(icon));
+	}
+}
+
+/******************************************************************************
+ * Plugin Exports
+ *****************************************************************************/
+static GPluginPluginInfo *
+purple_toast_query(G_GNUC_UNUSED GError **error) {
+	const gchar * const authors[] = {
+		"Gary Kramlich <grim@reaperworld.com>",
+		NULL
+	};
+
+	return purple_plugin_info_new(
+		"id", "purple/toast",
+		"abi-version", PURPLE_ABI_VERSION,
+		"name", "Purple Toast",
+		"version", "0.0.1",
+		"summary", "Toast notifications",
+		"authors", authors,
+		NULL
+	);
+}
+
+static gboolean
+purple_toast_load(GPluginPlugin *plugin, G_GNUC_UNUSED GError **error) {
+	gpointer conv_handle = purple_conversations_get_handle();
+
+	purple_signal_connect(conv_handle,
+	                      "received-im-msg",
+	                      plugin,
+	                      G_CALLBACK(purple_toast_im_message_received),
+	                      NULL
+	);
+
+	purple_signal_connect(conv_handle,
+	                      "received-chat-msg",
+	                      plugin,
+	                      G_CALLBACK(purple_toast_chat_message_received),
+	                      NULL
+	);
+
+	return TRUE;
+}
+
+static gboolean
+purple_toast_unload(G_GNUC_UNUSED GPluginPlugin *plugin,
+                    G_GNUC_UNUSED gboolean shutdown,
+                    G_GNUC_UNUSED GError **error)
+{
+	return TRUE;
+}
+
+GPLUGIN_NATIVE_PLUGIN_DECLARE(purple_toast)

mercurial