From fe3a5a4aeeb6d327c582b4cb673667386c69f85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Tue, 25 Apr 2017 14:43:54 +0200 Subject: [PATCH 1/2] Make some methods public --- src/common/connection.py | 18 +++++++++--------- src/common/zeroconf/connection_zeroconf.py | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/common/connection.py b/src/common/connection.py index 222ec8788..a92f929b4 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -198,7 +198,7 @@ class CommonConnection: """ gajim.ged.raise_event(event, self.name, data) - def _reconnect(self): + def reconnect(self): """ To be implemented by derivated classes """ @@ -849,7 +849,7 @@ class Connection(CommonConnection, ConnectionHandlers): def check_jid(self, jid): return helpers.parse_jid(jid) - def _reconnect(self): + def reconnect(self): # Do not try to reco while we are already trying self.time_to_reconnect = None if self.connected < 2: # connection failed @@ -894,7 +894,7 @@ class Connection(CommonConnection, ConnectionHandlers): gajim.nec.push_incoming_event(OurShowEvent(None, conn=self, show=gajim.SHOW_LIST[self.connected])) - def _disconnectedReconnCB(self): + def disconnectedReconnCB(self): """ Called when we are disconnected """ @@ -914,7 +914,7 @@ class Connection(CommonConnection, ConnectionHandlers): show='error')) if self.connection: self.connection.UnregisterDisconnectHandler( - self._disconnectedReconnCB) + self.disconnectedReconnCB) self.disconnect() if gajim.config.get_per('accounts', self.name, 'autoreconnect'): self.connected = -1 @@ -925,7 +925,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.status = gajim.status_before_autoaway[self.name] gajim.status_before_autoaway[self.name] = '' self.old_show = 'online' - # this check has moved from _reconnect method + # this check has moved from reconnect method # do exponential backoff until less than 5 minutes if self.retrycount < 2 or self.last_time_to_reconnect is None: self.last_time_to_reconnect = 5 @@ -1242,7 +1242,7 @@ class Connection(CommonConnection, ConnectionHandlers): self._connection_lost() else: # try reconnect if connection has failed before auth to server - self._disconnectedReconnCB() + self.disconnectedReconnCB() def connect_to_next_type(self, retry=False): if self.redirected: @@ -1409,7 +1409,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.connected_hostname = self._current_host['host'] self.on_connect_failure = None con.UnregisterDisconnectHandler(self._on_disconnected) - con.RegisterDisconnectHandler(self._disconnectedReconnCB) + con.RegisterDisconnectHandler(self.disconnectedReconnCB) log.debug('Connected to server %s:%s with %s' % ( self._current_host['host'], self._current_host['port'], con_type)) @@ -3038,7 +3038,7 @@ class Connection(CommonConnection, ConnectionHandlers): if self.awaiting_xmpp_ping_id: # We haven't got the pong in time, disco and reconnect log.warning("No reply received for keepalive ping. Reconnecting.") - self._disconnectedReconnCB() + self.disconnectedReconnCB() def _reconnect_alarm(self): if not gajim.config.get_per('accounts', self.name, 'active'): @@ -3046,7 +3046,7 @@ class Connection(CommonConnection, ConnectionHandlers): return if self.time_to_reconnect: if self.connected < 2: - self._reconnect() + self.reconnect() else: self.time_to_reconnect = None diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py index 9db42774d..27fb610d1 100644 --- a/src/common/zeroconf/connection_zeroconf.py +++ b/src/common/zeroconf/connection_zeroconf.py @@ -120,7 +120,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): def check_jid(self, jid): return jid - def _reconnect(self): + def reconnect(self): # Do not try to reco while we are already trying self.time_to_reconnect = None gajim.log.debug('reconnect') @@ -163,7 +163,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent( None, conn=self, fjid=jid, show='offline', status='')) - def _disconnectedReconnCB(self): + def disconnectedReconnCB(self): """ Called when we are disconnected. Comes from network manager for example we don't try to reconnect, network manager will tell us when we can From 1840ff235e67146c4083643d8ba093352572d1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sun, 23 Apr 2017 01:14:26 +0200 Subject: [PATCH 2/2] Port Network Watcher to Gio API --- src/common/config.py | 2 - src/features_window.py | 12 ++-- src/gui_interface.py | 4 +- src/network_manager_listener.py | 100 -------------------------------- src/network_watcher.py | 84 +++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 112 deletions(-) delete mode 100644 src/network_manager_listener.py create mode 100644 src/network_watcher.py diff --git a/src/common/config.py b/src/common/config.py index 4df5634ef..90c8fe402 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -193,7 +193,6 @@ class Config: 'always_english_wikipedia': [opt_bool, False], 'always_english_wiktionary': [opt_bool, True], 'remote_control': [opt_bool, False, _('If checked, Gajim can be controlled remotely using gajim-remote.'), True], - 'networkmanager_support': [opt_bool, True, _('If True, listen to D-Bus signals from NetworkManager and change the status of accounts (provided they do not have listen_to_network_manager set to False and they sync with global status) based upon the status of the network connection.'), True], 'outgoing_chat_state_notifications': [opt_str, 'all', _('Sent chat state notifications. Can be one of all, composing_only, disabled.')], 'displayed_chat_state_notifications': [opt_str, 'all', _('Displayed chat state notifications in chat windows. Can be one of all, composing_only, disabled.')], 'autodetect_browser_mailer': [opt_bool, True, '', True], @@ -387,7 +386,6 @@ class Config: 'msgwin-y-position': [opt_int, -1], # Default is to let the wm decide 'msgwin-width': [opt_int, 480], 'msgwin-height': [opt_int, 440], - 'listen_to_network_manager': [opt_bool, True], 'is_zeroconf': [opt_bool, False], 'last_status': [opt_str, 'online'], 'last_status_msg': [opt_str, ''], diff --git a/src/features_window.py b/src/features_window.py index 6e5ad1709..799c8c3ab 100644 --- a/src/features_window.py +++ b/src/features_window.py @@ -61,9 +61,9 @@ class FeaturesWindow: _('Ability to encrypting chat messages with OpenPGP.'), _('Requires gpg and python-gnupg (http://code.google.com/p/python-gnupg/).'), _('Requires gpg.exe in PATH.')), - _('Network-manager'): (self.network_manager_available, + _('Network-Watcher'): (self.network_watcher_available, _('Autodetection of network status.'), - _('Requires gnome-network-manager and python-dbus.'), + _('Requires gnome-network-manager'), _('Feature not available under Windows.')), _('Password encryption'): (self.some_keyring_available, _('Passwords can be stored securely and not just in plaintext.'), @@ -178,11 +178,9 @@ class FeaturesWindow: def gpg_available(self): return gajim.HAVE_GPG - def network_manager_available(self): - if os.name == 'nt': - return False - import network_manager_listener - return network_manager_listener.supported + def network_watcher_available(self): + import network_watcher + return network_watcher.supported def some_keyring_available(self): if os.name == 'nt': diff --git a/src/gui_interface.py b/src/gui_interface.py index d1589062c..d73e0c501 100644 --- a/src/gui_interface.py +++ b/src/gui_interface.py @@ -2966,9 +2966,7 @@ class Interface: self.remote_ctrl = None - if gajim.config.get('networkmanager_support') and \ - dbus_support.supported: - import network_manager_listener + import network_watcher if dbus_support.supported: import upower_listener diff --git a/src/network_manager_listener.py b/src/network_manager_listener.py deleted file mode 100644 index ff5e8a27c..000000000 --- a/src/network_manager_listener.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -## src/network_manager_listener.py -## -## Copyright (C) 2006 Jeffrey C. Ollie -## Nikos Kouremenos -## Stefan Bethge -## Copyright (C) 2006-2014 Yann Leboulanger -## -## This file is part of Gajim. -## -## Gajim is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published -## by the Free Software Foundation; version 3 only. -## -## Gajim is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Gajim. If not, see . -## - -from common import gajim - - -def device_now_active(self, *args): - """ - For Network Manager 0.6 - """ - for connection in gajim.connections.values(): - if gajim.config.get_per('accounts', connection.name, - 'listen_to_network_manager') and connection.time_to_reconnect: - connection._reconnect() - -def device_no_longer_active(self, *args): - """ - For Network Manager 0.6 - """ - for connection in gajim.connections.values(): - if gajim.config.get_per('accounts', connection.name, - 'listen_to_network_manager') and connection.connected > 1: - connection._disconnectedReconnCB() - -def state_changed(state): - """ - For Network Manager 0.7 - 0.9 - """ - if state == 70: - for connection in gajim.connections.values(): - if gajim.config.get_per('accounts', connection.name, - 'listen_to_network_manager') and connection.time_to_reconnect: - connection._reconnect() - else: - for connection in gajim.connections.values(): - if gajim.config.get_per('accounts', connection.name, - 'listen_to_network_manager') and connection.connected > 1: - connection._disconnectedReconnCB() - -supported = False - -from common import dbus_support - -if dbus_support.supported: - import dbus - - try: - from common.dbus_support import system_bus - - bus = system_bus.bus() - - if 'org.freedesktop.NetworkManager' in bus.list_names(): - nm_object = bus.get_object('org.freedesktop.NetworkManager', - '/org/freedesktop/NetworkManager') - props = dbus.Interface(nm_object, "org.freedesktop.DBus.Properties") - bus.add_signal_receiver(state_changed, - 'StateChanged', - 'org.freedesktop.NetworkManager', - 'org.freedesktop.NetworkManager', - '/org/freedesktop/NetworkManager') - supported = True - - except dbus.DBusException: - try: - if 'org.freedesktop.NetworkManager' in bus.list_names(): - supported = True - - bus.add_signal_receiver(device_no_longer_active, - 'DeviceNoLongerActive', - 'org.freedesktop.NetworkManager', - 'org.freedesktop.NetworkManager', - '/org/freedesktop/NetworkManager') - - bus.add_signal_receiver(device_now_active, - 'DeviceNowActive', - 'org.freedesktop.NetworkManager', - 'org.freedesktop.NetworkManager', - '/org/freedesktop/NetworkManager') - except Exception: - pass diff --git a/src/network_watcher.py b/src/network_watcher.py new file mode 100644 index 000000000..6c6a798ae --- /dev/null +++ b/src/network_watcher.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +## src/network_watcher.py +## +## Copyright (C) 2017 Philipp Hoerist +## +## This file is part of Gajim. +## +## Gajim is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## Gajim is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Gajim. If not, see . +## + + +import logging + +from gi.repository import Gio, GLib + +from common import gajim + +log = logging.getLogger('gajim.network_watcher') + + +supported = False + + +def watch_name(name): + Gio.bus_watch_name( + Gio.BusType.SYSTEM, + name, + Gio.BusNameWatcherFlags.NONE, + appeared, + None) + + +def signal_received(connection, sender_name, object_path, + interface_name, signal_name, parameters, *user_data): + connected = None + log.info('Signal received: %s - %s', interface_name, parameters) + if interface_name == 'org.freedesktop.NetworkManager': + # https://people.freedesktop.org/~lkundrak/nm-docs/nm-dbus-types.html + connected = parameters[0] == 70 + if connected is not None: + GLib.timeout_add_seconds( + 2, update_connection_state, + connected) + + +def appeared(connection, name, name_owner, *user_data): + global supported + supported = True + log.info('%s appeared', name) + if name == 'org.freedesktop.NetworkManager': + connection.signal_subscribe( + 'org.freedesktop.NetworkManager', + None, + 'StateChanged', + '/org/freedesktop/NetworkManager', + None, + Gio.DBusSignalFlags.NONE, + signal_received, + None) + + +def update_connection_state(connected): + if connected: + for connection in gajim.connections.values(): + log.info('Connect %s', connection.name) + connection.reconnect() + else: + for connection in gajim.connections.values(): + if connection.connected > 1: + log.info('Disconnect %s', connection.name) + connection.disconnectedReconnCB() + + +watch_name('org.freedesktop.NetworkManager')