From 2619aa93104c476bb08ac8734b6405943d6f3fdf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 13:41:19 +0000 Subject: [PATCH] Be parallel-installable with Gabble 0.x ... apart from /usr/share/doc, which packagers will probably shuffle around according to distro policy anyway. Also use telepathy-glib-1 and telepathy-glib-1-dbus in the .pc files. --- .gitignore | 4 +- configure.ac | 12 +- data/gabble.service.in | 2 +- docs/Makefile.am | 2 +- docs/telepathy-gabble-1.8.in | 49 +++ docs/telepathy-gabble.8.in | 49 --- gabble/Makefile.am | 2 +- gabble/telepathy-gabble-1-uninstalled.pc.in | 17 ++ gabble/telepathy-gabble-1.pc.in | 16 + gabble/telepathy-gabble-uninstalled.pc.in | 17 -- gabble/telepathy-gabble.pc.in | 16 - plugins/Makefile.am | 4 +- plugins/telepathy-gabble-1-xmpp-console | 451 ++++++++++++++++++++++++++++ plugins/telepathy-gabble-xmpp-console | 451 ---------------------------- src/Makefile.am | 16 +- 15 files changed, 554 insertions(+), 554 deletions(-) create mode 100644 docs/telepathy-gabble-1.8.in delete mode 100644 docs/telepathy-gabble.8.in create mode 100644 gabble/telepathy-gabble-1-uninstalled.pc.in create mode 100644 gabble/telepathy-gabble-1.pc.in delete mode 100644 gabble/telepathy-gabble-uninstalled.pc.in delete mode 100644 gabble/telepathy-gabble.pc.in create mode 100755 plugins/telepathy-gabble-1-xmpp-console delete mode 100755 plugins/telepathy-gabble-xmpp-console diff --git a/.gitignore b/.gitignore index 6d23041..a6bc6e4 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,7 @@ core /debian /depcomp /docs/*.html -/docs/telepathy-gabble.8 +/docs/telepathy-gabble-1.8 /extensions/extensions.html /gtk-doc.make /install-sh @@ -68,7 +68,7 @@ core /src/gabble-enumtypes.c /src/media-session-enumtypes.c /src/media-session-enumtypes.h -/src/telepathy-gabble +/src/telepathy-gabble-1 /src/write-mgr-file /stamp-h1 tags diff --git a/configure.ac b/configure.ac index ff476b1..74f9f2c 100644 --- a/configure.ac +++ b/configure.ac @@ -176,7 +176,7 @@ if test x$installed_tests = xyes; then fi AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], [test "x$installed_tests" = xyes]) -gabbletestsdir=${libdir}/telepathy-gabble-tests +gabbletestsdir=${libdir}/telepathy-gabble-1-tests AC_SUBST(gabbletestsdir) AC_ARG_ENABLE([is-a-phone], @@ -234,12 +234,12 @@ AC_SUBST(GLIB_GENMARSHAL) # # Private directory for Wocky and the gabble-plugins library if test "x$pluginexeclibdir" = x; then - pluginexeclibdir='${libdir}/telepathy/gabble-0/lib' + pluginexeclibdir='${libdir}/telepathy/gabble-1' fi AC_ARG_VAR([pluginexeclibdir]) # The actual plugins if test "x$pluginexecdir" = x; then - pluginexecdir='${libdir}/telepathy/gabble-0/plugins' + pluginexecdir='${libdir}/telepathy/gabble-1/plugins' fi AC_ARG_VAR([pluginexecdir]) @@ -257,7 +257,7 @@ if test x$enable_plugins = xyes; then [install headers for third-party plugins (experimental)]), [ enable_plugin_api=$enableval - wocky_install_headers_dir="${includedir}/telepathy-gabble-0" + wocky_install_headers_dir="${includedir}/telepathy-gabble-1" ], [enable_plugin_api=no]) fi @@ -425,8 +425,8 @@ AC_OUTPUT( Makefile \ lib/gibber/Makefile \ plugins/Makefile \ gabble/Makefile \ - gabble/telepathy-gabble-uninstalled.pc \ - gabble/telepathy-gabble.pc + gabble/telepathy-gabble-1-uninstalled.pc \ + gabble/telepathy-gabble-1.pc ) if test false != "$TEST_PYTHON"; then diff --git a/data/gabble.service.in b/data/gabble.service.in index e3c0bf8..4063509 100644 --- a/data/gabble.service.in +++ b/data/gabble.service.in @@ -1,3 +1,3 @@ [D-BUS Service] Name=im.telepathy.v1.ConnectionManager.gabble -Exec=@libexecdir@/telepathy-gabble +Exec=@libexecdir@/telepathy-gabble-1 diff --git a/docs/Makefile.am b/docs/Makefile.am index 027e56e..e2df34c 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -3,7 +3,7 @@ tools_dir = $(top_srcdir)/tools # htmldir is not defined by autoconf < 2.59c htmldir = $(if $(filter-out @%@,@htmldir@),@htmldir@,$(datadir)/doc/$(PACKAGE)) -man_MANS = telepathy-gabble.8 +man_MANS = telepathy-gabble-1.8 html_DATA = \ muc-bytestream.html \ si-multiple.html \ diff --git a/docs/telepathy-gabble-1.8.in b/docs/telepathy-gabble-1.8.in new file mode 100644 index 0000000..46e69f4 --- /dev/null +++ b/docs/telepathy-gabble-1.8.in @@ -0,0 +1,49 @@ +.TH TELEPATHY-GABBLE-1 "8" "October 2007" "Telepathy" "D-Bus services" +\" This man page was written by Simon McVittie for the Debian project, +\" but may be used by others. +\" Copyright © 2007 Collabora Ltd. +\" It may be distributed under the same terms as telepathy-gabble itself. +.SH NAME +telepathy-gabble-1 \- Telepathy connection manager for XMPP (Jabber) +.SH SYNOPSIS +\fB@libexecdir@/telepathy\-gabble\-1\fR +.SH DESCRIPTION +Gabble implements the Telepathy D-Bus specification for XMPP (Jabber), +allowing Telepathy clients like +.BR empathy (1) +to connect to XMPP accounts, including Google Talk. +.PP +It is a D-Bus service which runs on the session bus, and should usually be +started automatically by D-Bus activation. However, it might be useful to +start it manually for debugging. +.SH OPTIONS +There are no command-line options. +.SH ENVIRONMENT +.TP +\fBGABBLE_LOGFILE\fR=\fIfilename\fR +If set, debug output will go to the given file rather than to stderr. +If \fB+\fR is prepended to the \fIfilename\fR (e.g. +\fBGABBLE_LOGFILE=+gabble.log\fR), debug output will be appended +to the file; otherwise, any existing file will be replaced. +.TP +\fBGABBLE_DEBUG\fR=\fItype\fR +May be set to "all" for full debug output, or various undocumented options +(which may change from release to release) to filter the output. +.TP +\fBWOCKY_DEBUG\fR=\fItype\fR +May be set to "all" for full debug output from the Wocky XMPP library used +by Gabble, or various undocumented options (which may change from release to +release) to filter the output. For general Gabble debugging, "net" is +recommended. +.TP +\fBGABBLE_PERSIST\fR=\fI1\fR +If set (to any value), Gabble will continue running until killed, rather than +timing out if it has no open connections for a few seconds. +.TP +\fBGABBLE_PLUGIN_DIR\fR=\fIdirectory\fR +If set, and Gabble was compiled with plugin support, plugins will be loaded +from \fIdirectory\fR rather than from the default directory. +.SH SEE ALSO +.IR http://telepathy.freedesktop.org/ , +.IR http://telepathy.freedesktop.org/wiki/CategoryGabble , +.BR empathy (1) diff --git a/docs/telepathy-gabble.8.in b/docs/telepathy-gabble.8.in deleted file mode 100644 index 2dc96a0..0000000 --- a/docs/telepathy-gabble.8.in +++ /dev/null @@ -1,49 +0,0 @@ -.TH TELEPATHY-GABBLE "8" "October 2007" "Telepathy" "D-Bus services" -\" This man page was written by Simon McVittie for the Debian project, -\" but may be used by others. -\" Copyright © 2007 Collabora Ltd. -\" It may be distributed under the same terms as telepathy-gabble itself. -.SH NAME -telepathy-gabble \- Telepathy connection manager for XMPP (Jabber) -.SH SYNOPSIS -\fB@libexecdir@/telepathy\-gabble\fR -.SH DESCRIPTION -Gabble implements the Telepathy D-Bus specification for XMPP (Jabber), -allowing Telepathy clients like -.BR empathy (1) -to connect to XMPP accounts, including Google Talk. -.PP -It is a D-Bus service which runs on the session bus, and should usually be -started automatically by D-Bus activation. However, it might be useful to -start it manually for debugging. -.SH OPTIONS -There are no command-line options. -.SH ENVIRONMENT -.TP -\fBGABBLE_LOGFILE\fR=\fIfilename\fR -If set, debug output will go to the given file rather than to stderr. -If \fB+\fR is prepended to the \fIfilename\fR (e.g. -\fBGABBLE_LOGFILE=+gabble.log\fR), debug output will be appended -to the file; otherwise, any existing file will be replaced. -.TP -\fBGABBLE_DEBUG\fR=\fItype\fR -May be set to "all" for full debug output, or various undocumented options -(which may change from release to release) to filter the output. -.TP -\fBWOCKY_DEBUG\fR=\fItype\fR -May be set to "all" for full debug output from the Wocky XMPP library used -by Gabble, or various undocumented options (which may change from release to -release) to filter the output. For general Gabble debugging, "net" is -recommended. -.TP -\fBGABBLE_PERSIST\fR=\fI1\fR -If set (to any value), Gabble will continue running until killed, rather than -timing out if it has no open connections for a few seconds. -.TP -\fBGABBLE_PLUGIN_DIR\fR=\fIdirectory\fR -If set, and Gabble was compiled with plugin support, plugins will be loaded -from \fIdirectory\fR rather than from the default directory. -.SH SEE ALSO -.IR http://telepathy.freedesktop.org/ , -.IR http://telepathy.freedesktop.org/wiki/CategoryGabble , -.BR empathy (1) diff --git a/gabble/Makefile.am b/gabble/Makefile.am index 1e729a0..b9728a6 100644 --- a/gabble/Makefile.am +++ b/gabble/Makefile.am @@ -3,7 +3,7 @@ if ENABLE_PLUGIN_API pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = telepathy-gabble.pc -gabbleincludedir = $(includedir)/telepathy-gabble-0/gabble +gabbleincludedir = $(includedir)/telepathy-gabble-1/gabble gabbleinclude_HEADERS = $(headers) else diff --git a/gabble/telepathy-gabble-1-uninstalled.pc.in b/gabble/telepathy-gabble-1-uninstalled.pc.in new file mode 100644 index 0000000..639d53d --- /dev/null +++ b/gabble/telepathy-gabble-1-uninstalled.pc.in @@ -0,0 +1,17 @@ +prefix= +exec_prefix= +abs_top_srcdir=@abs_top_srcdir@ +abs_top_builddir=@abs_top_builddir@ +libdir=@libdir@ +pluginexecdir=@pluginexecdir@ +pluginexeclibdir=@pluginexeclibdir@ + +gabblepath=@abs_top_builddir@/src/telepathy-gabble-1 # For plugins' tests + +Name: Telepathy-Gabble +Description: XMPP backend for the Telepathy framework +Version: @VERSION@ +Requires: pkg-config >= 0.21 +Requires.private: glib-2.0 >= 2.32, gobject-2.0, gio-2.0, telepathy-glib-1, telepathy-glib-1-dbus +Libs: ${abs_top_builddir}/src/libgabble-plugins.la +Cflags: -I${abs_top_srcdir} -I${abs_top_srcdir}/lib/ext/wocky diff --git a/gabble/telepathy-gabble-1.pc.in b/gabble/telepathy-gabble-1.pc.in new file mode 100644 index 0000000..0cd1108 --- /dev/null +++ b/gabble/telepathy-gabble-1.pc.in @@ -0,0 +1,16 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +libexecdir=@libexecdir@ +pluginexecdir=@pluginexecdir@ +pluginexeclibdir=@pluginexeclibdir@ +gabblepath=${libexecdir}/telepathy-gabble-1 # For plugins' tests + +Name: Telepathy-Gabble +Description: XMPP backend for the Telepathy framework +Version: @VERSION@ +Requires: pkg-config >= 0.21 +Requires.private: glib-2.0 >= 2.32, gobject-2.0, gio-2.0, telepathy-glib-1, telepathy-glib-1-dbus +Libs: -L${pluginexeclibdir} -lgabble-plugins -lwocky +Cflags: -I${includedir}/telepathy-gabble-1 diff --git a/gabble/telepathy-gabble-uninstalled.pc.in b/gabble/telepathy-gabble-uninstalled.pc.in deleted file mode 100644 index f5d027f..0000000 --- a/gabble/telepathy-gabble-uninstalled.pc.in +++ /dev/null @@ -1,17 +0,0 @@ -prefix= -exec_prefix= -abs_top_srcdir=@abs_top_srcdir@ -abs_top_builddir=@abs_top_builddir@ -libdir=@libdir@ -pluginexecdir=@pluginexecdir@ -pluginexeclibdir=@pluginexeclibdir@ - -gabblepath=@abs_top_builddir@/src/telepathy-gabble # For plugins' tests - -Name: Telepathy-Gabble -Description: XMPP backend for the Telepathy framework -Version: @VERSION@ -Requires: pkg-config >= 0.21 -Requires.private: glib-2.0 >= 2.32, gobject-2.0, gio-2.0, telepathy-glib >= 0.19.9 -Libs: ${abs_top_builddir}/src/libgabble-plugins.la -Cflags: -I${abs_top_srcdir} -I${abs_top_srcdir}/lib/ext/wocky diff --git a/gabble/telepathy-gabble.pc.in b/gabble/telepathy-gabble.pc.in deleted file mode 100644 index 013ddbb..0000000 --- a/gabble/telepathy-gabble.pc.in +++ /dev/null @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -libexecdir=@libexecdir@ -pluginexecdir=@pluginexecdir@ -pluginexeclibdir=@pluginexeclibdir@ -gabblepath=${libexecdir}/telepathy-gabble # For plugins' tests - -Name: Telepathy-Gabble -Description: XMPP backend for the Telepathy framework -Version: @VERSION@ -Requires: pkg-config >= 0.21 -Requires.private: glib-2.0 >= 2.32, gobject-2.0, gio-2.0, telepathy-glib >= 0.19.9 -Libs: -L${pluginexeclibdir} -lgabble-plugins -lwocky -Cflags: -I${includedir}/telepathy-gabble-0 diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 2b00079..536f49d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -30,14 +30,14 @@ if ENABLE_PLUGINS pluginexec_LTLIBRARIES = $(installable_plugins) dist_bin_SCRIPTS = \ - telepathy-gabble-xmpp-console + telepathy-gabble-1-xmpp-console else # we still compile the plugin (just to make sure it compiles!) but we don't # install it noinst_LTLIBRARIES += $(installable_plugins) EXTRA_DIST = \ - telepathy-gabble-xmpp-console + telepathy-gabble-1-xmpp-console endif AM_LDFLAGS = -avoid-version -shared -no-undefined diff --git a/plugins/telepathy-gabble-1-xmpp-console b/plugins/telepathy-gabble-1-xmpp-console new file mode 100755 index 0000000..ea58315 --- /dev/null +++ b/plugins/telepathy-gabble-1-xmpp-console @@ -0,0 +1,451 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 sts=4 sw=4 et : +""" +The world's worst XMPP console user interface. + +Pass it a Gabble account name; type some words; get minimalistic +error reporting. + +Copyright © 2011–2013 Collabora Ltd. + +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 +""" + +import sys +from xml.dom import minidom + +from gi.repository import Gtk, GLib, Gio, GtkSource +from gi.repository import TelepathyGLib as Tp + +PADDING = 6 + +CONSOLE_IFACE = "im.telepathy.v1.Gabble.Plugin.Console" + +class StanzaViewer(Gtk.ScrolledWindow): + def __init__(self): + Gtk.ScrolledWindow.__init__(self) + + self.b = GtkSource.Buffer() + self.view = GtkSource.View.new_with_buffer(self.b) + self.b.set_language( + GtkSource.LanguageManager.get_default().get_language('xml')) + self.b.set_highlight_matching_brackets(False) + self.view.set_editable(False) + self.view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) + self.view.set_property('expand', True) + + self.add(self.view) + + def clear(self): + self.b.set_text("") + + def append_stanza(self, xml): + pretty = minidom.parseString(xml).toprettyxml() + pretty = pretty.replace('\n', '') + i = self.b.get_end_iter() + self.b.insert(i, pretty + '\n') + + def append_comment(self, text): + i = self.b.get_end_iter() + self.b.insert(i, '\n' % text) + + def tell_me_everything(self): + return self.b.get_property('text') + +class SpinWrapper(Gtk.Notebook): + PRIMARY_PAGE = 0 + SPINNER_PAGE = 1 + + def __init__(self, main_widget): + Gtk.Notebook.__init__(self) + self.set_show_tabs(False) + self.set_show_border(False) + self.insert_page(main_widget, None, self.PRIMARY_PAGE) + + self.spinner = Gtk.Spinner() + self.spinner.set_property('halign', Gtk.Align.CENTER) + self.spinner.set_property('valign', Gtk.Align.CENTER) + self.spinner.set_property('width-request', 32) + self.spinner.set_property('height-request', 32) + self.insert_page(self.spinner, None, self.SPINNER_PAGE) + + def start_spinning(self): + self.set_current_page(self.SPINNER_PAGE) + self.spinner.start() + + def stop_spinning(self): + self.spinner.stop() + self.set_current_page(self.PRIMARY_PAGE) + +class Page(Gtk.Grid): + def __init__(self, console_proxy): + Gtk.Grid.__init__(self) + + self.console_proxy = console_proxy + + self.set_column_spacing(PADDING) + self.set_row_spacing(PADDING) + + def add_title(self, title, below=None): + label = Gtk.Label() + label.set_markup("%s" % title) + label.set_property('xalign', 0) + + if below is None: + self.attach(label, 0, 0, 2, 1) + else: + self.attach_next_to(label, below, Gtk.PositionType.BOTTOM, 2, 1) + + return label + + def add_label(self, title, below=None): + label = Gtk.Label(title) + label.set_property('margin-left', PADDING) + label.set_property('xalign', 0) + + if below is None: + self.attach(label, 0, 0, 1, 1) + else: + self.attach_next_to(label, below, Gtk.PositionType.BOTTOM, 1, 1) + + return label + +class IQPage(Page): + def __init__(self, console_proxy): + Page.__init__(self, console_proxy) + + request_label = self.add_title("Request") + + recipient_label, recipient_entry = self.add_label_entry_pair( + 'To:', below=request_label) + self.recipient_entry = recipient_entry + + type_label = self.add_label('IQ Type:', below=recipient_label) + self.get_button = Gtk.RadioButton.new_with_label([], "get") + self.get_button.set_active(True) + self.set_button = Gtk.RadioButton.new_with_label_from_widget( + self.get_button, "set") + + box = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL) + box.set_layout(Gtk.ButtonBoxStyle.START) + box.add(self.get_button) + box.add(self.set_button) + self.attach_next_to(box, type_label, + Gtk.PositionType.RIGHT, 1, 1) + + body_label, body_entry = self.add_label_entry_pair( + 'Body:', below=type_label) + body_entry.set_text( + "") + body_entry.set_icon_from_stock( + Gtk.EntryIconPosition.SECONDARY, Gtk.STOCK_GO_FORWARD) + body_entry.set_icon_tooltip_text( + Gtk.EntryIconPosition.SECONDARY, "Send this IQ") + self.body_entry = body_entry + + reply_label = self.add_title("Reply", below=body_label) + + self.stanza_viewer = StanzaViewer() + self.stanza_viewer.append_comment("send a request to see the reply here") + + self.result_nb = SpinWrapper(self.stanza_viewer) + + self.attach_next_to(self.result_nb, reply_label, Gtk.PositionType.BOTTOM, 2, 1) + + body_entry.connect('activate', self.send_iq) + body_entry.connect('icon-release', self.send_iq) + + def add_label_entry_pair(self, title, below): + label = self.add_label(title, below) + + entry = Gtk.Entry() + entry.set_property('margin-right', PADDING) + entry.set_property('hexpand', True) + + self.attach_next_to(entry, label, Gtk.PositionType.RIGHT, 1, 1) + + return label, entry + + def send_iq(self, *misc): + type = 'get' if self.get_button.get_active() else 'set' + to = self.recipient_entry.get_text() + body = self.body_entry.get_text() + + self.console_proxy.SendIQ('(sss)', type, to, body, + result_handler=self.send_iq_cb) + self.result_nb.start_spinning() + + def send_iq_cb(self, proxy, result, user_data): + self.stanza_viewer.clear() + + if isinstance(result, Exception): + self.stanza_viewer.append_comment("error:\n%s" % result) + else: + reply_type, reply = result + self.stanza_viewer.append_stanza(reply) + + self.result_nb.stop_spinning() + +class StanzaPage(Page): + def __init__(self, console_proxy): + Page.__init__(self, console_proxy) + + title = self.add_title("Enter a complete stanza:") + + self.sv = StanzaViewer() + self.sv.view.set_editable(True) + self.sv.append_stanza("Been on any nice boats recently?") + + self.spin_wrapper = SpinWrapper(self.sv) + self.attach_next_to(self.spin_wrapper, title, Gtk.PositionType.BOTTOM, + 2, 1) + + self.result_label = self.add_label('', self.spin_wrapper) + self.result_label.set_property('hexpand', True) + self.result_label.set_line_wrap(True) + + b = Gtk.Button.new_with_mnemonic("_Send") + b.connect('clicked', self.__send_stanza) + b.set_property('hexpand', False) + self.attach_next_to(b, self.result_label, Gtk.PositionType.RIGHT, 1, 1) + + def __send_stanza(self, button): + self.console_proxy.SendStanza('(s)', self.sv.tell_me_everything(), + result_handler=self.__send_stanza_cb) + self.spin_wrapper.start_spinning() + + def __send_stanza_cb(self, proxy, result, user_data): + if isinstance(result, Exception): + # FIXME: this sucks. You can't just get the free text bit without + # the D-Bus error bit. + t = result.message + else: + t = "yes sir, captain tightpants" + + self.result_label.set_text(t) + self.spin_wrapper.stop_spinning() + +class SnoopyPage(Page): + def __init__(self, console_proxy): + Page.__init__(self, console_proxy) + + label = self.add_label("Stanza monitor:") + label.set_property('hexpand', True) + + switch = Gtk.Switch() + self.attach_next_to(switch, label, Gtk.PositionType.RIGHT, 1, 1) + + self.stanza_viewer = StanzaViewer() + self.attach_next_to(self.stanza_viewer, label, Gtk.PositionType.BOTTOM, 2, 1) + + switch.set_active(self.get_remote_active()) + switch.connect('notify::active', self.__switch_switched_cb) + + self.console_proxy.connect('g-signal', self.__g_signal_cb) + + def teardown(self): + """Turn off the monitor when we quit.""" + self.__set_spew(False) + + def __set_spew(self, spew): + args = GLib.Variant("(ssv)", (CONSOLE_IFACE, "SpewStanzas", + GLib.Variant.new_boolean(spew))) + self.console_proxy.call_sync( + "org.freedesktop.DBus.Properties.Set", + args, + 0, -1, None) + + def get_remote_active(self): + return self.console_proxy.get_cached_property('SpewStanzas').get_boolean() + + def __switch_switched_cb(self, switch, pspec): + remote = self.get_remote_active() + new_local = switch.get_active() + + if new_local != remote: + self.__set_spew(new_local) + self.stanza_viewer.append_comment( + 'started monitoring' if new_local else 'stopped monitoring') + + def __g_signal_cb(self, console_proxy, sender_name, signal_name, parameters): + if signal_name in ['StanzaSent', 'StanzaReceived']: + outgoing = (signal_name == 'StanzaSent') + xml, = parameters + + self.stanza_viewer.append_comment('sent' if outgoing else 'received') + self.stanza_viewer.append_stanza(xml) + +class Window(Gtk.Window): + IQ_PAGE = 0 + STANZA_PAGE = 1 + SNOOPY_PAGE = 2 + + def __init__(self, account): + Gtk.Window.__init__(self) + + self.set_title('XMPP Console') + self.set_default_size(600, 371) + + request = Tp.AccountChannelRequest.new( + account, + { Tp.PROP_CHANNEL_CHANNEL_TYPE: CONSOLE_IFACE }, + 0) + request.create_and_handle_channel_async(None, self.__create_cb, 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.grid.attach(self.nb, 0, 0, 1, 1) + + self.iq = IQPage(self.console_proxy) + self.nb.insert_page(self.iq, + Gtk.Label.new_with_mnemonic("_IQ console"), + self.IQ_PAGE) + + self.stanza = StanzaPage(self.console_proxy) + self.nb.insert_page(self.stanza, + Gtk.Label.new_with_mnemonic("Send a s_tanza"), + self.STANZA_PAGE) + + self.snoopy = SnoopyPage(self.console_proxy) + self.nb.insert_page(self.snoopy, + Gtk.Label.new_with_mnemonic("_Monitor network traffic"), + self.SNOOPY_PAGE) + + 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): + 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() + +def usage(am): + xmpp_accounts = sorted( + account.get_path_suffix() + for account in am.dup_valid_accounts() + if account.get_cm_name() == 'gabble') + + print """ +Usage: + + %(arg0)s gabble/jabber/blahblah + +Here are some account identifiers: + + %(accounts)s +""" % { 'arg0': sys.argv[0], + 'accounts': '\n '.join(xmpp_accounts), + } + raise SystemExit(1) + +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) + + 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 + + am = Tp.AccountManager.dup() + am.prepare_async([], am_prepared_cb, account_suffix) + + Gtk.main() + +""" + .,,. + ,;;*;;;;, + .-'``;-');;. + /' .-. /*;; + .' \d \;; .;;;, + / o ` \; ,__. ,;*;;;*;, + \__, _.__,' \_.-') __)--.;;;;;*;;;;, + `""`;;;\ /-')_) __) `\' ';;;;;; + ;*;;; -') `)_) |\ | ;;;;*; + ;;;;| `---` O | | ;;*;;; + *;*;\| O / ;;;;;* + ;;;;;/| .-------\ / ;*;;;;; + ;;;*;/ \ | '. (`. ;;;*;;; + ;;;;;'. ; | ) \ | ;;;;;; + ,;*;;;;\/ |. / /` | ';;;*; + ;;;;;;/ |/ / /__/ ';;; + '*jgs/ | / | ;*; + `""""` `""""` ;' +""" diff --git a/plugins/telepathy-gabble-xmpp-console b/plugins/telepathy-gabble-xmpp-console deleted file mode 100755 index ea58315..0000000 --- a/plugins/telepathy-gabble-xmpp-console +++ /dev/null @@ -1,451 +0,0 @@ -#!/usr/bin/env python -# vim: set fileencoding=utf-8 sts=4 sw=4 et : -""" -The world's worst XMPP console user interface. - -Pass it a Gabble account name; type some words; get minimalistic -error reporting. - -Copyright © 2011–2013 Collabora Ltd. - -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 -""" - -import sys -from xml.dom import minidom - -from gi.repository import Gtk, GLib, Gio, GtkSource -from gi.repository import TelepathyGLib as Tp - -PADDING = 6 - -CONSOLE_IFACE = "im.telepathy.v1.Gabble.Plugin.Console" - -class StanzaViewer(Gtk.ScrolledWindow): - def __init__(self): - Gtk.ScrolledWindow.__init__(self) - - self.b = GtkSource.Buffer() - self.view = GtkSource.View.new_with_buffer(self.b) - self.b.set_language( - GtkSource.LanguageManager.get_default().get_language('xml')) - self.b.set_highlight_matching_brackets(False) - self.view.set_editable(False) - self.view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) - self.view.set_property('expand', True) - - self.add(self.view) - - def clear(self): - self.b.set_text("") - - def append_stanza(self, xml): - pretty = minidom.parseString(xml).toprettyxml() - pretty = pretty.replace('\n', '') - i = self.b.get_end_iter() - self.b.insert(i, pretty + '\n') - - def append_comment(self, text): - i = self.b.get_end_iter() - self.b.insert(i, '\n' % text) - - def tell_me_everything(self): - return self.b.get_property('text') - -class SpinWrapper(Gtk.Notebook): - PRIMARY_PAGE = 0 - SPINNER_PAGE = 1 - - def __init__(self, main_widget): - Gtk.Notebook.__init__(self) - self.set_show_tabs(False) - self.set_show_border(False) - self.insert_page(main_widget, None, self.PRIMARY_PAGE) - - self.spinner = Gtk.Spinner() - self.spinner.set_property('halign', Gtk.Align.CENTER) - self.spinner.set_property('valign', Gtk.Align.CENTER) - self.spinner.set_property('width-request', 32) - self.spinner.set_property('height-request', 32) - self.insert_page(self.spinner, None, self.SPINNER_PAGE) - - def start_spinning(self): - self.set_current_page(self.SPINNER_PAGE) - self.spinner.start() - - def stop_spinning(self): - self.spinner.stop() - self.set_current_page(self.PRIMARY_PAGE) - -class Page(Gtk.Grid): - def __init__(self, console_proxy): - Gtk.Grid.__init__(self) - - self.console_proxy = console_proxy - - self.set_column_spacing(PADDING) - self.set_row_spacing(PADDING) - - def add_title(self, title, below=None): - label = Gtk.Label() - label.set_markup("%s" % title) - label.set_property('xalign', 0) - - if below is None: - self.attach(label, 0, 0, 2, 1) - else: - self.attach_next_to(label, below, Gtk.PositionType.BOTTOM, 2, 1) - - return label - - def add_label(self, title, below=None): - label = Gtk.Label(title) - label.set_property('margin-left', PADDING) - label.set_property('xalign', 0) - - if below is None: - self.attach(label, 0, 0, 1, 1) - else: - self.attach_next_to(label, below, Gtk.PositionType.BOTTOM, 1, 1) - - return label - -class IQPage(Page): - def __init__(self, console_proxy): - Page.__init__(self, console_proxy) - - request_label = self.add_title("Request") - - recipient_label, recipient_entry = self.add_label_entry_pair( - 'To:', below=request_label) - self.recipient_entry = recipient_entry - - type_label = self.add_label('IQ Type:', below=recipient_label) - self.get_button = Gtk.RadioButton.new_with_label([], "get") - self.get_button.set_active(True) - self.set_button = Gtk.RadioButton.new_with_label_from_widget( - self.get_button, "set") - - box = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL) - box.set_layout(Gtk.ButtonBoxStyle.START) - box.add(self.get_button) - box.add(self.set_button) - self.attach_next_to(box, type_label, - Gtk.PositionType.RIGHT, 1, 1) - - body_label, body_entry = self.add_label_entry_pair( - 'Body:', below=type_label) - body_entry.set_text( - "") - body_entry.set_icon_from_stock( - Gtk.EntryIconPosition.SECONDARY, Gtk.STOCK_GO_FORWARD) - body_entry.set_icon_tooltip_text( - Gtk.EntryIconPosition.SECONDARY, "Send this IQ") - self.body_entry = body_entry - - reply_label = self.add_title("Reply", below=body_label) - - self.stanza_viewer = StanzaViewer() - self.stanza_viewer.append_comment("send a request to see the reply here") - - self.result_nb = SpinWrapper(self.stanza_viewer) - - self.attach_next_to(self.result_nb, reply_label, Gtk.PositionType.BOTTOM, 2, 1) - - body_entry.connect('activate', self.send_iq) - body_entry.connect('icon-release', self.send_iq) - - def add_label_entry_pair(self, title, below): - label = self.add_label(title, below) - - entry = Gtk.Entry() - entry.set_property('margin-right', PADDING) - entry.set_property('hexpand', True) - - self.attach_next_to(entry, label, Gtk.PositionType.RIGHT, 1, 1) - - return label, entry - - def send_iq(self, *misc): - type = 'get' if self.get_button.get_active() else 'set' - to = self.recipient_entry.get_text() - body = self.body_entry.get_text() - - self.console_proxy.SendIQ('(sss)', type, to, body, - result_handler=self.send_iq_cb) - self.result_nb.start_spinning() - - def send_iq_cb(self, proxy, result, user_data): - self.stanza_viewer.clear() - - if isinstance(result, Exception): - self.stanza_viewer.append_comment("error:\n%s" % result) - else: - reply_type, reply = result - self.stanza_viewer.append_stanza(reply) - - self.result_nb.stop_spinning() - -class StanzaPage(Page): - def __init__(self, console_proxy): - Page.__init__(self, console_proxy) - - title = self.add_title("Enter a complete stanza:") - - self.sv = StanzaViewer() - self.sv.view.set_editable(True) - self.sv.append_stanza("Been on any nice boats recently?") - - self.spin_wrapper = SpinWrapper(self.sv) - self.attach_next_to(self.spin_wrapper, title, Gtk.PositionType.BOTTOM, - 2, 1) - - self.result_label = self.add_label('', self.spin_wrapper) - self.result_label.set_property('hexpand', True) - self.result_label.set_line_wrap(True) - - b = Gtk.Button.new_with_mnemonic("_Send") - b.connect('clicked', self.__send_stanza) - b.set_property('hexpand', False) - self.attach_next_to(b, self.result_label, Gtk.PositionType.RIGHT, 1, 1) - - def __send_stanza(self, button): - self.console_proxy.SendStanza('(s)', self.sv.tell_me_everything(), - result_handler=self.__send_stanza_cb) - self.spin_wrapper.start_spinning() - - def __send_stanza_cb(self, proxy, result, user_data): - if isinstance(result, Exception): - # FIXME: this sucks. You can't just get the free text bit without - # the D-Bus error bit. - t = result.message - else: - t = "yes sir, captain tightpants" - - self.result_label.set_text(t) - self.spin_wrapper.stop_spinning() - -class SnoopyPage(Page): - def __init__(self, console_proxy): - Page.__init__(self, console_proxy) - - label = self.add_label("Stanza monitor:") - label.set_property('hexpand', True) - - switch = Gtk.Switch() - self.attach_next_to(switch, label, Gtk.PositionType.RIGHT, 1, 1) - - self.stanza_viewer = StanzaViewer() - self.attach_next_to(self.stanza_viewer, label, Gtk.PositionType.BOTTOM, 2, 1) - - switch.set_active(self.get_remote_active()) - switch.connect('notify::active', self.__switch_switched_cb) - - self.console_proxy.connect('g-signal', self.__g_signal_cb) - - def teardown(self): - """Turn off the monitor when we quit.""" - self.__set_spew(False) - - def __set_spew(self, spew): - args = GLib.Variant("(ssv)", (CONSOLE_IFACE, "SpewStanzas", - GLib.Variant.new_boolean(spew))) - self.console_proxy.call_sync( - "org.freedesktop.DBus.Properties.Set", - args, - 0, -1, None) - - def get_remote_active(self): - return self.console_proxy.get_cached_property('SpewStanzas').get_boolean() - - def __switch_switched_cb(self, switch, pspec): - remote = self.get_remote_active() - new_local = switch.get_active() - - if new_local != remote: - self.__set_spew(new_local) - self.stanza_viewer.append_comment( - 'started monitoring' if new_local else 'stopped monitoring') - - def __g_signal_cb(self, console_proxy, sender_name, signal_name, parameters): - if signal_name in ['StanzaSent', 'StanzaReceived']: - outgoing = (signal_name == 'StanzaSent') - xml, = parameters - - self.stanza_viewer.append_comment('sent' if outgoing else 'received') - self.stanza_viewer.append_stanza(xml) - -class Window(Gtk.Window): - IQ_PAGE = 0 - STANZA_PAGE = 1 - SNOOPY_PAGE = 2 - - def __init__(self, account): - Gtk.Window.__init__(self) - - self.set_title('XMPP Console') - self.set_default_size(600, 371) - - request = Tp.AccountChannelRequest.new( - account, - { Tp.PROP_CHANNEL_CHANNEL_TYPE: CONSOLE_IFACE }, - 0) - request.create_and_handle_channel_async(None, self.__create_cb, 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.grid.attach(self.nb, 0, 0, 1, 1) - - self.iq = IQPage(self.console_proxy) - self.nb.insert_page(self.iq, - Gtk.Label.new_with_mnemonic("_IQ console"), - self.IQ_PAGE) - - self.stanza = StanzaPage(self.console_proxy) - self.nb.insert_page(self.stanza, - Gtk.Label.new_with_mnemonic("Send a s_tanza"), - self.STANZA_PAGE) - - self.snoopy = SnoopyPage(self.console_proxy) - self.nb.insert_page(self.snoopy, - Gtk.Label.new_with_mnemonic("_Monitor network traffic"), - self.SNOOPY_PAGE) - - 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): - 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() - -def usage(am): - xmpp_accounts = sorted( - account.get_path_suffix() - for account in am.dup_valid_accounts() - if account.get_cm_name() == 'gabble') - - print """ -Usage: - - %(arg0)s gabble/jabber/blahblah - -Here are some account identifiers: - - %(accounts)s -""" % { 'arg0': sys.argv[0], - 'accounts': '\n '.join(xmpp_accounts), - } - raise SystemExit(1) - -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) - - 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 - - am = Tp.AccountManager.dup() - am.prepare_async([], am_prepared_cb, account_suffix) - - Gtk.main() - -""" - .,,. - ,;;*;;;;, - .-'``;-');;. - /' .-. /*;; - .' \d \;; .;;;, - / o ` \; ,__. ,;*;;;*;, - \__, _.__,' \_.-') __)--.;;;;;*;;;;, - `""`;;;\ /-')_) __) `\' ';;;;;; - ;*;;; -') `)_) |\ | ;;;;*; - ;;;;| `---` O | | ;;*;;; - *;*;\| O / ;;;;;* - ;;;;;/| .-------\ / ;*;;;;; - ;;;*;/ \ | '. (`. ;;;*;;; - ;;;;;'. ; | ) \ | ;;;;;; - ,;*;;;;\/ |. / /` | ';;;*; - ;;;;;;/ |/ / /__/ ';;; - '*jgs/ | / | ;*; - `""""` `""""` ;' -""" diff --git a/src/Makefile.am b/src/Makefile.am index 28ff350..76bb226 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = -libexec_PROGRAMS=telepathy-gabble +libexec_PROGRAMS = telepathy-gabble-1 noinst_PROGRAMS = write-mgr-file libgabble_convenience_la_SOURCES = \ @@ -185,19 +185,19 @@ write_mgr_file_SOURCES = write-mgr-file.c write_mgr_file_LDADD = libgabble-convenience.la -telepathy_gabble_SOURCES = \ +telepathy_gabble_1_SOURCES = \ main.c check_c_sources = \ - $(telepathy_gabble_SOURCES) \ + $(telepathy_gabble_1_SOURCES) \ $(libgabble_convenience_la_SOURCES) \ $(write_mgr_file_SOURCES) include $(top_srcdir)/tools/check-coding-style.mk check-local: check-coding-style -telepathy_gabble_LDADD = libgabble-convenience.la +telepathy_gabble_1_LDADD = libgabble-convenience.la -telepathy_gabble_LDFLAGS = -export-dynamic +telepathy_gabble_1_LDFLAGS = -export-dynamic noinst_LTLIBRARIES = libgabble-convenience.la @@ -293,12 +293,12 @@ Android.mk: Makefile.am $(BUILT_SOURCES) -:CPPFLAGS $(CPPFLAGS) $(AM_CPPFLAGS) \ -:LDFLAGS $(libgabble_plugins_la_LDFLAGS) \ $(libgabble_plugins_la_LIBADD) \ - -:SHARED telepathy-gabble -:TAGS eng debug \ + -:SHARED telepathy-gabble-1 -:TAGS eng debug \ -:SOURCES $(libgabble_convenience_la_SOURCES) \ $(nodist_libgabble_convenience_la_SOURCES) main.c \ -:CFLAGS $(DEFS) $(CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CFLAGS) -DBUILD_AS_ANDROID_SERVICE \ - -:CPPFLAGS $(CPPFLAGS) $(AM_CPPFLAGS) $(telepathy_gabble_LDFLAGS) \ - -:LDFLAGS $(telepathy_gabble_LDADD) $(libgabble_convenience_la_LIBADD) \ + -:CPPFLAGS $(CPPFLAGS) $(AM_CPPFLAGS) $(telepathy_gabble_1_LDFLAGS) \ + -:LDFLAGS $(telepathy_gabble_1_LDADD) $(libgabble_convenience_la_LIBADD) \ $(lib_LTLIBRARIES) \ > $@ -- 1.8.4.3