Merge branch 'dbus' into 'master'

Port Network Watcher to Gio API

See merge request !88
This commit is contained in:
Philipp Hörist 2017-04-29 23:37:55 +02:00
commit 89f1e9820d
7 changed files with 101 additions and 123 deletions

View File

@ -193,7 +193,6 @@ class Config:
'always_english_wikipedia': [opt_bool, False], 'always_english_wikipedia': [opt_bool, False],
'always_english_wiktionary': [opt_bool, True], 'always_english_wiktionary': [opt_bool, True],
'remote_control': [opt_bool, False, _('If checked, Gajim can be controlled remotely using gajim-remote.'), 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.')], '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.')], '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], '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-y-position': [opt_int, -1], # Default is to let the wm decide
'msgwin-width': [opt_int, 480], 'msgwin-width': [opt_int, 480],
'msgwin-height': [opt_int, 440], 'msgwin-height': [opt_int, 440],
'listen_to_network_manager': [opt_bool, True],
'is_zeroconf': [opt_bool, False], 'is_zeroconf': [opt_bool, False],
'last_status': [opt_str, 'online'], 'last_status': [opt_str, 'online'],
'last_status_msg': [opt_str, ''], 'last_status_msg': [opt_str, ''],

View File

@ -198,7 +198,7 @@ class CommonConnection:
""" """
gajim.ged.raise_event(event, self.name, data) gajim.ged.raise_event(event, self.name, data)
def _reconnect(self): def reconnect(self):
""" """
To be implemented by derivated classes To be implemented by derivated classes
""" """
@ -849,7 +849,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def check_jid(self, jid): def check_jid(self, jid):
return helpers.parse_jid(jid) return helpers.parse_jid(jid)
def _reconnect(self): def reconnect(self):
# Do not try to reco while we are already trying # Do not try to reco while we are already trying
self.time_to_reconnect = None self.time_to_reconnect = None
if self.connected < 2: # connection failed if self.connected < 2: # connection failed
@ -894,7 +894,7 @@ class Connection(CommonConnection, ConnectionHandlers):
gajim.nec.push_incoming_event(OurShowEvent(None, conn=self, gajim.nec.push_incoming_event(OurShowEvent(None, conn=self,
show=gajim.SHOW_LIST[self.connected])) show=gajim.SHOW_LIST[self.connected]))
def _disconnectedReconnCB(self): def disconnectedReconnCB(self):
""" """
Called when we are disconnected Called when we are disconnected
""" """
@ -914,7 +914,7 @@ class Connection(CommonConnection, ConnectionHandlers):
show='error')) show='error'))
if self.connection: if self.connection:
self.connection.UnregisterDisconnectHandler( self.connection.UnregisterDisconnectHandler(
self._disconnectedReconnCB) self.disconnectedReconnCB)
self.disconnect() self.disconnect()
if gajim.config.get_per('accounts', self.name, 'autoreconnect'): if gajim.config.get_per('accounts', self.name, 'autoreconnect'):
self.connected = -1 self.connected = -1
@ -925,7 +925,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.status = gajim.status_before_autoaway[self.name] self.status = gajim.status_before_autoaway[self.name]
gajim.status_before_autoaway[self.name] = '' gajim.status_before_autoaway[self.name] = ''
self.old_show = 'online' 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 # do exponential backoff until less than 5 minutes
if self.retrycount < 2 or self.last_time_to_reconnect is None: if self.retrycount < 2 or self.last_time_to_reconnect is None:
self.last_time_to_reconnect = 5 self.last_time_to_reconnect = 5
@ -1242,7 +1242,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self._connection_lost() self._connection_lost()
else: else:
# try reconnect if connection has failed before auth to server # try reconnect if connection has failed before auth to server
self._disconnectedReconnCB() self.disconnectedReconnCB()
def connect_to_next_type(self, retry=False): def connect_to_next_type(self, retry=False):
if self.redirected: if self.redirected:
@ -1409,7 +1409,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connected_hostname = self._current_host['host'] self.connected_hostname = self._current_host['host']
self.on_connect_failure = None self.on_connect_failure = None
con.UnregisterDisconnectHandler(self._on_disconnected) con.UnregisterDisconnectHandler(self._on_disconnected)
con.RegisterDisconnectHandler(self._disconnectedReconnCB) con.RegisterDisconnectHandler(self.disconnectedReconnCB)
log.debug('Connected to server %s:%s with %s' % ( log.debug('Connected to server %s:%s with %s' % (
self._current_host['host'], self._current_host['port'], con_type)) self._current_host['host'], self._current_host['port'], con_type))
@ -3038,7 +3038,7 @@ class Connection(CommonConnection, ConnectionHandlers):
if self.awaiting_xmpp_ping_id: if self.awaiting_xmpp_ping_id:
# We haven't got the pong in time, disco and reconnect # We haven't got the pong in time, disco and reconnect
log.warning("No reply received for keepalive ping. Reconnecting.") log.warning("No reply received for keepalive ping. Reconnecting.")
self._disconnectedReconnCB() self.disconnectedReconnCB()
def _reconnect_alarm(self): def _reconnect_alarm(self):
if not gajim.config.get_per('accounts', self.name, 'active'): if not gajim.config.get_per('accounts', self.name, 'active'):
@ -3046,7 +3046,7 @@ class Connection(CommonConnection, ConnectionHandlers):
return return
if self.time_to_reconnect: if self.time_to_reconnect:
if self.connected < 2: if self.connected < 2:
self._reconnect() self.reconnect()
else: else:
self.time_to_reconnect = None self.time_to_reconnect = None

View File

@ -120,7 +120,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
def check_jid(self, jid): def check_jid(self, jid):
return jid return jid
def _reconnect(self): def reconnect(self):
# Do not try to reco while we are already trying # Do not try to reco while we are already trying
self.time_to_reconnect = None self.time_to_reconnect = None
gajim.log.debug('reconnect') gajim.log.debug('reconnect')
@ -163,7 +163,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent( gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
None, conn=self, fjid=jid, show='offline', status='')) 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 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 we don't try to reconnect, network manager will tell us when we can

View File

@ -61,9 +61,9 @@ class FeaturesWindow:
_('Ability to encrypting chat messages with OpenPGP.'), _('Ability to encrypting chat messages with OpenPGP.'),
_('Requires gpg and python-gnupg (http://code.google.com/p/python-gnupg/).'), _('Requires gpg and python-gnupg (http://code.google.com/p/python-gnupg/).'),
_('Requires gpg.exe in PATH.')), _('Requires gpg.exe in PATH.')),
_('Network-manager'): (self.network_manager_available, _('Network-Watcher'): (self.network_watcher_available,
_('Autodetection of network status.'), _('Autodetection of network status.'),
_('Requires gnome-network-manager and python-dbus.'), _('Requires gnome-network-manager'),
_('Feature not available under Windows.')), _('Feature not available under Windows.')),
_('Password encryption'): (self.some_keyring_available, _('Password encryption'): (self.some_keyring_available,
_('Passwords can be stored securely and not just in plaintext.'), _('Passwords can be stored securely and not just in plaintext.'),
@ -178,11 +178,9 @@ class FeaturesWindow:
def gpg_available(self): def gpg_available(self):
return gajim.HAVE_GPG return gajim.HAVE_GPG
def network_manager_available(self): def network_watcher_available(self):
if os.name == 'nt': import network_watcher
return False return network_watcher.supported
import network_manager_listener
return network_manager_listener.supported
def some_keyring_available(self): def some_keyring_available(self):
if os.name == 'nt': if os.name == 'nt':

View File

@ -2973,9 +2973,7 @@ class Interface:
self.remote_ctrl = None self.remote_ctrl = None
if gajim.config.get('networkmanager_support') and \ import network_watcher
dbus_support.supported:
import network_manager_listener
if dbus_support.supported: if dbus_support.supported:
import upower_listener import upower_listener

View File

@ -1,100 +0,0 @@
# -*- coding: utf-8 -*-
## src/network_manager_listener.py
##
## Copyright (C) 2006 Jeffrey C. Ollie <jeff AT ocjtech.us>
## Nikos Kouremenos <kourem AT gmail.com>
## Stefan Bethge <stefan AT lanpartei.de>
## Copyright (C) 2006-2014 Yann Leboulanger <asterix AT lagaule.org>
##
## 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 <http://www.gnu.org/licenses/>.
##
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

84
src/network_watcher.py Normal file
View File

@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
## src/network_watcher.py
##
## Copyright (C) 2017 Philipp Hoerist <philipp AT hoerist.com>
##
## 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 <http://www.gnu.org/licenses/>.
##
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')