summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-10-14 14:35:26 (GMT)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-10-14 14:35:26 (GMT)
commita8f8a94c917a97c40e8e43997b12290bc9264c09 (patch)
tree1a67d2c3334284c157703553d538352af3c3e416
parent4b7a4f7b487064eca0754d9602505dae12d0033e (diff)
parent1108a8aa37c2fa4ef14ad9f5a198ac5f80f2d765 (diff)
downloadtelepathy-gabble-a8f8a94c917a97c40e8e43997b12290bc9264c09.tar.gz
telepathy-gabble-a8f8a94c917a97c40e8e43997b12290bc9264c09.tar.xz
Merge remote-tracking branch 'wjt/xmpp-console'
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=66085 Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Conflicts: plugins/console/channel.c
-rw-r--r--extensions/Gabble_Plugin_Console.xml2
-rw-r--r--plugins/Makefile.am11
-rw-r--r--plugins/console/channel-manager.c277
-rw-r--r--plugins/console/channel-manager.h52
-rw-r--r--plugins/console/channel.c (renamed from plugins/console.c)298
-rw-r--r--plugins/console/channel.h53
-rw-r--r--plugins/console/debug.c36
-rw-r--r--plugins/console/debug.h28
-rw-r--r--plugins/console/plugin.c91
-rw-r--r--plugins/console/plugin.h (renamed from plugins/console.h)37
-rwxr-xr-xplugins/telepathy-gabble-xmpp-console163
-rw-r--r--src/plugin-loader.c14
-rw-r--r--tests/twisted/console.py22
13 files changed, 753 insertions, 331 deletions
diff --git a/extensions/Gabble_Plugin_Console.xml b/extensions/Gabble_Plugin_Console.xml
index 1e3b523..a2d94ca 100644
--- a/extensions/Gabble_Plugin_Console.xml
+++ b/extensions/Gabble_Plugin_Console.xml
@@ -23,7 +23,7 @@
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="true"/>
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A sidecar interface providing an XMPP console.</p>
+ <p>A channel type providing an XMPP console.</p>
</tp:docstring>
<method name="SendIQ" tp:name-for-bindings="Send_IQ">
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index a511604..2b00079 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -62,8 +62,15 @@ libgateways_la_SOURCES = \
gateways.h
libconsole_la_SOURCES = \
- console.c \
- console.h
+ console/channel-manager.c \
+ console/channel-manager.h \
+ console/channel.c \
+ console/channel.h \
+ console/debug.c \
+ console/debug.h \
+ console/plugin.c \
+ console/plugin.h \
+ $(NULL)
AM_CFLAGS = $(ERROR_CFLAGS) \
-I $(top_srcdir) -I $(top_builddir) \
diff --git a/plugins/console/channel-manager.c b/plugins/console/channel-manager.c
new file mode 100644
index 0000000..3d826db
--- /dev/null
+++ b/plugins/console/channel-manager.c
@@ -0,0 +1,277 @@
+/* XML console plugin
+ *
+ * Copyright © 2011–2013 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "console/channel-manager.h"
+
+#include "extensions/extensions.h"
+#include "console/channel.h"
+
+static void channel_manager_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsoleChannelManager, gabble_console_channel_manager,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER, channel_manager_iface_init)
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER, NULL);
+ )
+
+enum {
+ PROP_CONNECTION = 1,
+};
+
+static void connection_status_changed_cb (
+ TpBaseConnection *conn,
+ guint status,
+ guint reason,
+ GabbleConsoleChannelManager *self);
+static void gabble_console_channel_manager_close_all (
+ GabbleConsoleChannelManager *self);
+
+static void
+gabble_console_channel_manager_init (GabbleConsoleChannelManager *self)
+{
+ g_weak_ref_init (&self->plugin_connection_ref, NULL);
+}
+
+
+static void
+gabble_console_channel_manager_constructed (GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+ GabblePluginConnection *plugin_connection;
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->constructed (object);
+
+ plugin_connection = g_weak_ref_get (&self->plugin_connection_ref);
+ if (plugin_connection != NULL)
+ {
+ g_signal_connect_object (plugin_connection, "status-changed",
+ G_CALLBACK (connection_status_changed_cb), self, 0);
+ g_object_unref (plugin_connection);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_set_property (
+ GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_weak_ref_set (&self->plugin_connection_ref, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gabble_console_channel_manager_get_property (
+ GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_value_take_object (value, g_weak_ref_get (&self->plugin_connection_ref));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_dispose (
+ GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ gabble_console_channel_manager_close_all (self);
+ g_weak_ref_clear (&self->plugin_connection_ref);
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->dispose (object);
+}
+
+
+static void
+connection_status_changed_cb (
+ TpBaseConnection *conn,
+ guint status,
+ guint reason,
+ GabbleConsoleChannelManager *self)
+{
+ switch (status)
+ {
+ case TP_CONNECTION_STATUS_DISCONNECTED:
+ gabble_console_channel_manager_close_all (self);
+ break;
+
+ default:
+ return;
+ }
+}
+
+static void
+gabble_console_channel_manager_close_all (
+ GabbleConsoleChannelManager *self)
+{
+ TpBaseChannel *channel;
+
+ while ((channel = g_queue_peek_head (&self->console_channels)) != NULL)
+ {
+ tp_base_channel_close (channel);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->constructed = gabble_console_channel_manager_constructed;
+ oclass->set_property = gabble_console_channel_manager_set_property;
+ oclass->get_property = gabble_console_channel_manager_get_property;
+ oclass->dispose = gabble_console_channel_manager_dispose;
+
+ g_object_class_install_property (oclass, PROP_CONNECTION,
+ g_param_spec_object ("plugin-connection", "Gabble Plugin Connection",
+ "Gabble Plugin Connection",
+ GABBLE_TYPE_PLUGIN_CONNECTION,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+
+static const gchar * const allowed[] = {
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ NULL
+};
+
+static void
+gabble_console_channel_manager_type_foreach_channel_class (GType type,
+ TpChannelManagerTypeChannelClassFunc func,
+ gpointer user_data)
+{
+ GHashTable *table = tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_NONE,
+ NULL);
+
+ func (type, table, NULL, user_data);
+
+ g_hash_table_unref (table);
+}
+
+
+static void
+console_channel_closed_cb (
+ GabbleConsoleChannel *channel,
+ gpointer user_data)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (user_data);
+
+ tp_channel_manager_emit_channel_closed_for_object (self,
+ TP_EXPORTABLE_CHANNEL (channel));
+
+ if (g_queue_remove (&self->console_channels, channel))
+ {
+ g_object_unref (channel);
+ }
+}
+
+
+static gboolean
+gabble_console_channel_manager_create_channel (
+ TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (manager);
+ GabblePluginConnection *connection;
+ TpBaseChannel *channel = NULL;
+ GError *error = NULL;
+ GSList *request_tokens;
+
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_IFACE_CHANNEL ".ChannelType"),
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
+ return FALSE;
+
+ if (tp_asv_get_uint32 (request_properties,
+ TP_IFACE_CHANNEL ".TargetHandleType", NULL) != 0)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Console channels can't have a target handle");
+ goto error;
+ }
+
+ if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+ allowed,
+ allowed,
+ &error))
+ goto error;
+
+ connection = g_weak_ref_get (&self->plugin_connection_ref);
+ g_return_val_if_fail (connection != NULL, FALSE);
+
+ channel = g_object_new (GABBLE_TYPE_CONSOLE_CHANNEL,
+ "connection", connection,
+ NULL);
+ tp_base_channel_register (channel);
+ g_signal_connect (channel, "closed", (GCallback) console_channel_closed_cb,
+ self);
+ g_queue_push_tail (&self->console_channels, channel);
+
+ request_tokens = g_slist_prepend (NULL, request_token);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (channel), request_tokens);
+ g_slist_free (request_tokens);
+
+ g_object_unref (connection);
+ return TRUE;
+
+error:
+ tp_channel_manager_emit_request_failed (self, request_token,
+ error->domain, error->code, error->message);
+ g_error_free (error);
+ return TRUE;
+}
+
+
+static void
+channel_manager_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ TpChannelManagerIface *iface = g_iface;
+
+ iface->type_foreach_channel_class = gabble_console_channel_manager_type_foreach_channel_class;
+ iface->create_channel = gabble_console_channel_manager_create_channel;
+}
diff --git a/plugins/console/channel-manager.h b/plugins/console/channel-manager.h
new file mode 100644
index 0000000..5e7a8b9
--- /dev/null
+++ b/plugins/console/channel-manager.h
@@ -0,0 +1,52 @@
+/* XML console plugin
+ *
+ * Copyright © 2011–2013 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib-object.h>
+#include <gabble/gabble.h>
+
+typedef struct _GabbleConsoleChannelManager GabbleConsoleChannelManager;
+typedef struct _GabbleConsoleChannelManagerClass GabbleConsoleChannelManagerClass;
+
+struct _GabbleConsoleChannelManagerClass {
+ GObjectClass parent_class;
+};
+
+struct _GabbleConsoleChannelManager {
+ GObject parent;
+
+ GWeakRef plugin_connection_ref;
+ GQueue console_channels;
+};
+
+GType gabble_console_channel_manager_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER \
+ (gabble_console_channel_manager_get_type ())
+#define GABBLE_CONSOLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER, GabbleConsoleChannelManager))
+#define GABBLE_CONSOLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,\
+ GabbleConsoleChannelManagerClass))
+#define GABBLE_IS_CONSOLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER))
+#define GABBLE_IS_CONSOLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER))
+#define GABBLE_CONSOLE_CHANNEL_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,\
+ GabbleConsoleChannelManagerClass))
diff --git a/plugins/console.c b/plugins/console/channel.c
index b0da5a6..3ddbef9 100644
--- a/plugins/console.c
+++ b/plugins/console/channel.c
@@ -18,8 +18,7 @@
*/
#include "config.h"
-
-#include "console.h"
+#include "console/channel.h"
#include <string.h>
@@ -27,148 +26,19 @@
#include <telepathy-glib/telepathy-glib-dbus.h>
#include <wocky/wocky.h>
-
-#include "extensions/extensions.h"
-
#include <gabble/gabble.h>
+#include "extensions/extensions.h"
-/*************************
- * Plugin implementation *
- *************************/
-
-static guint debug = 0;
-
-#define DEBUG(format, ...) \
-G_STMT_START { \
- if (debug != 0) \
- g_debug ("%s: " format, G_STRFUNC, ## __VA_ARGS__); \
-} G_STMT_END
-
-static const GDebugKey debug_keys[] = {
- { "console", 1 },
- { NULL, 0 }
-};
-
-static void plugin_iface_init (
- gpointer g_iface,
- gpointer data);
-
-static const gchar * const sidecar_interfaces[] = {
- GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
- NULL
-};
-
-G_DEFINE_TYPE_WITH_CODE (GabbleConsolePlugin, gabble_console_plugin,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN, plugin_iface_init);
- )
-
-static void
-gabble_console_plugin_init (GabbleConsolePlugin *self)
-{
-}
-
-static void
-gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
-{
-}
-
-static void
-gabble_console_plugin_create_sidecar_async (
- GabblePlugin *plugin,
- const gchar *sidecar_interface,
- GabblePluginConnection *connection,
- WockySession *session,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (plugin),
- callback, user_data,
- gabble_console_plugin_create_sidecar_async);
- GabbleSidecar *sidecar = NULL;
-
- if (!tp_strdiff (sidecar_interface, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
- {
- sidecar = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR,
- "connection", connection,
- "session", session,
- NULL);
- }
- else
- {
- g_simple_async_result_set_error (result, TP_ERROR,
- TP_ERROR_NOT_IMPLEMENTED, "'%s' not implemented", sidecar_interface);
- }
-
- if (sidecar != NULL)
- g_simple_async_result_set_op_res_gpointer (result, sidecar,
- g_object_unref);
-
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-}
-
-static GabbleSidecar *
-gabble_console_plugin_create_sidecar_finish (
- GabblePlugin *plugin,
- GAsyncResult *result,
- GError **error)
-{
- GabbleSidecar *sidecar;
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- error))
- return NULL;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (plugin), gabble_console_plugin_create_sidecar_async), NULL);
-
- sidecar = GABBLE_SIDECAR (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (result)));
-
- return g_object_ref (sidecar);
-}
-
-static void
-plugin_iface_init (
- gpointer g_iface,
- gpointer data G_GNUC_UNUSED)
-{
- GabblePluginInterface *iface = g_iface;
-
- iface->name = "XMPP console";
- iface->version = PACKAGE_VERSION;
- iface->sidecar_interfaces = sidecar_interfaces;
- iface->create_sidecar_async = gabble_console_plugin_create_sidecar_async;
- iface->create_sidecar_finish = gabble_console_plugin_create_sidecar_finish;
-}
-
-GabblePlugin *
-gabble_plugin_create (void)
-{
- debug = g_parse_debug_string (g_getenv ("GABBLE_DEBUG"), debug_keys,
- G_N_ELEMENTS (debug_keys) - 1);
- DEBUG ("loaded");
-
- return g_object_new (GABBLE_TYPE_CONSOLE_PLUGIN,
- NULL);
-}
-
-/**************************
- * Sidecar implementation *
- **************************/
+#include "console/debug.h"
enum {
PROP_0,
- PROP_CONNECTION,
- PROP_SESSION,
PROP_SPEW
};
-struct _GabbleConsoleSidecarPrivate
+struct _GabbleConsoleChannelPrivate
{
WockySession *session;
- TpBaseConnection *connection;
WockyXmppReader *reader;
WockyXmppWriter *writer;
@@ -183,43 +53,58 @@ struct _GabbleConsoleSidecarPrivate
gulong sending_id;
};
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data);
static void console_iface_init (
gpointer g_iface,
gpointer data);
-static void gabble_console_sidecar_set_spew (
- GabbleConsoleSidecar *self,
+static void gabble_console_channel_set_spew (
+ GabbleConsoleChannel *self,
gboolean spew);
+gchar *gabble_console_channel_get_path (TpBaseChannel *chan);
+static void gabble_console_channel_close (TpBaseChannel *chan);
-G_DEFINE_TYPE_WITH_CODE (GabbleConsoleSidecar, gabble_console_sidecar,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SIDECAR, sidecar_iface_init);
+G_DEFINE_TYPE_WITH_CODE (GabbleConsoleChannel, gabble_console_channel,
+ TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_GABBLE_PLUGIN_CONSOLE,
console_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
)
static void
-gabble_console_sidecar_init (GabbleConsoleSidecar *self)
+gabble_console_channel_init (GabbleConsoleChannel *self)
{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GABBLE_TYPE_CONSOLE_SIDECAR,
- GabbleConsoleSidecarPrivate);
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GABBLE_TYPE_CONSOLE_CHANNEL,
+ GabbleConsoleChannelPrivate);
self->priv->reader = wocky_xmpp_reader_new_no_stream_ns (
WOCKY_XMPP_NS_JABBER_CLIENT);
self->priv->writer = wocky_xmpp_writer_new_no_stream ();
}
+
+static void
+gabble_console_channel_constructed (GObject *object)
+{
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
+ void (*chain_up)(GObject *) =
+ G_OBJECT_CLASS (gabble_console_channel_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ chain_up (object);
+
+ self->priv->session = g_object_ref (
+ gabble_plugin_connection_get_session (
+ GABBLE_PLUGIN_CONNECTION (
+ tp_base_channel_get_connection (
+ TP_BASE_CHANNEL (self)))));
+ g_return_if_fail (self->priv->session != NULL);
+}
+
static void
-gabble_console_sidecar_get_property (
+gabble_console_channel_get_property (
GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
switch (property_id)
{
@@ -233,28 +118,18 @@ gabble_console_sidecar_get_property (
}
static void
-gabble_console_sidecar_set_property (
+gabble_console_channel_set_property (
GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
switch (property_id)
{
- case PROP_CONNECTION:
- g_assert (self->priv->connection == NULL); /* construct-only */
- self->priv->connection = g_value_dup_object (value);
- break;
-
- case PROP_SESSION:
- g_assert (self->priv->session == NULL); /* construct-only */
- self->priv->session = g_value_dup_object (value);
- break;
-
case PROP_SPEW:
- gabble_console_sidecar_set_spew (self, g_value_get_boolean (value));
+ gabble_console_channel_set_spew (self, g_value_get_boolean (value));
break;
default:
@@ -263,15 +138,14 @@ gabble_console_sidecar_set_property (
}
static void
-gabble_console_sidecar_dispose (GObject *object)
+gabble_console_channel_dispose (GObject *object)
{
void (*chain_up) (GObject *) =
- G_OBJECT_CLASS (gabble_console_sidecar_parent_class)->dispose;
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ G_OBJECT_CLASS (gabble_console_channel_parent_class)->dispose;
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
- gabble_console_sidecar_set_spew (self, FALSE);
+ gabble_console_channel_set_spew (self, FALSE);
- tp_clear_object (&self->priv->connection);
tp_clear_object (&self->priv->reader);
tp_clear_object (&self->priv->writer);
tp_clear_object (&self->priv->session);
@@ -281,46 +155,25 @@ gabble_console_sidecar_dispose (GObject *object)
}
static void
-gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
+gabble_console_channel_class_init (GabbleConsoleChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TpBaseChannelClass *channel_class = TP_BASE_CHANNEL_CLASS (klass);
static TpDBusPropertiesMixinPropImpl console_props[] = {
{ "SpewStanzas", "spew-stanzas", "spew-stanzas" },
{ NULL },
};
- static TpDBusPropertiesMixinIfaceImpl interfaces[] = {
- { GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
- tp_dbus_properties_mixin_getter_gobject_properties,
- /* FIXME: if we were feeling clever, we'd override the setter so that
- * we can monitor the bus name of any application which sets
- * SpewStanzas to TRUE and flip it back to false when that application
- * dies.
- *
- * Alternatively, we could just replace this sidecar with a channel.
- */
- tp_dbus_properties_mixin_setter_gobject_properties,
- console_props
- },
- { NULL },
- };
-
- object_class->get_property = gabble_console_sidecar_get_property;
- object_class->set_property = gabble_console_sidecar_set_property;
- object_class->dispose = gabble_console_sidecar_dispose;
- g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate));
+ object_class->constructed = gabble_console_channel_constructed;
+ object_class->get_property = gabble_console_channel_get_property;
+ object_class->set_property = gabble_console_channel_set_property;
+ object_class->dispose = gabble_console_channel_dispose;
- g_object_class_install_property (object_class, PROP_CONNECTION,
- g_param_spec_object ("connection", "Connection",
- "Gabble connection",
- GABBLE_TYPE_PLUGIN_CONNECTION,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ channel_class->channel_type = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
+ channel_class->get_object_path_suffix = gabble_console_channel_get_path;
+ channel_class->close = gabble_console_channel_close;
- g_object_class_install_property (object_class, PROP_SESSION,
- g_param_spec_object ("session", "Session",
- "Wocky session",
- WOCKY_TYPE_SESSION,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_type_class_add_private (klass, sizeof (GabbleConsoleChannelPrivate));
g_object_class_install_property (object_class, PROP_SPEW,
g_param_spec_boolean ("spew-stanzas", "SpewStanzas",
@@ -328,19 +181,26 @@ gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- klass->props_class.interfaces = interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleConsoleSidecarClass, props_class));
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ GABBLE_IFACE_QUARK_GABBLE_PLUGIN_CONSOLE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ tp_dbus_properties_mixin_setter_gobject_properties,
+ console_props);
}
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data)
+gchar *
+gabble_console_channel_get_path (TpBaseChannel *chan)
+{
+ return g_strdup_printf ("console%p", chan);
+}
+
+static void
+gabble_console_channel_close (TpBaseChannel *chan)
{
- GabbleSidecarInterface *iface = g_iface;
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (chan);
- iface->interface = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
- iface->get_immutable_properties = NULL;
+ gabble_console_channel_set_spew (self, FALSE);
+ tp_base_channel_destroyed (chan);
}
static gboolean
@@ -349,7 +209,7 @@ incoming_cb (
WockyStanza *stanza,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (user_data);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (user_data);
const guint8 *body;
gsize length;
@@ -365,7 +225,7 @@ sending_cb (
WockyStanza *stanza,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (user_data);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (user_data);
if (stanza != NULL)
{
@@ -380,11 +240,11 @@ sending_cb (
}
static void
-gabble_console_sidecar_set_spew (
- GabbleConsoleSidecar *self,
+gabble_console_channel_set_spew (
+ GabbleConsoleChannel *self,
gboolean spew)
{
- GabbleConsoleSidecarPrivate *priv = self->priv;
+ GabbleConsoleChannelPrivate *priv = self->priv;
if (!spew != !priv->spew)
{
@@ -425,7 +285,7 @@ return_from_send_iq (
GAsyncResult *result,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (source);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (source);
DBusGMethodInvocation *context = user_data;
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
GError *error = NULL;
@@ -524,12 +384,12 @@ validate_jid (const gchar **to,
*/
static gboolean
parse_me_a_stanza (
- GabbleConsoleSidecar *self,
+ GabbleConsoleChannel *self,
const gchar *xml,
WockyStanza **stanza_out,
GError **error)
{
- GabbleConsoleSidecarPrivate *priv = self->priv;
+ GabbleConsoleChannelPrivate *priv = self->priv;
WockyStanza *stanza;
wocky_xmpp_reader_reset (priv->reader);
@@ -555,13 +415,13 @@ parse_me_a_stanza (
static void
console_send_iq (
- GabbleSvcGabblePluginConsole *sidecar,
+ GabbleSvcGabblePluginConsole *channel,
const gchar *type_str,
const gchar *to,
const gchar *body,
DBusGMethodInvocation *context)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (sidecar);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (channel);
WockyPorter *porter = wocky_session_get_porter (self->priv->session);
WockyStanzaSubType sub_type;
WockyStanza *fragment;
@@ -641,11 +501,11 @@ stanza_looks_coherent (
static void
console_send_stanza (
- GabbleSvcGabblePluginConsole *sidecar,
+ GabbleSvcGabblePluginConsole *channel,
const gchar *xml,
DBusGMethodInvocation *context)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (sidecar);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (channel);
WockyPorter *porter = wocky_session_get_porter (self->priv->session);
WockyStanza *stanza = NULL;
GError *error = NULL;
diff --git a/plugins/console/channel.h b/plugins/console/channel.h
new file mode 100644
index 0000000..7e41c5a
--- /dev/null
+++ b/plugins/console/channel.h
@@ -0,0 +1,53 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+typedef struct _GabbleConsoleChannel GabbleConsoleChannel;
+typedef struct _GabbleConsoleChannelClass GabbleConsoleChannelClass;
+typedef struct _GabbleConsoleChannelPrivate GabbleConsoleChannelPrivate;
+
+struct _GabbleConsoleChannel {
+ TpBaseChannel parent;
+
+ GabbleConsoleChannelPrivate *priv;
+};
+
+struct _GabbleConsoleChannelClass {
+ TpBaseChannelClass parent;
+};
+
+GType gabble_console_channel_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_CHANNEL \
+ (gabble_console_channel_get_type ())
+#define GABBLE_CONSOLE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannel))
+#define GABBLE_CONSOLE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannelClass))
+#define GABBLE_IS_CONSOLE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_CHANNEL))
+#define GABBLE_IS_CONSOLE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_CHANNEL))
+#define GABBLE_CONSOLE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannelClass))
diff --git a/plugins/console/debug.c b/plugins/console/debug.c
new file mode 100644
index 0000000..29dcf16
--- /dev/null
+++ b/plugins/console/debug.c
@@ -0,0 +1,36 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib.h>
+
+#include "console/debug.h"
+
+int debug = 0;
+
+static const GDebugKey debug_keys[] = {
+ { "console", 1 },
+ { NULL, 0 }
+};
+
+void
+gabble_console_debug_init (void)
+{
+ debug = g_parse_debug_string (g_getenv ("GABBLE_DEBUG"), debug_keys,
+ G_N_ELEMENTS (debug_keys) - 1);
+}
diff --git a/plugins/console/debug.h b/plugins/console/debug.h
new file mode 100644
index 0000000..7803172
--- /dev/null
+++ b/plugins/console/debug.h
@@ -0,0 +1,28 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+extern int debug;
+
+#define DEBUG(format, ...) \
+G_STMT_START { \
+ if (debug != 0) \
+ g_debug ("%s: " format, G_STRFUNC, ## __VA_ARGS__); \
+} G_STMT_END
+
+void gabble_console_debug_init (void);
diff --git a/plugins/console/plugin.c b/plugins/console/plugin.c
new file mode 100644
index 0000000..c17cf71
--- /dev/null
+++ b/plugins/console/plugin.c
@@ -0,0 +1,91 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "console/plugin.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <wocky/wocky.h>
+#include <gabble/gabble.h>
+#include "extensions/extensions.h"
+
+#include "console/channel-manager.h"
+#include "console/channel.h"
+#include "console/debug.h"
+
+static void plugin_iface_init (
+ gpointer g_iface,
+ gpointer data);
+
+static const gchar * const sidecar_interfaces[] = {
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
+ NULL
+};
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsolePlugin, gabble_console_plugin,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN, plugin_iface_init);
+ )
+
+static void
+gabble_console_plugin_init (GabbleConsolePlugin *self)
+{
+}
+
+static void
+gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
+{
+}
+
+static GPtrArray *
+gabble_console_plugin_create_channel_managers (GabblePlugin *plugin,
+ GabblePluginConnection *plugin_connection)
+{
+ GPtrArray *ret = g_ptr_array_new ();
+
+ g_ptr_array_add (ret,
+ g_object_new (GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,
+ "plugin-connection", plugin_connection,
+ NULL));
+
+ return ret;
+}
+
+static void
+plugin_iface_init (
+ gpointer g_iface,
+ gpointer data G_GNUC_UNUSED)
+{
+ GabblePluginInterface *iface = g_iface;
+
+ iface->name = "XMPP console";
+ iface->version = PACKAGE_VERSION;
+ iface->create_channel_managers = gabble_console_plugin_create_channel_managers;
+}
+
+GabblePlugin *
+gabble_plugin_create (void)
+{
+ gabble_console_debug_init ();
+
+ DEBUG ("loaded");
+
+ return g_object_new (GABBLE_TYPE_CONSOLE_PLUGIN,
+ NULL);
+}
diff --git a/plugins/console.h b/plugins/console/plugin.h
index e646d06..153484f 100644
--- a/plugins/console.h
+++ b/plugins/console/plugin.h
@@ -19,10 +19,6 @@
#include <glib-object.h>
-#include <gio/gio.h>
-#include <wocky/wocky.h>
-#include <telepathy-glib/telepathy-glib.h>
-
typedef struct _GabbleConsolePlugin GabbleConsolePlugin;
typedef struct _GabbleConsolePluginClass GabbleConsolePluginClass;
typedef struct _GabbleConsolePluginPrivate GabbleConsolePluginPrivate;
@@ -53,36 +49,3 @@ GType gabble_console_plugin_get_type (void);
#define GABBLE_CONSOLE_PLUGIN_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_PLUGIN, \
GabbleConsolePluginClass))
-
-typedef struct _GabbleConsoleSidecar GabbleConsoleSidecar;
-typedef struct _GabbleConsoleSidecarClass GabbleConsoleSidecarClass;
-typedef struct _GabbleConsoleSidecarPrivate GabbleConsoleSidecarPrivate;
-
-struct _GabbleConsoleSidecar {
- GObject parent;
- GabbleConsoleSidecarPrivate *priv;
-};
-
-struct _GabbleConsoleSidecarClass {
- GObjectClass parent;
-
- TpDBusPropertiesMixinClass props_class;
-};
-
-GType gabble_console_sidecar_get_type (void);
-
-#define GABBLE_TYPE_CONSOLE_SIDECAR \
- (gabble_console_sidecar_get_type ())
-#define GABBLE_CONSOLE_SIDECAR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecar))
-#define GABBLE_CONSOLE_SIDECAR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecarClass))
-#define GABBLE_IS_CONSOLE_SIDECAR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_SIDECAR))
-#define GABBLE_IS_CONSOLE_SIDECAR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_SIDECAR))
-#define GABBLE_CONSOLE_SIDECAR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecarClass))
diff --git a/plugins/telepathy-gabble-xmpp-console b/plugins/telepathy-gabble-xmpp-console
index 8b96469..a72c92b 100755
--- a/plugins/telepathy-gabble-xmpp-console
+++ b/plugins/telepathy-gabble-xmpp-console
@@ -3,10 +3,10 @@
"""
The world's worst XMPP console user interface.
-Pass it the bus name of a Gabble connection; type some words; get minimalistic
+Pass it a Gabble account name; type some words; get minimalistic
error reporting.
-Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+Copyright © 2011–2013 Collabora Ltd. <http://www.collabora.co.uk/>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -24,23 +24,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import sys
-import re
from xml.dom import minidom
-from gi.repository import Gtk
-from gi.repository import GLib
-from gi.repository import Gio
-from gi.repository import GtkSource
+from gi.repository import Gtk, GLib, Gio, GtkSource
+from gi.repository import TelepathyGLib as Tp
PADDING = 6
-def pathify(name):
- return '/' + name.replace('.', '/')
-
-def nameify(path):
- return (path[1:]).replace('/', '.')
-
-CONN_FUTURE_IFACE = "org.freedesktop.Telepathy.Connection.FUTURE"
CONSOLE_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Console"
class StanzaViewer(Gtk.ScrolledWindow):
@@ -302,32 +292,27 @@ class Window(Gtk.Window):
STANZA_PAGE = 1
SNOOPY_PAGE = 2
- def __init__(self, bus, connection_bus_name):
+ def __init__(self, account):
Gtk.Window.__init__(self)
self.set_title('XMPP Console')
self.set_default_size(600, 371)
- conn_future_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- connection_bus_name, pathify(connection_bus_name),
- CONN_FUTURE_IFACE, None)
- try:
- sidecar_path, _ = conn_future_proxy.EnsureSidecar('(s)', CONSOLE_IFACE)
- except Exception, e:
- print """
-Couldn't connect to the XMPP console interface on '%(connection_bus_name)s':
- %(e)s
-Check that it's a running Jabber connection, and that you have the console
-plugin installed.""" % locals()
+ request = Tp.AccountChannelRequest.new(
+ account,
+ { Tp.PROP_CHANNEL_CHANNEL_TYPE: CONSOLE_IFACE },
+ 0)
+ request.create_and_handle_channel_async(None, self.__create_cb, None)
- raise SystemExit(2)
-
- self.console_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- connection_bus_name, sidecar_path, CONSOLE_IFACE, None)
+ self.connect('destroy', Window.__destroy_cb)
+ def __build_ui(self):
# Build up the UI
+ self.grid = Gtk.Grid()
+ self.add(self.grid)
+
self.nb = Gtk.Notebook()
- self.add(self.nb)
+ self.grid.attach(self.nb, 0, 0, 1, 1)
self.iq = IQPage(self.console_proxy)
self.nb.insert_page(self.iq,
@@ -344,57 +329,103 @@ plugin installed.""" % locals()
Gtk.Label.new_with_mnemonic("_Monitor network traffic"),
self.SNOOPY_PAGE)
- self.connect('destroy', Window.__destroy_cb)
+ self.infobar = Gtk.InfoBar()
+ self.infobar.set_message_type(Gtk.MessageType.WARNING)
+ self.infobar.set_no_show_all(True)
+ label = Gtk.Label("The connection went away! Time to leave.")
+ label.show()
+ self.infobar.get_content_area().add(label)
+ self.infobar_close_button = self.infobar.add_button("Close", Gtk.ResponseType.CLOSE)
+ self.infobar.connect('response', lambda infobar, response: Gtk.main_quit())
+ self.infobar.connect('close', lambda infobar: Gtk.main_quit())
+
+ self.grid.attach_next_to(self.infobar, self.nb,
+ Gtk.PositionType.BOTTOM, 1, 1)
+
+ def __create_cb(self, request, result, _):
+ try:
+ channel, context = request.create_and_handle_channel_finish(result)
+ channel.connect('invalidated', self.__channel_invalidated_cb)
+
+ bus_name = channel.get_bus_name()
+ sidecar_path = channel.get_object_path()
+
+ bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
+ self.console_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
+ bus_name, sidecar_path, CONSOLE_IFACE, None)
+
+ except GLib.GError as e:
+ print """
+Couldn't connect to the XMPP console interface on '%(name)s':
+%(e)s
+Check that you have the console plugin installed.""" % {
+ 'name': request.get_account().get_path_suffix(),
+ 'e': e,
+ }
+ raise SystemExit(2)
+
+ self.__build_ui()
+ self.show_all()
+
+ def __channel_invalidated_cb(self, channel, domain, code, message):
+ self.infobar.show()
+ self.infobar_close_button.grab_focus()
+ self.nb.set_sensitive(False)
+ # TODO: try to reconnect?
def __destroy_cb(self):
- self.snoopy.teardown()
+ try:
+ self.snoopy.teardown()
+ except GLib.GError, e:
+ print "Couldn't turn off the monitor (maybe the connection went away?)"
+ print e
Gtk.main_quit()
-GABBLE_PREFIX = 'org.freedesktop.Telepathy.Connection.gabble.jabber.'
-
-AM_BUS_NAME = 'org.freedesktop.Telepathy.AccountManager'
-ACCOUNT_PREFIX = '/org/freedesktop/Telepathy/Account'
-ACCOUNT_IFACE = 'org.freedesktop.Telepathy.Account'
+def usage(am):
+ xmpp_accounts = sorted(
+ account.get_path_suffix()
+ for account in am.dup_valid_accounts()
+ if account.get_cm_name() == 'gabble')
-def usage():
print """
Usage:
%(arg0)s gabble/jabber/blahblah
- %(arg0)s %(prefix)sblahblah
-List account identifiers using `mc-tool list | grep gabble`.
-List connection bus names using `qdbus | grep gabble`.
+Here are some account identifiers:
+
+ %(accounts)s
""" % { 'arg0': sys.argv[0],
- 'prefix': GABBLE_PREFIX,
+ 'accounts': '\n '.join(xmpp_accounts),
}
raise SystemExit(1)
-if __name__ == '__main__':
- bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
-
- if len(sys.argv) != 2:
- usage()
-
- thing = sys.argv[1]
-
- if re.match('^gabble/jabber/[a-zA-Z0-9_]+$', thing):
- # Looks like an account path to me.
- account_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- AM_BUS_NAME, '%s/%s' % (ACCOUNT_PREFIX, thing),
- ACCOUNT_IFACE, None)
- path = account_proxy.get_cached_property('Connection').get_string()
- if path == '/':
- print "%s is not online" % thing
- raise SystemExit(1)
- else:
- thing = nameify(path)
+def am_prepared_cb(am, result, account_suffix):
+ try:
+ am.prepare_finish(result)
+ except GLib.GError as e:
+ print e
+ raise SystemExit(2)
+
+ if account_suffix is None:
+ usage(am)
- if not re.match('^%s[a-zA-Z0-9_]+$' % GABBLE_PREFIX, thing):
- usage()
+ for account in am.dup_valid_accounts():
+ if account.get_path_suffix() == account_suffix:
+ if account.get_connection() is None:
+ print "%s is not online." % account_suffix
+ raise SystemExit(2)
+ else:
+ win = Window(account)
+ return
+
+ usage(am)
+
+if __name__ == '__main__':
+ account_suffix = sys.argv[1] if len(sys.argv) == 2 else None
- win = Window(bus, thing)
- win.show_all()
+ am = Tp.AccountManager.dup()
+ am.prepare_async([], am_prepared_cb, account_suffix)
Gtk.main()
diff --git a/src/plugin-loader.c b/src/plugin-loader.c
index d308437..3927159 100644
--- a/src/plugin-loader.c
+++ b/src/plugin-loader.c
@@ -89,13 +89,18 @@ plugin_loader_try_to_load (
}
else
{
- gchar *sidecars = g_strjoinv (", ",
- (gchar **) gabble_plugin_get_sidecar_interfaces (plugin));
+ const gchar * const *interfaces = gabble_plugin_get_sidecar_interfaces (plugin);
const gchar *version = gabble_plugin_get_version (plugin);
+ gchar *sidecars;
if (version == NULL)
version = "(unspecified)";
+ if (interfaces != NULL)
+ sidecars = g_strjoinv (", ", (gchar **) interfaces);
+ else
+ sidecars = g_strdup ("none (maybe it implements some channels instead?)");
+
DEBUG ("loaded '%s' version %s (%s), implementing these sidecars: %s",
gabble_plugin_get_name (plugin), version, path, sidecars);
@@ -108,7 +113,6 @@ plugin_loader_try_to_load (
static void
gabble_plugin_loader_probe (GabblePluginLoader *self)
{
- GError *error = NULL;
const gchar *directory_names = g_getenv ("GABBLE_PLUGIN_DIR");
gchar **dir_array;
gchar **ptr;
@@ -132,13 +136,15 @@ gabble_plugin_loader_probe (GabblePluginLoader *self)
for (ptr = dir_array ; *ptr != NULL ; ptr++)
{
+ GError *error = NULL;
+
DEBUG ("probing %s", *ptr);
d = g_dir_open (*ptr, 0, &error);
if (d == NULL)
{
DEBUG ("%s", error->message);
- g_error_free (error);
+ g_clear_error (&error);
continue;
}
diff --git a/tests/twisted/console.py b/tests/twisted/console.py
index dfb643c..3d99c26 100644
--- a/tests/twisted/console.py
+++ b/tests/twisted/console.py
@@ -27,9 +27,25 @@ def send_unrecognised_get(q, stream):
return q.expect('stream-iq', iq_type='error')
def test(q, bus, conn, stream):
- path, _ = conn.Future.EnsureSidecar(CONSOLE_PLUGIN_IFACE)
+ rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS,
+ 'RequestableChannelClasses')
+
+ fixed = {
+ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE,
+ cs.TARGET_HANDLE_TYPE: cs.HT_NONE,
+ }
+ allowed = []
+ assertContains((fixed, allowed), rccs)
+
+ path, _ = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE })
+ other_path, _ = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE })
+
+ assertNotEquals(path, other_path)
+ # leave the other one open, to test we don't crash on disconnect
+
console = ProxyWrapper(bus.get_object(conn.bus_name, path),
- CONSOLE_PLUGIN_IFACE)
+ CONSOLE_PLUGIN_IFACE,
+ {'Channel': cs.CHANNEL})
assert not console.Properties.Get(CONSOLE_PLUGIN_IFACE, 'SpewStanzas')
es = [
@@ -88,5 +104,7 @@ def test(q, bus, conn, stream):
assertEquals('body', body.name)
assertEquals(ns.CLIENT, body.uri)
+ console.Channel.Close()
+
if __name__ == '__main__':
exec_test(test)