diff --git a/gajim/chat_control.py b/gajim/chat_control.py
index 9581e8eed..0a9b9dd11 100644
--- a/gajim/chat_control.py
+++ b/gajim/chat_control.py
@@ -122,7 +122,7 @@ class ChatControl(ChatControlBase):
self._pep_images['mood'] = self.xml.get_object('mood_image')
self._pep_images['activity'] = self.xml.get_object('activity_image')
self._pep_images['tune'] = self.xml.get_object('tune_image')
- self._pep_images['location'] = self.xml.get_object('location_image')
+ self._pep_images['geoloc'] = self.xml.get_object('location_image')
self.update_all_pep_types()
self.show_avatar()
@@ -584,8 +584,8 @@ class ChatControl(ChatControlBase):
return True
def on_location_eventbox_button_release_event(self, widget, event):
- if 'location' in self.contact.pep:
- location = self.contact.pep['location']._pep_specific_data
+ if 'geoloc' in self.contact.pep:
+ location = self.contact.pep['geoloc']._pep_specific_data
if ('lat' in location) and ('lon' in location):
uri = 'https://www.openstreetmap.org/?' + \
'mlat=%(lat)s&mlon=%(lon)s&zoom=16' % {'lat': location['lat'],
diff --git a/gajim/common/connection.py b/gajim/common/connection.py
index 7f134bb42..1b69f49d8 100644
--- a/gajim/common/connection.py
+++ b/gajim/common/connection.py
@@ -81,6 +81,7 @@ from gajim.common.modules.user_avatar import UserAvatar
from gajim.common.modules.user_activity import UserActivity
from gajim.common.modules.user_tune import UserTune
from gajim.common.modules.user_mood import UserMood
+from gajim.common.modules.user_location import UserLocation
from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action
@@ -633,7 +634,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.password = passwords.get_password(name)
self.music_track_info = 0
- self.location_info = {}
+
self.register_supported = False
self.pubsub_publish_options_supported = False
# Do we auto accept insecure connection
@@ -678,6 +679,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('UserActivity', UserActivity, self)
self.register_module('UserTune', UserTune, self)
self.register_module('UserMood', UserMood, self)
+ self.register_module('UserLocation', UserLocation, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py
index d5c05a31e..631587d71 100644
--- a/gajim/common/connection_handlers.py
+++ b/gajim/common/connection_handlers.py
@@ -42,7 +42,6 @@ from gi.repository import GLib
import nbxmpp
from gajim.common import caps_cache as capscache
-from gajim.common.pep import LOCATION_DATA
from gajim.common import helpers
from gajim.common import app
from gajim.common import dataforms
@@ -296,7 +295,6 @@ class ConnectionPEP(object):
def reset_awaiting_pep(self):
self.to_be_sent_nick = None
- self.to_be_sent_location = None
def send_awaiting_pep(self):
"""
@@ -304,8 +302,6 @@ class ConnectionPEP(object):
"""
if self.to_be_sent_nick:
self.send_nick(self.to_be_sent_nick)
- if self.to_be_sent_location:
- self.send_location(self.to_be_sent_location)
self.reset_awaiting_pep()
def send_nickname(self, nick):
@@ -326,27 +322,6 @@ class ConnectionPEP(object):
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_NICK, '0')
- def send_location(self, info):
- if self.connected == 1:
- # We are connecting, keep location in mem and send it when we'll be
- # connected
- self.to_be_sent_location = info
- return
- if not self.pep_supported:
- return
- item = nbxmpp.Node('geoloc', {'xmlns': nbxmpp.NS_LOCATION})
- for field in LOCATION_DATA:
- if info.get(field, None):
- i = item.addChild(field)
- i.addData(info[field])
- self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_LOCATION, item, '0')
-
- def retract_location(self):
- if not self.pep_supported:
- return
- self.send_location({})
- # not all client support new XEP, so we still retract
- self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_LOCATION, '0')
# basic connection handlers used here and in zeroconf
class ConnectionHandlersBase:
diff --git a/gajim/common/const.py b/gajim/common/const.py
index 40dedafcd..5397bded9 100644
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -150,6 +150,7 @@ class PEPEventType(IntEnum):
ACTIVITY = 0
TUNE = 1
MOOD = 2
+ LOCATION = 3
ACTIVITIES = {
@@ -330,6 +331,31 @@ MOODS = {
'worried': _('Worried')
}
+LOCATION_DATA = {
+ 'accuracy': _('accuracy'),
+ 'alt': _('alt'),
+ 'area': _('area'),
+ 'bearing': _('bearing'),
+ 'building': _('building'),
+ 'country': _('country'),
+ 'countrycode': _('countrycode'),
+ 'datum': _('datum'),
+ 'description': _('description'),
+ 'error': _('error'),
+ 'floor': _('floor'),
+ 'lat': _('lat'),
+ 'locality': _('locality'),
+ 'lon': _('lon'),
+ 'postalcode': _('postalcode'),
+ 'region': _('region'),
+ 'room': _('room'),
+ 'speed': _('speed'),
+ 'street': _('street'),
+ 'text': _('text'),
+ 'timestamp': _('timestamp'),
+ 'uri': _('URI')
+}
+
SSLError = {
2: _("Unable to get issuer certificate"),
diff --git a/gajim/common/location_listener.py b/gajim/common/location_listener.py
index e40e9d4fb..d622f1970 100644
--- a/gajim/common/location_listener.py
+++ b/gajim/common/location_listener.py
@@ -97,7 +97,7 @@ class LocationListener:
del new_data['timestamp']
if last_data == new_data:
continue
- app.connections[acct].send_location(self._data)
+ app.connections[acct].get_module('UserLocation').send(self._data)
self.location_info = self._data.copy()
def _timestamp_to_utc(self, timestamp):
diff --git a/gajim/common/modules/user_location.py b/gajim/common/modules/user_location.py
new file mode 100644
index 000000000..803174c1c
--- /dev/null
+++ b/gajim/common/modules/user_location.py
@@ -0,0 +1,85 @@
+# 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 .
+
+# XEP-0080: User Location
+
+import logging
+
+import nbxmpp
+from gi.repository import GLib
+
+from gajim.common.const import PEPEventType, LOCATION_DATA
+from gajim.common.exceptions import StanzaMalformed
+from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+
+log = logging.getLogger('gajim.c.m.user_location')
+
+
+class UserLocationData(AbstractPEPData):
+
+ type_ = PEPEventType.LOCATION
+
+ def __init__(self, mood):
+ self._pep_specific_data = mood
+
+ def asMarkupText(self):
+ location = self._pep_specific_data
+ location_string = ''
+
+ for entry in location.keys():
+ text = location[entry]
+ text = GLib.markup_escape_text(text)
+ # Translate standard location tag
+ tag = LOCATION_DATA.get(entry, entry)
+ location_string += '\n%(tag)s: %(text)s' % {
+ 'tag': tag.capitalize(), 'text': text}
+
+ return location_string.strip()
+
+
+class UserLocation(AbstractPEPModule):
+
+ name = 'geoloc'
+ namespace = nbxmpp.NS_LOCATION
+ pep_class = UserLocationData
+ store_publish = True
+ _log = log
+
+ def __init__(self, con):
+ AbstractPEPModule.__init__(self, con, con.name)
+
+ self.handlers = []
+
+ def _extract_info(self, item):
+ location_dict = {}
+ location_tag = item.getTag('geoloc', namespace=nbxmpp.NS_LOCATION)
+ if location_tag is None:
+ raise StanzaMalformed('No geoloc node')
+
+ for child in location_tag.getChildren():
+ name = child.getName().strip()
+ data = child.getData().strip()
+ if child.getName() in LOCATION_DATA:
+ location_dict[name] = data
+
+ return location_dict or None
+
+ def _build_node(self, data):
+ item = nbxmpp.Node('geoloc', {'xmlns': nbxmpp.NS_LOCATION})
+ if data is None:
+ return item
+ for field in LOCATION_DATA:
+ if data.get(field, False):
+ item.addChild(field, payload=data[field])
+ return item
diff --git a/gajim/common/pep.py b/gajim/common/pep.py
index e5dd9e0d5..d64a295d7 100644
--- a/gajim/common/pep.py
+++ b/gajim/common/pep.py
@@ -23,32 +23,6 @@
## along with Gajim. If not, see .
##
-LOCATION_DATA = {
- 'accuracy': _('accuracy'),
- 'alt': _('alt'),
- 'area': _('area'),
- 'bearing': _('bearing'),
- 'building': _('building'),
- 'country': _('country'),
- 'countrycode': _('countrycode'),
- 'datum': _('datum'),
- 'description': _('description'),
- 'error': _('error'),
- 'floor': _('floor'),
- 'lat': _('lat'),
- 'locality': _('locality'),
- 'lon': _('lon'),
- 'postalcode': _('postalcode'),
- 'region': _('region'),
- 'room': _('room'),
- 'speed': _('speed'),
- 'street': _('street'),
- 'text': _('text'),
- 'timestamp': _('timestamp'),
- 'uri': _('URI')}
-
-from gi.repository import GLib
-
import logging
log = logging.getLogger('gajim.c.pep')
@@ -136,48 +110,6 @@ class UserNicknamePEP(AbstractPEP):
app.nicks[account] = self._pep_specific_data
-class UserLocationPEP(AbstractPEP):
- '''XEP-0080: User Location'''
-
- type_ = 'location'
- namespace = nbxmpp.NS_LOCATION
-
- def _extract_info(self, items):
- location_dict = {}
-
- for item in items.getTags('item'):
- location_tag = item.getTag('geoloc')
- if location_tag:
- for child in location_tag.getChildren():
- name = child.getName().strip()
- data = child.getData().strip()
- if child.getName() in LOCATION_DATA:
- location_dict[name] = data
-
- retracted = items.getTag('retract') or not location_dict
- return (location_dict, retracted)
-
- def _update_account(self, account):
- AbstractPEP._update_account(self, account)
- con = app.connections[account].location_info = \
- self._pep_specific_data
-
- def asMarkupText(self):
- assert not self._retracted
- location = self._pep_specific_data
- location_string = ''
-
- for entry in location.keys():
- text = location[entry]
- text = GLib.markup_escape_text(text)
- # Translate standard location tag
- tag = LOCATION_DATA.get(entry, entry)
- location_string += '\n%(tag)s: %(text)s' % \
- {'tag': tag.capitalize(), 'text': text}
-
- return location_string.strip()
-
-
class AvatarNotificationPEP(AbstractPEP):
'''XEP-0084: Avatars'''
@@ -222,4 +154,4 @@ class AvatarNotificationPEP(AbstractPEP):
SUPPORTED_PERSONAL_USER_EVENTS = [
- UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP]
+ UserNicknamePEP, AvatarNotificationPEP]
diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py
index d0e41c2f5..a583c47a1 100644
--- a/gajim/gtkgui_helpers.py
+++ b/gajim/gtkgui_helpers.py
@@ -28,7 +28,6 @@
##
import xml.sax.saxutils
-import gi
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf
@@ -50,7 +49,6 @@ log = logging.getLogger('gajim.gtkgui_helpers')
from gajim.common import i18n
from gajim.common import app
-from gajim.common import pep
from gajim.common import configpaths
from gajim.common.const import PEPEventType, ACTIVITIES, MOODS
from gajim.filechoosers import AvatarSaveDialog
@@ -651,7 +649,7 @@ def get_pep_as_pixbuf(pep_class):
return load_activity_icon(activity).get_pixbuf()
else:
return load_activity_icon('unknown').get_pixbuf()
- elif isinstance(pep_class, pep.UserLocationPEP):
+ elif pep_class == PEPEventType.LOCATION:
icon = get_icon_pixmap('applications-internet', quiet=True)
if not icon:
icon = get_icon_pixmap('gajim-earth')
diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py
index cd12c1746..cff6d9086 100644
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -97,7 +97,6 @@ from gajim.common.connection_handlers_events import (
HTTPUploadProgressEvent)
from gajim.common.connection import Connection
from gajim.common.file_props import FilesProp
-from gajim.common import pep
from gajim import emoticons
from gajim.common.const import AvatarSize, SSLError, PEPEventType
from gajim.common.const import ACTIVITIES, MOODS
@@ -2501,7 +2500,7 @@ class Interface:
get_pixbuf()
else:
return gtkgui_helpers.load_activity_icon('unknown').get_pixbuf()
- elif isinstance(pep_obj, pep.UserLocationPEP):
+ elif pep_obj == PEPEventType.LOCATION:
icon = gtkgui_helpers.get_icon_pixmap('applications-internet',
quiet=True)
return icon
diff --git a/gajim/roster_window.py b/gajim/roster_window.py
index f928b2abc..4876f2fbc 100644
--- a/gajim/roster_window.py
+++ b/gajim/roster_window.py
@@ -1090,10 +1090,10 @@ class RosterWindow:
else:
self.model[child_iter][Column.TUNE_PIXBUF] = empty_pixbuf
- if app.config.get('show_location_in_roster') and 'location' in \
+ if app.config.get('show_location_in_roster') and 'geoloc' in \
pep_dict:
self.model[child_iter][Column.LOCATION_PIXBUF] = \
- gtkgui_helpers.get_pep_as_pixbuf(pep_dict['location'])
+ gtkgui_helpers.get_pep_as_pixbuf(pep_dict['geoloc'])
else:
self.model[child_iter][Column.LOCATION_PIXBUF] = empty_pixbuf
@@ -1354,7 +1354,7 @@ class RosterWindow:
return app.config.get('show_activity_in_roster')
elif pep_type == 'tune':
return app.config.get('show_tunes_in_roster')
- elif pep_type == 'location':
+ elif pep_type == 'geoloc':
return app.config.get('show_location_in_roster')
else:
return False
@@ -3610,7 +3610,7 @@ class RosterWindow:
if active:
location_listener.enable()
else:
- app.connections[account].retract_location()
+ app.connections[account].get_module('UserLocation').retract()
helpers.update_optional_features(account)
@@ -5728,7 +5728,7 @@ class RosterWindow:
self.renderers_propertys ={}
self._pep_type_to_model_column = {'mood': Column.MOOD_PIXBUF,
'activity': Column.ACTIVITY_PIXBUF, 'tune': Column.TUNE_PIXBUF,
- 'location': Column.LOCATION_PIXBUF}
+ 'geoloc': Column.LOCATION_PIXBUF}
renderer_text = Gtk.CellRendererText()
self.renderers_propertys[renderer_text] = ('ellipsize',
@@ -5761,7 +5761,7 @@ class RosterWindow:
'pixbuf', Column.TUNE_PIXBUF,
self._fill_pep_pixbuf_renderer, Column.TUNE_PIXBUF),
- ('location', Gtk.CellRendererPixbuf(), False,
+ ('geoloc', Gtk.CellRendererPixbuf(), False,
'pixbuf', Column.LOCATION_PIXBUF,
self._fill_pep_pixbuf_renderer, Column.LOCATION_PIXBUF))
diff --git a/gajim/tooltips.py b/gajim/tooltips.py
index abfa641bd..6ab4a3af5 100644
--- a/gajim/tooltips.py
+++ b/gajim/tooltips.py
@@ -577,8 +577,8 @@ class RosterTooltip(Gtk.Window, StatusTable):
self.tune.show()
self.tune_label.show()
- if 'location' in contact.pep:
- location = contact.pep['location'].asMarkupText()
+ if 'geoloc' in contact.pep:
+ location = contact.pep['geoloc'].asMarkupText()
self.location.set_markup(location)
self.location.show()
self.location_label.show()