ability to get address / location from geoclue and send it via PEP
This commit is contained in:
		
							parent
							
								
									d15897e50e
								
							
						
					
					
						commit
						2a944e5404
					
				
					 7 changed files with 181 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -350,6 +350,7 @@ class Config:
 | 
			
		|||
			'answer_receipts' : [opt_bool, True, _('Answer to receipt requests')],
 | 
			
		||||
			'request_receipt' : [opt_bool, True, _('Sent receipt requests')],
 | 
			
		||||
			'publish_tune': [opt_bool, False],
 | 
			
		||||
			'publish_location': [opt_bool, False],
 | 
			
		||||
			'subscribe_mood': [opt_bool, True],
 | 
			
		||||
			'subscribe_activity': [opt_bool, True],
 | 
			
		||||
			'subscribe_tune': [opt_bool, True],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -653,8 +653,8 @@ class Connection(CommonConnection, ConnectionHandlers):
 | 
			
		|||
		self.last_history_time = {}
 | 
			
		||||
		self.password = passwords.get_password(name)
 | 
			
		||||
 | 
			
		||||
		# Used to ask privacy only once at connection
 | 
			
		||||
		self.music_track_info = 0
 | 
			
		||||
		self.location_info = {}
 | 
			
		||||
		self.pubsub_supported = False
 | 
			
		||||
		self.pubsub_publish_options_supported = False
 | 
			
		||||
		# Do we auto accept insecure connection
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1290,6 +1290,8 @@ def update_optional_features(account = None):
 | 
			
		|||
			gajim.gajim_optional_features[a].append(xmpp.NS_ACTIVITY + '+notify')
 | 
			
		||||
		if gajim.config.get_per('accounts', a, 'publish_tune'):
 | 
			
		||||
			gajim.gajim_optional_features[a].append(xmpp.NS_TUNE)
 | 
			
		||||
		if gajim.config.get_per('accounts', a, 'publish_location'):
 | 
			
		||||
			gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION)
 | 
			
		||||
		if gajim.config.get_per('accounts', a, 'subscribe_tune'):
 | 
			
		||||
			gajim.gajim_optional_features[a].append(xmpp.NS_TUNE + '+notify')
 | 
			
		||||
		if gajim.config.get_per('accounts', a, 'subscribe_nick'):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										116
									
								
								src/common/location_listener.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/common/location_listener.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
# -*- coding: utf-8 -*-
 | 
			
		||||
## src/common/location_listener.py
 | 
			
		||||
##
 | 
			
		||||
## Copyright (C) 2009 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
 | 
			
		||||
from common import pep
 | 
			
		||||
from common import dbus_support
 | 
			
		||||
if dbus_support.supported:
 | 
			
		||||
	import dbus
 | 
			
		||||
	import dbus.glib
 | 
			
		||||
 | 
			
		||||
class LocationListener:
 | 
			
		||||
	_instance = None
 | 
			
		||||
	@classmethod
 | 
			
		||||
	def get(cls):
 | 
			
		||||
		if cls._instance is None:
 | 
			
		||||
			cls._instance = cls()
 | 
			
		||||
		return cls._instance
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self._data = {}
 | 
			
		||||
 | 
			
		||||
	def get_data(self):
 | 
			
		||||
		self._get_address()
 | 
			
		||||
		self._get_position()
 | 
			
		||||
 | 
			
		||||
	def _get_address(self):
 | 
			
		||||
		bus = dbus.SessionBus()
 | 
			
		||||
		if 'org.freedesktop.Geoclue.Master' not in bus.list_names():
 | 
			
		||||
			self._on_geoclue_address_changed(0, {}, 0)
 | 
			
		||||
			return
 | 
			
		||||
		obj = bus.get_object('org.freedesktop.Geoclue.Master',
 | 
			
		||||
			'/org/freedesktop/Geoclue/Master')
 | 
			
		||||
		# get MasterClient path
 | 
			
		||||
		path = obj.Create()
 | 
			
		||||
		# get MasterClient
 | 
			
		||||
		cli = bus.get_object('org.freedesktop.Geoclue.Master', path)
 | 
			
		||||
		cli.AddressStart()
 | 
			
		||||
		# Check that there is a provider
 | 
			
		||||
		name, description, service, path = cli.GetAddressProvider()
 | 
			
		||||
		if path:
 | 
			
		||||
			timestamp, address, accuracy = cli.GetAddress()
 | 
			
		||||
			self._on_geoclue_address_changed(timestamp, address, accuracy)
 | 
			
		||||
 | 
			
		||||
	def _get_position(self):
 | 
			
		||||
		bus = dbus.SessionBus()
 | 
			
		||||
		if 'org.freedesktop.Geoclue.Master' not in bus.list_names():
 | 
			
		||||
			self._on_geoclue_position_changed([], 0, None, None, 0)
 | 
			
		||||
			return
 | 
			
		||||
		obj = bus.get_object('org.freedesktop.Geoclue.Master',
 | 
			
		||||
			'/org/freedesktop/Geoclue/Master')
 | 
			
		||||
		# get MasterClient path
 | 
			
		||||
		path = obj.Create()
 | 
			
		||||
		# get MasterClient
 | 
			
		||||
		cli = bus.get_object('org.freedesktop.Geoclue.Master', path)
 | 
			
		||||
		cli.PositionStart()
 | 
			
		||||
		# Check that there is a provider
 | 
			
		||||
		name, description, service, path = cli.GetPositionProvider()
 | 
			
		||||
		if path:
 | 
			
		||||
			fields, timestamp, lat, lon, accuray = cli.GetPosition()
 | 
			
		||||
			self._on_geoclue_position_changed(fields, timestamp, lat, lon,
 | 
			
		||||
				accuracy)
 | 
			
		||||
 | 
			
		||||
	def start(self):
 | 
			
		||||
		bus = dbus.SessionBus()
 | 
			
		||||
		# Geoclue
 | 
			
		||||
		bus.add_signal_receiver(self._on_geoclue_address_changed,
 | 
			
		||||
			'AddressChanged', 'org.freedesktop.Geoclue.Address')
 | 
			
		||||
		bus.add_signal_receiver(self._on_geoclue_address_changed,
 | 
			
		||||
			'PositionChanged', 'org.freedesktop.Geoclue.Position')
 | 
			
		||||
 | 
			
		||||
	def shut_down(self):
 | 
			
		||||
		pass
 | 
			
		||||
 | 
			
		||||
	def _on_geoclue_address_changed(self, timestamp, address, accuracy):
 | 
			
		||||
		# update data with info we just received
 | 
			
		||||
		for field in pep.LOCATION_DATA:
 | 
			
		||||
			self._data[field] = address.get(field, self._data.get(field, None))
 | 
			
		||||
		self._send_location()
 | 
			
		||||
 | 
			
		||||
	def _on_geoclue_position_changed(self, fields, timestamp, lat, lon,
 | 
			
		||||
	accuracy):
 | 
			
		||||
		# update data with info we just received
 | 
			
		||||
		if lat:
 | 
			
		||||
			self._data['lat'] = lat
 | 
			
		||||
		if lon:
 | 
			
		||||
			self._data['lon'] = lon
 | 
			
		||||
		self._send_location()
 | 
			
		||||
 | 
			
		||||
	def _send_location(self):
 | 
			
		||||
		accounts = gajim.connections.keys()
 | 
			
		||||
		for acct in accounts:
 | 
			
		||||
			if not gajim.account_is_connected(acct):
 | 
			
		||||
				continue
 | 
			
		||||
			if not gajim.config.get_per('accounts', acct, 'publish_location'):
 | 
			
		||||
				continue
 | 
			
		||||
			if gajim.connections[acct].location_info == self._data:
 | 
			
		||||
				continue
 | 
			
		||||
			gajim.connections[acct].send_location(self._data)
 | 
			
		||||
			gajim.connections[acct].location_info = self._data
 | 
			
		||||
| 
						 | 
				
			
			@ -468,6 +468,11 @@ class UserLocationPEP(AbstractPEP):
 | 
			
		|||
		retracted = items.getTag('retract') or not location_dict
 | 
			
		||||
		return (location_dict, retracted)
 | 
			
		||||
 | 
			
		||||
	def _update_account(self, account):
 | 
			
		||||
		AbstractPEP._update_account(self, account)
 | 
			
		||||
		con = gajim.connections[account].location_info = \
 | 
			
		||||
			self._pep_specific_data
 | 
			
		||||
 | 
			
		||||
	def asPixbufIcon(self):
 | 
			
		||||
		path = gtkgui_helpers.get_icon_path('gajim-earth')
 | 
			
		||||
		return gtk.gdk.pixbuf_new_from_file(path)
 | 
			
		||||
| 
						 | 
				
			
			@ -606,4 +611,19 @@ class ConnectionPEP(object):
 | 
			
		|||
		self.send_nickname(None)
 | 
			
		||||
		self._pubsub_connection.send_pb_retract('', xmpp.NS_NICK, '0')
 | 
			
		||||
 | 
			
		||||
	def send_location(self, info):
 | 
			
		||||
		if not self.pep_supported:
 | 
			
		||||
			return
 | 
			
		||||
		item = xmpp.Node('geoloc', {'xmlns': xmpp.NS_LOCATION})
 | 
			
		||||
		for field in LOCATION_DATA:
 | 
			
		||||
			if info.get(field, None):
 | 
			
		||||
				i = item.addChild(field)
 | 
			
		||||
				i.addData(info[field])
 | 
			
		||||
		self._pubsub_connection.send_pb_publish('', xmpp.NS_LOCATION, item, '0')
 | 
			
		||||
 | 
			
		||||
	def retract_location(self):
 | 
			
		||||
		if not self.pep_supported:
 | 
			
		||||
			return
 | 
			
		||||
		self._pubsub_connection.send_pb_retract('', xmpp.NS_LOCATION, '0')
 | 
			
		||||
 | 
			
		||||
# vim: se ts=3:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,7 @@ from common import gajim
 | 
			
		|||
from common import dbus_support
 | 
			
		||||
if dbus_support.supported:
 | 
			
		||||
	from music_track_listener import MusicTrackListener
 | 
			
		||||
	from common.location_listener import LocationListener
 | 
			
		||||
	import dbus
 | 
			
		||||
 | 
			
		||||
import gtkgui_helpers
 | 
			
		||||
| 
						 | 
				
			
			@ -1547,6 +1548,10 @@ class Interface:
 | 
			
		|||
		if gajim.connections[account].pep_supported and dbus_support.supported \
 | 
			
		||||
		and gajim.config.get_per('accounts', account, 'publish_tune'):
 | 
			
		||||
			self.enable_music_listener()
 | 
			
		||||
		# enable location listener
 | 
			
		||||
		if gajim.connections[account].pep_supported and dbus_support.supported \
 | 
			
		||||
		and gajim.config.get_per('accounts', account, 'publish_location'):
 | 
			
		||||
			self.enable_location_listener()
 | 
			
		||||
 | 
			
		||||
	def handle_event_metacontacts(self, account, tags_list):
 | 
			
		||||
		gajim.contacts.define_metacontacts(account, tags_list)
 | 
			
		||||
| 
						 | 
				
			
			@ -2785,6 +2790,15 @@ class Interface:
 | 
			
		|||
		listener.disconnect(self.music_track_changed_signal)
 | 
			
		||||
		self.music_track_changed_signal = None
 | 
			
		||||
 | 
			
		||||
	def enable_location_listener(self):
 | 
			
		||||
		listener = LocationListener.get()
 | 
			
		||||
		listener.get_data()
 | 
			
		||||
		listener.start()
 | 
			
		||||
 | 
			
		||||
	def disable_location_listener(self):
 | 
			
		||||
		listener = LocationListener.get()
 | 
			
		||||
		listener.shut_down()
 | 
			
		||||
 | 
			
		||||
	def music_track_changed(self, unused_listener, music_track_info, account=None):
 | 
			
		||||
		if not account:
 | 
			
		||||
			accounts = gajim.connections.keys()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3433,6 +3433,22 @@ class RosterWindow:
 | 
			
		|||
 | 
			
		||||
		helpers.update_optional_features(account)
 | 
			
		||||
 | 
			
		||||
	def on_publish_location_toggled(self, widget, account):
 | 
			
		||||
		active = widget.get_active()
 | 
			
		||||
		gajim.config.set_per('accounts', account, 'publish_location', active)
 | 
			
		||||
		if active:
 | 
			
		||||
			gajim.interface.enable_location_listener()
 | 
			
		||||
		else:
 | 
			
		||||
			gajim.connections[account].retract_location()
 | 
			
		||||
			# disable music listener only if no other account uses it
 | 
			
		||||
			for acc in gajim.connections:
 | 
			
		||||
				if gajim.config.get_per('accounts', acc, 'publish_location'):
 | 
			
		||||
					break
 | 
			
		||||
			else:
 | 
			
		||||
				gajim.interface.disable_location_listener()
 | 
			
		||||
 | 
			
		||||
		helpers.update_optional_features(account)
 | 
			
		||||
 | 
			
		||||
	def on_pep_services_menuitem_activate(self, widget, account):
 | 
			
		||||
		if 'pep_services' in gajim.interface.instances[account]:
 | 
			
		||||
			gajim.interface.instances[account]['pep_services'].window.present()
 | 
			
		||||
| 
						 | 
				
			
			@ -4993,6 +5009,8 @@ class RosterWindow:
 | 
			
		|||
			if gajim.connections[account].pep_supported:
 | 
			
		||||
				have_tune = gajim.config.get_per('accounts', account,
 | 
			
		||||
					'publish_tune')
 | 
			
		||||
				have_location = gajim.config.get_per('accounts', account,
 | 
			
		||||
					'publish_location')
 | 
			
		||||
				pep_submenu = gtk.Menu()
 | 
			
		||||
				pep_menuitem.set_submenu(pep_submenu)
 | 
			
		||||
				item = gtk.CheckMenuItem(_('Publish Tune'))
 | 
			
		||||
| 
						 | 
				
			
			@ -5003,6 +5021,15 @@ class RosterWindow:
 | 
			
		|||
					item.set_active(have_tune)
 | 
			
		||||
					item.connect('toggled', self.on_publish_tune_toggled, account)
 | 
			
		||||
 | 
			
		||||
				item = gtk.CheckMenuItem(_('Publish Location'))
 | 
			
		||||
				pep_submenu.append(item)
 | 
			
		||||
				if not dbus_support.supported:
 | 
			
		||||
					item.set_sensitive(False)
 | 
			
		||||
				else:
 | 
			
		||||
					item.set_active(have_location)
 | 
			
		||||
					item.connect('toggled', self.on_publish_location_toggled,
 | 
			
		||||
						account)
 | 
			
		||||
 | 
			
		||||
				pep_config = gtk.ImageMenuItem(_('Configure Services...'))
 | 
			
		||||
				item = gtk.SeparatorMenuItem()
 | 
			
		||||
				pep_submenu.append(item)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue