2008-02-24 15:42:31 +00:00
|
|
|
/*
|
2011-01-19 13:48:47 +00:00
|
|
|
* This file Copyright (C) Mnemosyne LLC
|
2008-02-24 15:42:31 +00:00
|
|
|
*
|
2010-12-27 19:18:17 +00:00
|
|
|
* This file is licensed by the GPL version 2. Works owned by the
|
2012-12-05 17:29:46 +00:00
|
|
|
* Transmission project are granted a special exemption to clause 2 (b)
|
2008-09-23 19:11:04 +00:00
|
|
|
* so that the bulk of its code can remain under the MIT license.
|
2008-02-24 15:42:31 +00:00
|
|
|
* This exemption does not extend to derived works not owned by
|
|
|
|
* the Transmission project.
|
2008-09-23 19:11:04 +00:00
|
|
|
*
|
2008-03-02 16:14:46 +00:00
|
|
|
* $Id$
|
2008-02-24 15:42:31 +00:00
|
|
|
*/
|
|
|
|
|
2012-12-05 17:29:46 +00:00
|
|
|
#include <string.h> /* strcmp () */
|
2011-12-10 19:00:50 +00:00
|
|
|
|
|
|
|
#include <gio/gio.h>
|
|
|
|
|
2008-03-03 04:44:27 +00:00
|
|
|
#include <glib/gi18n.h>
|
2009-01-13 16:39:19 +00:00
|
|
|
#include "conf.h"
|
2008-02-24 15:42:31 +00:00
|
|
|
#include "notify.h"
|
2009-01-12 21:15:14 +00:00
|
|
|
#include "tr-prefs.h"
|
2011-12-10 19:00:50 +00:00
|
|
|
#include "util.h"
|
2008-02-24 15:42:31 +00:00
|
|
|
|
2011-12-10 19:00:50 +00:00
|
|
|
#define NOTIFICATIONS_DBUS_NAME "org.freedesktop.Notifications"
|
|
|
|
#define NOTIFICATIONS_DBUS_CORE_OBJECT "/org/freedesktop/Notifications"
|
|
|
|
#define NOTIFICATIONS_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
|
|
|
|
|
|
|
|
static GDBusProxy *proxy = NULL;
|
|
|
|
static GHashTable *active_notifications = NULL;
|
|
|
|
static gboolean server_supports_actions = FALSE;
|
|
|
|
|
|
|
|
typedef struct _TrNotification
|
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
guint id;
|
|
|
|
TrCore * core;
|
|
|
|
int torrent_id;
|
|
|
|
}
|
|
|
|
TrNotification;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
|
|
|
static void
|
2012-12-05 17:29:46 +00:00
|
|
|
tr_notification_free (gpointer data)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
TrNotification * n = data;
|
|
|
|
|
|
|
|
if (n->core)
|
|
|
|
g_object_unref (G_OBJECT (n->core));
|
|
|
|
|
|
|
|
g_free (n);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-05 17:29:46 +00:00
|
|
|
get_capabilities_callback (GObject * source,
|
2011-12-10 19:00:50 +00:00
|
|
|
GAsyncResult * res,
|
2012-12-05 17:29:46 +00:00
|
|
|
gpointer user_data UNUSED)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
int i;
|
|
|
|
char ** caps;
|
|
|
|
GVariant * result;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, NULL);
|
|
|
|
if (!result || !g_variant_is_of_type (result, G_VARIANT_TYPE ("(as)")))
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
if (result)
|
|
|
|
g_variant_unref (result);
|
|
|
|
return;
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_get (result, "(^a&s)", &caps);
|
|
|
|
for (i=0; caps[i]; i++)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
if (strcmp (caps[i], "actions") == 0)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
server_supports_actions = TRUE;
|
|
|
|
break;
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-05 21:26:40 +00:00
|
|
|
|
|
|
|
g_free (caps);
|
|
|
|
g_variant_unref (result);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-05 17:29:46 +00:00
|
|
|
g_signal_callback (GDBusProxy * proxy UNUSED,
|
2011-12-10 19:00:50 +00:00
|
|
|
char * sender_name UNUSED,
|
|
|
|
char * signal_name,
|
|
|
|
GVariant * params,
|
2012-12-05 17:29:46 +00:00
|
|
|
gpointer user_data UNUSED)
|
2008-09-23 19:11:04 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
guint id;
|
|
|
|
TrNotification * n;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_return_if_fail (g_variant_is_of_type (params, G_VARIANT_TYPE ("(u*)")));
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_get (params, "(u*)", &id, NULL);
|
|
|
|
n = g_hash_table_lookup (active_notifications,
|
|
|
|
GINT_TO_POINTER ((int *) &id));
|
|
|
|
if (n == NULL)
|
|
|
|
return;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
if (strcmp (signal_name, "NotificationClosed") == 0)
|
2009-11-22 18:55:24 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
g_hash_table_remove (active_notifications,
|
|
|
|
GINT_TO_POINTER ((int *) &n->id));
|
2009-11-22 18:55:24 +00:00
|
|
|
}
|
2012-12-05 21:26:40 +00:00
|
|
|
else if (strcmp (signal_name, "ActionInvoked") == 0 &&
|
|
|
|
g_variant_is_of_type (params, G_VARIANT_TYPE ("(us)")))
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
char * action;
|
|
|
|
tr_torrent * tor;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
tor = gtr_core_find_torrent (n->core, n->torrent_id);
|
|
|
|
if (tor == NULL)
|
|
|
|
return;
|
2009-11-22 18:55:24 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_get (params, "(u&s)", NULL, &action);
|
|
|
|
if (strcmp (action, "folder") == 0)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
gtr_core_open_folder (n->core, n->torrent_id);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
2012-12-05 21:26:40 +00:00
|
|
|
else if (strcmp (action, "file") == 0)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
const tr_info * inf = tr_torrentInfo (tor);
|
|
|
|
const char * dir = tr_torrentGetDownloadDir (tor);
|
|
|
|
char * path = g_build_filename (dir, inf->files[0].name, NULL);
|
|
|
|
gtr_open_file (path);
|
|
|
|
g_free (path);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-05 17:29:46 +00:00
|
|
|
dbus_proxy_ready_callback (GObject * source UNUSED,
|
2011-12-10 19:00:50 +00:00
|
|
|
GAsyncResult * res,
|
2012-12-05 17:29:46 +00:00
|
|
|
gpointer user_data UNUSED)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
proxy = g_dbus_proxy_new_for_bus_finish (res, NULL);
|
|
|
|
if (proxy == NULL)
|
2009-01-12 18:48:20 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
g_warning ("Failed to create proxy for %s", NOTIFICATIONS_DBUS_NAME);
|
|
|
|
return;
|
2009-01-12 18:48:20 +00:00
|
|
|
}
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_signal_connect (proxy, "g-signal",
|
|
|
|
G_CALLBACK (g_signal_callback), NULL);
|
|
|
|
g_dbus_proxy_call (proxy,
|
|
|
|
"GetCapabilities",
|
|
|
|
g_variant_new ("()"),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE, -1, NULL,
|
|
|
|
get_capabilities_callback, NULL);
|
2008-02-24 15:42:31 +00:00
|
|
|
}
|
|
|
|
|
2009-06-11 16:17:48 +00:00
|
|
|
void
|
2012-12-05 17:29:46 +00:00
|
|
|
gtr_notify_init (void)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
active_notifications = g_hash_table_new_full (g_int_hash, g_int_equal,
|
|
|
|
NULL, tr_notification_free);
|
|
|
|
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
|
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
|
|
|
NULL,
|
|
|
|
NOTIFICATIONS_DBUS_NAME,
|
|
|
|
NOTIFICATIONS_DBUS_CORE_OBJECT,
|
|
|
|
NOTIFICATIONS_DBUS_CORE_INTERFACE,
|
|
|
|
NULL, dbus_proxy_ready_callback, NULL);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-05 17:29:46 +00:00
|
|
|
notify_callback (GObject * source,
|
2011-12-10 19:00:50 +00:00
|
|
|
GAsyncResult * res,
|
2012-12-05 17:29:46 +00:00
|
|
|
gpointer user_data)
|
2009-06-11 16:17:48 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
GVariant * result;
|
|
|
|
TrNotification * n = user_data;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, NULL);
|
|
|
|
if (!result || !g_variant_is_of_type (result, G_VARIANT_TYPE ("(u)")))
|
2009-06-11 16:17:48 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
if (result)
|
|
|
|
g_variant_unref (result);
|
|
|
|
tr_notification_free (n);
|
|
|
|
return;
|
2009-06-11 16:17:48 +00:00
|
|
|
}
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_get (result, "(u)", &n->id);
|
|
|
|
g_hash_table_insert (active_notifications,
|
|
|
|
GINT_TO_POINTER ((int *)&n->id), n);
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_unref (result);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-12-05 17:29:46 +00:00
|
|
|
gtr_notify_torrent_completed (TrCore * core, int torrent_id)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
GVariantBuilder actions_builder;
|
|
|
|
TrNotification * n;
|
|
|
|
tr_torrent * tor;
|
|
|
|
const char * cmd = gtr_pref_string_get (PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND);
|
2012-04-07 00:30:37 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
if (gtr_pref_flag_get (PREF_KEY_TORRENT_COMPLETE_SOUND_ENABLED))
|
|
|
|
g_spawn_command_line_async (cmd, NULL);
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
if (!gtr_pref_flag_get (PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED))
|
|
|
|
return;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
tor = gtr_core_find_torrent (core, torrent_id);
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
n = g_new0 (TrNotification, 1);
|
|
|
|
n->core = g_object_ref (G_OBJECT (core));
|
|
|
|
n->torrent_id = torrent_id;
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_builder_init (&actions_builder, G_VARIANT_TYPE ("as"));
|
2011-12-10 19:00:50 +00:00
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
if (server_supports_actions)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
const tr_info * inf = tr_torrentInfo (tor);
|
|
|
|
if (inf->fileCount == 1)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_builder_add (&actions_builder, "s", "file");
|
|
|
|
g_variant_builder_add (&actions_builder, "s", _("Open File"));
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
2012-12-05 21:26:40 +00:00
|
|
|
else
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
g_variant_builder_add (&actions_builder, "s", "folder");
|
|
|
|
g_variant_builder_add (&actions_builder, "s", _("Open Folder"));
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-05 21:26:40 +00:00
|
|
|
g_dbus_proxy_call (proxy,
|
|
|
|
"Notify",
|
|
|
|
g_variant_new ("(susssasa{sv}i)",
|
|
|
|
"Transmission", n->id, "transmission",
|
|
|
|
_("Torrent Complete"),
|
|
|
|
tr_torrentName (tor),
|
|
|
|
&actions_builder, NULL, -1),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE, -1, NULL,
|
|
|
|
notify_callback, n);
|
2011-12-10 19:00:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-12-05 17:29:46 +00:00
|
|
|
gtr_notify_torrent_added (const char * name)
|
2011-12-10 19:00:50 +00:00
|
|
|
{
|
2012-12-05 21:26:40 +00:00
|
|
|
TrNotification * n;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
|
|
|
|
|
|
|
if (!gtr_pref_flag_get (PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED))
|
|
|
|
return;
|
|
|
|
|
|
|
|
n = g_new0 (TrNotification, 1);
|
|
|
|
g_dbus_proxy_call (proxy,
|
|
|
|
"Notify",
|
|
|
|
g_variant_new ("(susssasa{sv}i)",
|
|
|
|
"Transmission", 0, "transmission",
|
|
|
|
_("Torrent Added"), name,
|
|
|
|
NULL, NULL, -1),
|
|
|
|
G_DBUS_CALL_FLAGS_NONE, -1, NULL,
|
|
|
|
notify_callback, n);
|
2009-06-11 16:17:48 +00:00
|
|
|
}
|