From bbf3a544e8b3bf76e68136ef31c0e822e18a0bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Thu, 5 Jul 2018 19:14:03 +0200 Subject: [PATCH] Refactor UserLocation into own module --- gajim/chat_control.py | 6 +- gajim/common/connection.py | 4 +- gajim/common/connection_handlers.py | 25 -------- gajim/common/const.py | 26 ++++++++ gajim/common/location_listener.py | 2 +- gajim/common/modules/user_location.py | 85 +++++++++++++++++++++++++++ gajim/common/pep.py | 70 +--------------------- gajim/gtkgui_helpers.py | 4 +- gajim/gui_interface.py | 3 +- gajim/roster_window.py | 12 ++-- gajim/tooltips.py | 4 +- 11 files changed, 129 insertions(+), 112 deletions(-) create mode 100644 gajim/common/modules/user_location.py 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()