Refactor UserLocation into own module

This commit is contained in:
Philipp Hörist 2018-07-05 19:14:03 +02:00
parent 14f088c2d9
commit bbf3a544e8
11 changed files with 129 additions and 112 deletions

View File

@ -122,7 +122,7 @@ class ChatControl(ChatControlBase):
self._pep_images['mood'] = self.xml.get_object('mood_image') self._pep_images['mood'] = self.xml.get_object('mood_image')
self._pep_images['activity'] = self.xml.get_object('activity_image') self._pep_images['activity'] = self.xml.get_object('activity_image')
self._pep_images['tune'] = self.xml.get_object('tune_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.update_all_pep_types()
self.show_avatar() self.show_avatar()
@ -584,8 +584,8 @@ class ChatControl(ChatControlBase):
return True return True
def on_location_eventbox_button_release_event(self, widget, event): def on_location_eventbox_button_release_event(self, widget, event):
if 'location' in self.contact.pep: if 'geoloc' in self.contact.pep:
location = self.contact.pep['location']._pep_specific_data location = self.contact.pep['geoloc']._pep_specific_data
if ('lat' in location) and ('lon' in location): if ('lat' in location) and ('lon' in location):
uri = 'https://www.openstreetmap.org/?' + \ uri = 'https://www.openstreetmap.org/?' + \
'mlat=%(lat)s&mlon=%(lon)s&zoom=16' % {'lat': location['lat'], 'mlat=%(lat)s&mlon=%(lon)s&zoom=16' % {'lat': location['lat'],

View File

@ -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_activity import UserActivity
from gajim.common.modules.user_tune import UserTune from gajim.common.modules.user_tune import UserTune
from gajim.common.modules.user_mood import UserMood 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.connection_handlers import *
from gajim.common.contacts import GC_Contact from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action from gajim.gtkgui_helpers import get_action
@ -633,7 +634,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.password = passwords.get_password(name) self.password = passwords.get_password(name)
self.music_track_info = 0 self.music_track_info = 0
self.location_info = {}
self.register_supported = False self.register_supported = False
self.pubsub_publish_options_supported = False self.pubsub_publish_options_supported = False
# Do we auto accept insecure connection # Do we auto accept insecure connection
@ -678,6 +679,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('UserActivity', UserActivity, self) self.register_module('UserActivity', UserActivity, self)
self.register_module('UserTune', UserTune, self) self.register_module('UserTune', UserTune, self)
self.register_module('UserMood', UserMood, self) self.register_module('UserMood', UserMood, self)
self.register_module('UserLocation', UserLocation, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE, app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received) self._nec_privacy_list_received)

View File

@ -42,7 +42,6 @@ from gi.repository import GLib
import nbxmpp import nbxmpp
from gajim.common import caps_cache as capscache from gajim.common import caps_cache as capscache
from gajim.common.pep import LOCATION_DATA
from gajim.common import helpers from gajim.common import helpers
from gajim.common import app from gajim.common import app
from gajim.common import dataforms from gajim.common import dataforms
@ -296,7 +295,6 @@ class ConnectionPEP(object):
def reset_awaiting_pep(self): def reset_awaiting_pep(self):
self.to_be_sent_nick = None self.to_be_sent_nick = None
self.to_be_sent_location = None
def send_awaiting_pep(self): def send_awaiting_pep(self):
""" """
@ -304,8 +302,6 @@ class ConnectionPEP(object):
""" """
if self.to_be_sent_nick: if self.to_be_sent_nick:
self.send_nick(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() self.reset_awaiting_pep()
def send_nickname(self, nick): def send_nickname(self, nick):
@ -326,27 +322,6 @@ class ConnectionPEP(object):
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_NICK, '0') 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 # basic connection handlers used here and in zeroconf
class ConnectionHandlersBase: class ConnectionHandlersBase:

View File

@ -150,6 +150,7 @@ class PEPEventType(IntEnum):
ACTIVITY = 0 ACTIVITY = 0
TUNE = 1 TUNE = 1
MOOD = 2 MOOD = 2
LOCATION = 3
ACTIVITIES = { ACTIVITIES = {
@ -330,6 +331,31 @@ MOODS = {
'worried': _('Worried') '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 = { SSLError = {
2: _("Unable to get issuer certificate"), 2: _("Unable to get issuer certificate"),

View File

@ -97,7 +97,7 @@ class LocationListener:
del new_data['timestamp'] del new_data['timestamp']
if last_data == new_data: if last_data == new_data:
continue continue
app.connections[acct].send_location(self._data) app.connections[acct].get_module('UserLocation').send(self._data)
self.location_info = self._data.copy() self.location_info = self._data.copy()
def _timestamp_to_utc(self, timestamp): def _timestamp_to_utc(self, timestamp):

View File

@ -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 <http://www.gnu.org/licenses/>.
# 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<b>%(tag)s</b>: %(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

View File

@ -23,32 +23,6 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>. ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
## ##
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 import logging
log = logging.getLogger('gajim.c.pep') log = logging.getLogger('gajim.c.pep')
@ -136,48 +110,6 @@ class UserNicknamePEP(AbstractPEP):
app.nicks[account] = self._pep_specific_data 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<b>%(tag)s</b>: %(text)s' % \
{'tag': tag.capitalize(), 'text': text}
return location_string.strip()
class AvatarNotificationPEP(AbstractPEP): class AvatarNotificationPEP(AbstractPEP):
'''XEP-0084: Avatars''' '''XEP-0084: Avatars'''
@ -222,4 +154,4 @@ class AvatarNotificationPEP(AbstractPEP):
SUPPORTED_PERSONAL_USER_EVENTS = [ SUPPORTED_PERSONAL_USER_EVENTS = [
UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP] UserNicknamePEP, AvatarNotificationPEP]

View File

@ -28,7 +28,6 @@
## ##
import xml.sax.saxutils import xml.sax.saxutils
import gi
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Gdk from gi.repository import Gdk
from gi.repository import GdkPixbuf from gi.repository import GdkPixbuf
@ -50,7 +49,6 @@ log = logging.getLogger('gajim.gtkgui_helpers')
from gajim.common import i18n from gajim.common import i18n
from gajim.common import app from gajim.common import app
from gajim.common import pep
from gajim.common import configpaths from gajim.common import configpaths
from gajim.common.const import PEPEventType, ACTIVITIES, MOODS from gajim.common.const import PEPEventType, ACTIVITIES, MOODS
from gajim.filechoosers import AvatarSaveDialog from gajim.filechoosers import AvatarSaveDialog
@ -651,7 +649,7 @@ def get_pep_as_pixbuf(pep_class):
return load_activity_icon(activity).get_pixbuf() return load_activity_icon(activity).get_pixbuf()
else: else:
return load_activity_icon('unknown').get_pixbuf() 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) icon = get_icon_pixmap('applications-internet', quiet=True)
if not icon: if not icon:
icon = get_icon_pixmap('gajim-earth') icon = get_icon_pixmap('gajim-earth')

View File

@ -97,7 +97,6 @@ from gajim.common.connection_handlers_events import (
HTTPUploadProgressEvent) HTTPUploadProgressEvent)
from gajim.common.connection import Connection from gajim.common.connection import Connection
from gajim.common.file_props import FilesProp from gajim.common.file_props import FilesProp
from gajim.common import pep
from gajim import emoticons from gajim import emoticons
from gajim.common.const import AvatarSize, SSLError, PEPEventType from gajim.common.const import AvatarSize, SSLError, PEPEventType
from gajim.common.const import ACTIVITIES, MOODS from gajim.common.const import ACTIVITIES, MOODS
@ -2501,7 +2500,7 @@ class Interface:
get_pixbuf() get_pixbuf()
else: else:
return gtkgui_helpers.load_activity_icon('unknown').get_pixbuf() 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', icon = gtkgui_helpers.get_icon_pixmap('applications-internet',
quiet=True) quiet=True)
return icon return icon

View File

@ -1090,10 +1090,10 @@ class RosterWindow:
else: else:
self.model[child_iter][Column.TUNE_PIXBUF] = empty_pixbuf 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: pep_dict:
self.model[child_iter][Column.LOCATION_PIXBUF] = \ 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: else:
self.model[child_iter][Column.LOCATION_PIXBUF] = empty_pixbuf self.model[child_iter][Column.LOCATION_PIXBUF] = empty_pixbuf
@ -1354,7 +1354,7 @@ class RosterWindow:
return app.config.get('show_activity_in_roster') return app.config.get('show_activity_in_roster')
elif pep_type == 'tune': elif pep_type == 'tune':
return app.config.get('show_tunes_in_roster') return app.config.get('show_tunes_in_roster')
elif pep_type == 'location': elif pep_type == 'geoloc':
return app.config.get('show_location_in_roster') return app.config.get('show_location_in_roster')
else: else:
return False return False
@ -3610,7 +3610,7 @@ class RosterWindow:
if active: if active:
location_listener.enable() location_listener.enable()
else: else:
app.connections[account].retract_location() app.connections[account].get_module('UserLocation').retract()
helpers.update_optional_features(account) helpers.update_optional_features(account)
@ -5728,7 +5728,7 @@ class RosterWindow:
self.renderers_propertys ={} self.renderers_propertys ={}
self._pep_type_to_model_column = {'mood': Column.MOOD_PIXBUF, self._pep_type_to_model_column = {'mood': Column.MOOD_PIXBUF,
'activity': Column.ACTIVITY_PIXBUF, 'tune': Column.TUNE_PIXBUF, 'activity': Column.ACTIVITY_PIXBUF, 'tune': Column.TUNE_PIXBUF,
'location': Column.LOCATION_PIXBUF} 'geoloc': Column.LOCATION_PIXBUF}
renderer_text = Gtk.CellRendererText() renderer_text = Gtk.CellRendererText()
self.renderers_propertys[renderer_text] = ('ellipsize', self.renderers_propertys[renderer_text] = ('ellipsize',
@ -5761,7 +5761,7 @@ class RosterWindow:
'pixbuf', Column.TUNE_PIXBUF, 'pixbuf', Column.TUNE_PIXBUF,
self._fill_pep_pixbuf_renderer, Column.TUNE_PIXBUF), self._fill_pep_pixbuf_renderer, Column.TUNE_PIXBUF),
('location', Gtk.CellRendererPixbuf(), False, ('geoloc', Gtk.CellRendererPixbuf(), False,
'pixbuf', Column.LOCATION_PIXBUF, 'pixbuf', Column.LOCATION_PIXBUF,
self._fill_pep_pixbuf_renderer, Column.LOCATION_PIXBUF)) self._fill_pep_pixbuf_renderer, Column.LOCATION_PIXBUF))

View File

@ -577,8 +577,8 @@ class RosterTooltip(Gtk.Window, StatusTable):
self.tune.show() self.tune.show()
self.tune_label.show() self.tune_label.show()
if 'location' in contact.pep: if 'geoloc' in contact.pep:
location = contact.pep['location'].asMarkupText() location = contact.pep['geoloc'].asMarkupText()
self.location.set_markup(location) self.location.set_markup(location)
self.location.show() self.location.show()
self.location_label.show() self.location_label.show()