Commit 942fda62 authored by Martin's avatar Martin

Imported upstream master from 2017-12-14

parent 72207b29
......@@ -14,7 +14,7 @@
### Optional Runtime Requirements
- python-pillow for support of webp avatars
- python3-pil (pillow) for support of webp avatars
- python3-crypto to enable End to end encryption
- python3-gnupg to enable GPG encryption
- For zeroconf (bonjour) you need dbus-glib, python-avahi
......
......@@ -177,10 +177,7 @@ class AccountsWindow(Gtk.ApplicationWindow):
def on_remove_account(self, button, account):
if app.events.get_events(account):
dialogs.ErrorDialog(
_('Unread events'),
_('Read all pending events before removing this account.'),
transient_for=self)
app.interface.raise_dialog('unread-events-on-remove')
return
if app.config.get_per('accounts', account, 'is_zeroconf'):
......@@ -361,10 +358,7 @@ class Account(Gtk.Box):
if (account in app.connections and
app.connections[account].connected > 0):
# connecting or connected
dialogs.ErrorDialog(
_('You are currently connected to the server'),
_('To disable the account, you must be disconnected.'),
transient_for=self.parent)
app.interface.raise_dialog('connected-on-disable-account')
switch.set_active(not state)
return
if state:
......
......@@ -364,10 +364,8 @@ class CommandWindow:
if self.data_form_widget.get_data_form():
df = self.data_form_widget.get_data_form()
if not df.is_valid():
dialogs.ErrorDialog(
_('Invalid Form'),
_('The form is not filled correctly.'),
transient_for=self.window)
app.interface.raise_dialog(
'invalid-form', transient_for=self.window)
self.data_form_widget.set_sensitive(True)
return
self.data_form_widget.data_form.type_ = 'submit'
......
......@@ -124,8 +124,7 @@ class AppActions():
account = param.get_string()
invisible_show = app.SHOW_LIST.index('invisible')
if app.connections[account].connected == invisible_show:
dialogs.ErrorDialog(_(
'You cannot join a group chat while you are invisible'))
app.interface.raise_dialog('join-while-invisible')
return
if 'join_gc' in interface.instances[account]:
interface.instances[account]['join_gc'].present()
......
......@@ -236,6 +236,8 @@ class ChatControl(ChatControlBase):
self._nec_chatstate_received)
app.ged.register_event_handler('caps-received', ged.GUI1,
self._nec_caps_received)
app.ged.register_event_handler('stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
# PluginSystem: adding GUI extension point for this ChatControl
# instance object
......@@ -811,6 +813,35 @@ class ChatControl(ChatControlBase):
app.plugin_manager.extension_point(
'encryption_dialog' + self.encryption, self)
def _message_sent(self, obj):
if obj.conn.name != self.account:
return
if obj.jid != self.contact.jid:
return
if not obj.message:
return
self.last_sent_msg = obj.stanza_id
id_ = obj.msg_iq.getID()
xep0184_id = None
if self.contact.jid != app.get_jid_from_account(self.account):
if app.config.get_per('accounts', self.account, 'request_receipt'):
xep0184_id = id_
if obj.label:
displaymarking = obj.label.getTag('displaymarking')
else:
displaymarking = None
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.print_conversation(obj.message, self.contact.jid, tim=obj.timestamp,
encrypted=obj.encrypted, xep0184_id=xep0184_id, xhtml=obj.xhtml,
displaymarking=displaymarking, msg_stanza_id=id_,
correct_id=obj.correct_id,
additional_data=obj.additional_data)
def send_message(self, message, keyID='', chatstate=None, xhtml=None,
process_commands=True, attention=False):
"""
......@@ -843,32 +874,9 @@ class ChatControl(ChatControlBase):
self._schedule_activity_timers()
def _on_sent(obj, msg_stanza, message, encrypted, xhtml, label):
id_ = msg_stanza.getID()
xep0184_id = None
if self.contact.jid != app.get_jid_from_account(self.account):
if app.config.get_per('accounts', self.account, 'request_receipt'):
xep0184_id = id_
if label:
displaymarking = label.getTag('displaymarking')
else:
displaymarking = None
if self.correcting:
self.correcting = False
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.print_conversation(message, self.contact.jid, tim=obj.timestamp,
encrypted=encrypted, xep0184_id=xep0184_id, xhtml=xhtml,
displaymarking=displaymarking, msg_stanza_id=id_,
correct_id=obj.correct_id,
additional_data=obj.additional_data)
ChatControlBase.send_message(self, message, keyID, type_='chat',
chatstate=chatstate_to_send, xhtml=xhtml, callback=_on_sent,
callback_args=[message, self.encryption, xhtml, self.get_seclabel()],
process_commands=process_commands,
attention=attention)
chatstate=chatstate_to_send, xhtml=xhtml,
process_commands=process_commands, attention=attention)
def on_cancel_session_negotiation(self):
msg = _('Session negotiation cancelled')
......@@ -1138,6 +1146,8 @@ class ChatControl(ChatControlBase):
self._nec_chatstate_received)
app.ged.remove_event_handler('caps-received', ged.GUI1,
self._nec_caps_received)
app.ged.remove_event_handler('stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
self.unsubscribe_events()
......
......@@ -694,8 +694,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
if send_message and app.connections[self.account].connected < 2:
# we are not connected
dialogs.ErrorDialog(_('A connection is not available'),
_('Your message can not be sent until you are connected.'))
app.interface.raise_dialog('not-connected-while-sending')
elif send_message:
self.send_message(message, xhtml=xhtml)
else:
......@@ -743,17 +742,13 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
return label
def send_message(self, message, keyID='', type_='chat', chatstate=None,
resource=None, xhtml=None, callback=None, callback_args=None,
process_commands=True, attention=False):
resource=None, xhtml=None, process_commands=True, attention=False):
"""
Send the given message to the active tab. Doesn't return None if error
"""
if not message or message == '\n':
return None
if callback_args is None:
callback_args = []
if process_commands and self.process_as_command(message):
return
......@@ -767,11 +762,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
label = self.get_seclabel()
def _cb(obj, msg, cb, *cb_args):
self.last_sent_msg = obj.stanza_id
if cb:
cb(obj, msg, *cb_args)
if self.correcting and self.last_sent_msg:
correct_id = self.last_sent_msg
else:
......@@ -781,8 +771,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
account=self.account, jid=self.contact.jid, message=message,
keyID=keyID, type_=type_, chatstate=chatstate,
resource=resource, user_nick=self.user_nick, xhtml=xhtml,
label=label, callback=_cb, callback_args=[callback] + callback_args,
control=self, attention=attention, correct_id=correct_id,
label=label, control=self, attention=attention, correct_id=correct_id,
automatic_message=False, encryption=self.encryption))
# Record the history of sent messages
......
......@@ -275,19 +275,15 @@ class CommonConnection:
try:
self.check_jid(jid)
except helpers.InvalidFormat:
app.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error', pri_txt=_('Invalid JID'),
sec_txt=_('It is not possible to send a message '
'to %s, this JID is not valid.') % jid))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invalid-jid', args=jid))
return
else:
try:
self.check_jid(obj.jid)
except helpers.InvalidFormat:
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Invalid JID'), sec_txt=_(
'It is not possible to send a message to %s, this JID is not '
'valid.') % obj.jid))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invalid-jid', args=obj.jid))
return
if obj.message and not obj.xhtml and app.config.get(
......@@ -937,11 +933,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.disconnect(on_purpose=True)
return
if not data[1]: # wrong answer
app.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error', pri_txt=_('Invalid answer'),
sec_txt=_('Transport %(name)s answered wrongly to '
'register request: %(error)s') % {'name': data[0],
'error': data[3]}))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invalid-answer',
kwargs={'name': data[0], 'error': data[3]}))
return
is_form = data[2]
conf = data[1]
......@@ -1063,11 +1057,9 @@ class Connection(CommonConnection, ConnectionHandlers):
try:
helpers.idn_to_ascii(custom_h)
except Exception:
app.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error',
pri_txt=_('Wrong Custom Hostname'),
sec_txt='Wrong custom hostname "%s". Ignoring it.' \
% custom_h))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invalid-custom-hostname',
args=custom_h))
use_custom = False
# create connection if it doesn't already exist
......@@ -1584,11 +1576,8 @@ class Connection(CommonConnection, ConnectionHandlers):
app.nec.push_incoming_event(PrivacyListRemovedEvent(None,
conn=self, list_name=privacy_list))
else:
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Error while removing privacy '
'list'), sec_txt=_('Privacy list %s has not been removed. '
'It is maybe active in one of your connected resources. '
'Deactivate it and try again.') % privacy_list))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='privacy-list-error', args=privacy_list))
nbxmpp.features_nb.delPrivacyList(self.connection, privacy_list,
_on_del_privacy_list_result)
......@@ -1771,10 +1760,8 @@ class Connection(CommonConnection, ConnectionHandlers):
if not self.privacy_rules_supported:
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show=app.SHOW_LIST[self.connected]))
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Invisibility not supported'),
sec_txt=_('Account %s doesn\'t support invisibility.') % \
self.name))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invisibility-not-supported', args=self.name))
return
# If we are already connected, and privacy rules are supported, send
# offline presence first as it's required by XEP-0126
......@@ -1896,10 +1883,8 @@ class Connection(CommonConnection, ConnectionHandlers):
self.disconnect(on_purpose=True)
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show='offline'))
app.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error', pri_txt=_('Invisibility not '
'supported'), sec_txt=_('Account %s doesn\'t support '
'invisibility.') % self.name))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invisibility-not-supported', args=self.name))
return
if self.blocking_supported:
self._request_blocking()
......@@ -2076,6 +2061,9 @@ class Connection(CommonConnection, ConnectionHandlers):
if encryption:
app.plugin_manager.extension_point(
'encrypt' + encryption, self, obj, self.send_message)
if not obj.encrypted:
# Dont propagate event
return True
else:
self.send_message(obj)
......@@ -2087,8 +2075,6 @@ class Connection(CommonConnection, ConnectionHandlers):
None, conn=self, jid=obj.jid, message=obj.message, keyID=obj.keyID,
chatstate=obj.chatstate, automatic_message=obj.automatic_message,
stanza_id=obj.stanza_id, additional_data=obj.additional_data))
if obj.callback:
obj.callback(obj, obj.msg_iq, *obj.callback_args)
if isinstance(obj.jid, list):
for j in obj.jid:
......@@ -2717,8 +2703,6 @@ class Connection(CommonConnection, ConnectionHandlers):
None, conn=self, jid=obj.jid, message=obj.message, keyID=None,
chatstate=None, automatic_message=obj.automatic_message,
stanza_id=obj.stanza_id, additional_data=obj.additional_data))
if obj.callback:
obj.callback(obj)
def send_gc_subject(self, jid, subject):
if not app.account_is_connected(self.name):
......@@ -2917,12 +2901,9 @@ class Connection(CommonConnection, ConnectionHandlers):
if result.getID() == id_:
on_remove_success(True)
return
app.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error',
pri_txt=_('Unregister failed'),
sec_txt=_('Unregistration with server %(server)s '
'failed: %(error)s') % {'server': hostname,
'error': result.getErrorMsg()}))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='unregister-error',
kwargs={'server': hostname, 'error': result.getErrorMsg()}))
on_remove_success(False)
con.RegisterHandler('iq', _on_answer, 'result', system=True)
con.SendAndWaitForResponse(iq)
......
......@@ -118,10 +118,8 @@ class ConnectionDisco:
callback()
return
app.nec.push_incoming_event(
InformationEvent(None, conn=self,
level='error',
pri_txt=_('Unable to join Groupchat'),
sec_txt=error))
InformationEvent(
None, dialog_name='unable-join-groupchat', args=error))
def request_register_agent_info(self, agent):
if not self.connection or self.connected < 2:
......@@ -138,9 +136,8 @@ class ConnectionDisco:
def _agent_registered_cb(self, con, resp, agent):
if resp.getType() == 'result':
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='info', pri_txt=_('Registration succeeded'), sec_txt=_(
'Registration with agent %s succeeded') % agent))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='agent-register-success', args=agent))
self.request_subscription(agent, auto_auth=True)
self.agent_registrations[agent]['roster_push'] = True
if self.agent_registrations[agent]['sub_received']:
......@@ -148,11 +145,11 @@ class ConnectionDisco:
p = self.add_sha(p)
self.connection.send(p)
if resp.getType() == 'error':
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Registration failed'), sec_txt=_(
'Registration with agent %(agent)s failed with error %(error)s:'
' %(error_msg)s') % {'agent': agent, 'error': resp.getError(),
'error_msg': resp.getErrorMsg()}))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='agent-register-error',
kwargs={'agent': agent,
'error': resp.getError(),
'error_msg': resp.getErrorMsg()}))
def register_agent(self, agent, info, is_form=False):
if not self.connection or self.connected < 2:
......
......@@ -2845,6 +2845,7 @@ class MessageOutgoingEvent(nec.NetworkOutgoingEvent):
self.correct_id = None
self.automatic_message = True
self.encryption = ''
self.encrypted = False
def get_full_jid(self):
if self.resource:
......@@ -2905,8 +2906,18 @@ class InformationEvent(nec.NetworkIncomingEvent):
base_network_events = []
def init(self):
self.args = None
self.kwargs = {}
self.dialog_name = None
self.popup = True
def generate(self):
if self.args is None:
self.args = ()
else:
self.args = (self.args,)
return True
class BlockingEvent(nec.NetworkIncomingEvent):
name = 'blocking'
base_network_events = []
......
......@@ -228,11 +228,9 @@ class JingleRTPContent(JingleContent):
if not self.stream_failed_once:
app.nec.push_incoming_event(
InformationEvent(
None, conn=self.session.connection, level='error',
pri_txt=_('GStreamer error'),
sec_txt=_('Error: %(error)s\nDebug: %(debug)s' % {
'error': message.get_structure().get_value('gerror'),
'debug': message.get_structure().get_value('debug')})))
None, dialog_name='gstreamer-error',
kwargs={'error': message.get_structure().get_value('gerror'),
'debug': message.get_structure().get_value('debug')}))
sink_pad = self.p2psession.get_property('sink-pad')
......
......@@ -401,9 +401,8 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
self._add_streamhosts_to_query(query, sender, port, my_ips)
except socket.gaierror:
from gajim.common.connection_handlers_events import InformationEvent
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Wrong host'),
sec_txt=_('Invalid local address? :-O')))
app.nec.push_incoming_event(
InformationEvent(None, dialog_name='wrong-host')),
def _add_addiditional_streamhosts_to_query(self, query, file_props):
sender = file_props.sender
......
......@@ -189,9 +189,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
alt_name=alt_name))
def _on_error(self, message):
app.nec.push_incoming_event(InformationEvent(None, conn=self,
level='error', pri_txt=_('Avahi error'), sec_txt=_('%s\nLink-local '
'messaging might not work properly.') % message))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='avahi-error', args=message))
def connect(self, show='online', msg=''):
self.get_config_values_or_default()
......@@ -343,8 +342,6 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
jid=obj.jid, message=obj.message, keyID=obj.keyID,
automatic_message=obj.automatic_message, chatstate=None,
stanza_id=stanza_id))
if obj.callback:
obj.callback(obj.msg_iq, *obj.callback_args)
self.log_message(obj, obj.jid)
......@@ -353,6 +350,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
app.nec.push_incoming_event(MessageErrorEvent(None, conn=self,
fjid=obj.jid, error_code=-1, error_msg=reason, msg=None,
time_=None, session=obj.session))
# Dont propagate event
return True
ret = self.connection.send(
obj.msg_iq, obj.message is not None,
......@@ -364,6 +363,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
fjid=obj.jid, error_code=-1, error_msg=_(
'Contact is offline. Your message could not be sent.'),
msg=None, time_=None, session=obj.session))
# Dont propagate event
return True
def send_stanza(self, stanza):
# send a stanza untouched
......
......@@ -37,6 +37,7 @@ from gajim import dialogs
from gajim.common import dataforms
from gajim.common import helpers
from gajim.common import app
import itertools
......@@ -641,12 +642,10 @@ class SingleForm(Gtk.Table, object):
try:
newtext = helpers.parse_jid(newtext)
except helpers.InvalidFormat as s:
dialogs.ErrorDialog(_('Invalid JID'), str(s))
app.interface.raise_dialog('invalid-jid-with-error', str(s))
return
if newtext in field.values:
dialogs.ErrorDialog(
_('JID already in list'),
_('The JID you entered is already in the list. Choose another one.'))
app.interface.raise_dialog('jid-in-list')
GLib.idle_add(treeview.set_cursor, path)
return
model[path][0]=newtext
......
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Philipp Hörist <philipp AT hoerist.com>
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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 collections import namedtuple
from gi.repository import GLib
from gajim.common.app import app
from gajim.dialogs import ErrorDialog
from gajim.dialogs import InformationDialog
Message = namedtuple('Message', ['title', 'text', 'dialog'])
messages = {
'start-chat-not-connected': Message(
_('You are not connected to the server'),
_('You can not start a new conversation unless you are connected.'),
ErrorDialog),
'invalid-jid-with-error': Message(
_('Invalid JID'),
'%s',
ErrorDialog),
'invalid-jid': Message(
_('Invalid JID'),
_('It is not possible to send a message '
'to %s, this JID is not valid.'),
ErrorDialog),
'unread-events-on-remove-account': Message(
_('Unread events'),
_('Read all pending events before removing this account.'),
ErrorDialog),
'connected-on-disable-account': Message(
_('You are currently connected to the server'),
_('To disable the account, you must be disconnected.'),
ErrorDialog),
'invalid-form': Message(
_('Invalid Form'),
_('The form is not filled correctly.'),
ErrorDialog),
'join-while-invisible': Message(
_('Invisible'),
_('You cannot join a group chat while you are invisible'),
ErrorDialog),
'not-connected-while-sending': Message(
_('A connection is not available'),
_('Your message can not be sent until you are connected.'),
ErrorDialog),
'jid-in-list': Message(
_('JID already in list'),
_('The JID you entered is already in the list. Choose another one.'),
ErrorDialog),
'invalid-answer': Message(
_('Invalid answer'),
_('Transport %(name)s answered wrongly to '
'register request: %(error)s'),
ErrorDialog),
'invalid-custom-hostname': Message(
_('Wrong Custom Hostname'),
_('Wrong custom hostname "%s". Ignoring it.'),
ErrorDialog),
'privacy-list-error': Message(
_('Error while removing privacy list'),
_('Privacy list %s has not been removed. '
'It is maybe active in one of your connected resources. '
'Deactivate it and try again.'),
ErrorDialog),
'invisibility-not-supported': Message(
_('Invisibility not supported'),
_('Account %s doesn\'t support invisibility.'),
ErrorDialog),
'unregister-error': Message(
_('Unregister failed'),
_('Unregistration with server %(server)s failed: %(error)s'),
ErrorDialog),
'agent-register-success': Message(
_('Registration succeeded'),
_('Registration with agent %s succeeded'),
InformationDialog),
'agent-register-error': Message(
_('Registration failed'),
_('Registration with agent %(agent)s failed with error %(error)s: '
'%(error_msg)s'),
ErrorDialog),
'unable-join-groupchat': Message(
_('Unable to join Groupchat'),
'%s',
ErrorDialog),
'gstreamer-error': Message(
_('GStreamer error'),
_('Error: %(error)s\nDebug: %(debug)s'),
ErrorDialog),
'wrong-host': Message(
_('Wrong host'),
_('Invalid local address? :-O'),
ErrorDialog),
'avahi-error': Message(
_('Avahi error'),
_('%s\nLink-local messaging might not work properly.'),
ErrorDialog),
}
def get_dialog(name, *args, **kwargs):
message = messages.get(name, None)
if message is None:
raise ValueError('Dialog %s does not exist' % name)
# Set transient window
transient_for = kwargs.get('transient_for', None)
if transient_for is None:
transient_for = app.get_active_window()
else:
del kwargs['transient_for']
if args:
message_text = message.text % args
elif kwargs:
message_text = message.text % kwargs
else:
message_text = message.text
dialog = message.dialog(message.title,
GLib.markup_escape_text(message_text),
transient_for=transient_for)
return dialog
......@@ -2879,16 +2879,12 @@ class StartChatDialog(Gtk.ApplicationWindow):
def _start_new_chat(self, row):
if row.new:
if not app.account_is_connected(row.account):
ErrorDialog(
_('You are not connected to the server'),
_('You can not start a new conversation'
' unless you are connected.'),
transient_for=self)
app.interface.raise_dialog('start-chat-not-connected')
return
try:
helpers.parse_jid(row.jid)
except helpers.InvalidFormat as e:
ErrorDialog(_('Invalid JID'), str(e), transient_for=self)
app.interface.raise_dialog('invalid-jid-with-error', str(e))
return
if row.groupchat:
......
......@@ -85,10 +85,6 @@ class FeaturesWindow:
_('Ability to request your router to forward port for file transfer.'),
_('Requires gir1.2-gupnpigd-1.0.'),
_('Feature not available under Windows.')),
_('UPower'): (self.upower_available,
_('Ability to disconnect properly just before suspending the machine.'),
_('Requires upower and python-dbus.'),
_('Feature not available under Windows.')),
}
# name, supported
......@@ -186,8 +182,3 @@ class FeaturesWindow:
def gupnp_igd_available(self):
return app.HAVE_UPNP_IGD
def upower_available(self):
if os.name == 'nt':
return False
from gajim import upower_listener
return upower_listener.supported
......@@ -235,17 +235,22 @@ class GajimApplication(Gtk.Application):
gui_menu_builder.build_accounts_menu()
def _open(self, application, file, hint, *args):
from gajim.common import app
for arg in file:
uri = arg.get_uri()
app.log('uri_handler').info('open %s', uri)
# remove xmpp:///
uri = uri[8:]
jid, cmd = uri.split('?')
try:
jid, cmd = uri.split('?')
except ValueError:
# Invalid URI
return
if cmd == 'join':
self.interface.join_gc_minimal(None, jid)
elif cmd == 'roster':
self.activate_action('add-contact', GLib.Variant('s', jid))