Skip to content
Snippets Groups Projects
set_location.py 9.61 KiB
Newer Older
Dicson's avatar
Dicson committed
# -*- coding: utf-8 -*-
##

from datetime import datetime
import time
import gtk
import os
import locale
import gettext

from plugins.gui import GajimPluginConfigDialog
from plugins import GajimPlugin
from plugins.helpers import log, log_calls
Dicson's avatar
Dicson committed
from common import gajim
Dicson's avatar
Dicson committed
from dialogs import InputDialog
Dicson's avatar
Dicson committed
locale_path = os.path.dirname(__file__) + '/locales'
locale.bindtextdomain('setlocation', locale_path)
try:
    gett = gettext.Catalog('setlocation', locale_path)
    _ = gett.gettext
except:
    pass

Dicson's avatar
Dicson committed

Dicson's avatar
Dicson committed
class SetLocationPlugin(GajimPlugin):
    @log_calls('SetLocationPlugin')
    def init(self):
        self.config_dialog = SetLocationPluginConfigDialog(self)
        self.config_default_values = {
Dicson's avatar
Dicson committed
            'alt': (1609, ''),
Dicson's avatar
Dicson committed
            'area': ('Central Park', ''),
Dicson's avatar
Dicson committed
            'building': ('The Empire State Building', ''),
Dicson's avatar
Dicson committed
            'country': ('United States', ''),
Dicson's avatar
Dicson committed
            'countrycode': ('US', ''),
            'description': ('Bill\'s house', ''),
            'floor': ('102', ''),
            'lat': (39.75, ''),
            'locality': ('New York City', ''),
            'lon': (-104.99, ''),
            'postalcode': ('10027', ''),
            'region': ('New York', ''),
            'room': ('Observatory', ''),
            'street': ('34th and Broadway', ''),
            'text': ('Northwest corner of the lobby', ''),
            'uri': ('http://beta.plazes.com/plazes/1940:jabber_inc', ''),
            'presets': ({'default': {}}, ''), }
Dicson's avatar
Dicson committed

    @log_calls('SetLocationPlugin')
    def activate(self):
        self._data = {}
        timestamp = time.time()
        timestamp = datetime.utcfromtimestamp(timestamp)
        timestamp = timestamp.strftime('%Y-%m-%dT%H:%MZ')
        self._data['timestamp'] = timestamp
        for name in self.config_default_values:
            self._data[name] = self.config[name]
        for acct in gajim.connections:
            if gajim.connections[acct].connected == 0:
                gajim.connections[acct].to_be_sent_location = self._data
            else:
                gajim.connections[acct].send_location(self._data)

    @log_calls('SetLocationPlugin')
    def deactivate(self):
        self._data = {}
        for acct in gajim.connections:
            gajim.connections[acct].send_location(self._data)


class SetLocationPluginConfigDialog(GajimPluginConfigDialog):
    def init(self):
        self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
                'config_dialog.ui')
        self.xml = gtk.Builder()
Dicson's avatar
Dicson committed
        self.xml.set_translation_domain('gajim_plugins')
Dicson's avatar
Dicson committed
        self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
                ['hbox1'])
        hbox = self.xml.get_object('hbox1')
        self.child.pack_start(hbox)
Dicson's avatar
Dicson committed
        self.xml.connect_signals(self)
        self.connect('hide', self.on_hide)
Dicson's avatar
Dicson committed
        self.is_active = None
Dicson's avatar
Dicson committed

Dicson's avatar
Dicson committed
        self.preset_combo = self.xml.get_object('preset_combobox')
        self.preset_liststore = gtk.ListStore(str)
        self.preset_combo.set_model(self.preset_liststore)
        cellrenderer = gtk.CellRendererText()
        self.preset_combo.pack_start(cellrenderer, True)
        self.preset_combo.add_attribute(cellrenderer, 'text', 0)
        #self.plugin.config['presets'] = {'default': {}}

    @log_calls('SetLocationPlugin.SetLocationPluginConfigDialog')
Dicson's avatar
Dicson committed
    def on_run(self):
Dicson's avatar
Dicson committed
        if not self.is_active:
            pres_keys = sorted(self.plugin.config['presets'].keys())
            for key in pres_keys:
                self.preset_liststore.append((key,))
Dicson's avatar
Dicson committed

        for name in self.plugin.config_default_values:
Dicson's avatar
Dicson committed
            if name == 'presets':
                continue
Dicson's avatar
Dicson committed
            widget = self.xml.get_object(name)
            widget.set_text(str(self.plugin.config[name]))

Dicson's avatar
Dicson committed
            if osmgpsmap.__version__ < '0.6':
                no_map = True
                log.debug('python-osmgpsmap < 0.6 detected')
            log.debug('python-osmgpsmap not detected')

        log.debug('python-osmgpsmap > 0.5 detected')
Dicson's avatar
Dicson committed
        if not no_map and not self.is_active:
            from layers import DummyLayer

            vbox = self.xml.get_object('vbox1')
            vbox.set_size_request(400, -1)

            self.osm = osmgpsmap.GpsMap()
            self.osm.layer_add(osmgpsmap.GpsMapOsd(show_dpad=True,
                show_zoom=True))
            self.osm.layer_add(DummyLayer())
            lat = float(self.plugin.config['lat'])
            lon = float(self.plugin.config['lon'])
            self.osm.set_center_and_zoom(lat, lon, 12)
            self.path_to_image = os.path.abspath(gtkgui_helpers.get_icon_path(
                'gajim', 16))
            self.icon = gtk.gdk.pixbuf_new_from_file_at_size(
                self.path_to_image, 16, 16)
            self.osm.connect('button_release_event', self.map_clicked)
Dicson's avatar
Dicson committed
            vbox.pack_start(self.osm, expand=True, fill=True, padding=6)
Dicson's avatar
Dicson committed
            label = gtk.Label(_(
                'Click the right mouse button to specify the location, \n'\
Dicson's avatar
Dicson committed
                'middle mouse button to show / hide the contacts on the map'))
Dicson's avatar
Dicson committed
            vbox.pack_start(label, expand=False, fill=False, padding=6)
            self.is_active = True
Dicson's avatar
Dicson committed
            self.osm_image = self.osm.image_add(lat, lon, self.icon)
            self.xml.get_object('lat').connect('changed', self.on_lon_changed)
            self.xml.get_object('lon').connect('changed', self.on_lon_changed)
Dicson's avatar
Dicson committed

    def on_hide(self, widget):
        for name in self.plugin.config_default_values:
Dicson's avatar
Dicson committed
            if name == 'presets':
                continue
            widget = self.xml.get_object(name)
            self.plugin.config[name] = widget.get_text()
            if self.plugin.active:
                self.plugin.activate()

    def map_clicked(self, osm, event):
        lat, lon = self.osm.get_event_location(event).get_degrees()
        if event.button == 3:
            self.osm.image_remove(self.osm_image)
            self.osm_image = self.osm.image_add(lat, lon, self.icon)
            self.xml.get_object('lat').set_text(str(lat))
            self.xml.get_object('lon').set_text(str(lon))
        if event.button == 2:
            self.show_contacts()
Dicson's avatar
Dicson committed

    def on_lon_changed(self, widget):
        try:
            lat = float(self.xml.get_object('lat').get_text())
            lon = float(self.xml.get_object('lon').get_text())
Dicson's avatar
Dicson committed
        except ValueError, e:
Dicson's avatar
Dicson committed
            return
        if not -85 < lat < 85 or not -180 < lon < 180:
            return
        self.osm.image_remove(self.osm_image)
        self.osm_image = self.osm.image_add(lat, lon, self.icon)
        self.osm.set_center(lat, lon)

    def show_contacts(self):
        if not self.images:
            data = {}
            accounts = gajim.contacts._accounts
            for account in accounts:
                if not gajim.account_is_connected(account):
                    continue
                for contact in accounts[account].contacts._contacts:
                    pep = accounts[account].contacts._contacts[contact][0].pep
                    if 'location' not in pep:
                        continue
                    lat = pep['location']._pep_specific_data.get('lat', None)
                    lon = pep['location']._pep_specific_data.get('lon', None)
                    if not lat or not lon:
                        continue
                    data[contact] = (lat, lon)
            for jid in data:
                path = gtkgui_helpers.get_path_to_generic_or_avatar(None,
                        jid=jid, suffix='')
                icon = gtk.gdk.pixbuf_new_from_file_at_size(path, 24, 24)
                image = self.osm.image_add(float(data[jid][0]),
                    float(data[jid][1]), icon)
                self.images.append(image)
        else:
            for image in self.images:
                self.osm.image_remove(image)
            self.images = []
Dicson's avatar
Dicson committed

    def on_preset_button_clicked(self, widget):
        def on_ok(preset_name):
            if preset_name == '':
                return
            preset = {}
            for name in self.plugin.config_default_values:
                if name == 'presets':
                    continue
                widget = self.xml.get_object(name)
                preset[name] = widget.get_text()
            preset = {preset_name: preset}
            presets = dict(self.plugin.config['presets'].items() + \
                preset.items())
            if preset_name not in self.plugin.config['presets'].keys():
                iter_ = self.preset_liststore.append((preset_name,))
Dicson's avatar
Dicson committed
            self.plugin.config['presets'] = presets
        self.set_modal(False)
        InputDialog(_('Save as Preset'), _('Please type a name for this preset'),
            is_modal=True, ok_handler=on_ok)

    def on_preset_combobox_changed(self, widget):
        model = widget.get_model()
        active = widget.get_active()
        if active < 0:
            self.xml.get_object('del_preset').set_sensitive(False)
Dicson's avatar
Dicson committed
            return
        pres_name = model[active][0].decode('utf-8')
        for name in self.plugin.config['presets'][pres_name].keys():
            widget = self.xml.get_object(name)
            widget.set_text(str(self.plugin.config['presets'][pres_name][name]))

        self.xml.get_object('del_preset').set_sensitive(True)

    def on_del_preset_clicked(self, widget):
        active = self.preset_combo.get_active()
        active_iter = self.preset_combo.get_active_iter()
        name = self.preset_liststore[active][0].decode('utf-8')
        presets = self.plugin.config['presets']
        del presets[name]
        self.plugin.config['presets'] = presets
        self.preset_liststore.remove(active_iter)