add ad hoc commands for zeroconf. Fixes #2819
This commit is contained in:
parent
1e76981322
commit
da799bcb59
|
@ -1,32 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkMenu" id="zeroconf_contact_context_menu">
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="start_chat_menuitem">
|
||||
<property name="label">Start _Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Start _Chat</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1701">
|
||||
<widget class="GtkImage" id="image9">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="send_file_menuitem">
|
||||
<property name="label">Send _File</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Send _File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1706">
|
||||
<widget class="GtkImage" id="image10">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-save</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -36,67 +38,85 @@
|
|||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="execute_command_menuitem">
|
||||
<property name="label" translatable="yes">Execute Command...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="manage_contact">
|
||||
<property name="label">_Manage Contact</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Manage Contact</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menu2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="rename_menuitem">
|
||||
<property name="label" translatable="yes">_Rename</property>
|
||||
<property name="label">_Rename</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1705">
|
||||
<widget class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="edit_groups_menuitem">
|
||||
<property name="label" translatable="yes">Edit _Groups</property>
|
||||
<property name="label">Edit _Groups</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image21">
|
||||
<widget class="GtkImage" id="image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="assign_openpgp_key_menuitem">
|
||||
<property name="label" translatable="yes">Assign Open_PGP Key</property>
|
||||
<property name="label">Assign Open_PGP Key</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_assign_openpgp_key_menuitem_activate"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1707">
|
||||
<widget class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-authentication</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="add_special_notification_menuitem">
|
||||
<property name="label">Add Special _Notification</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">Add Special _Notification</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1708">
|
||||
<widget class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-info</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -104,11 +124,10 @@
|
|||
</widget>
|
||||
</child>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image19">
|
||||
<widget class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -120,20 +139,28 @@
|
|||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="information_menuitem">
|
||||
<property name="label">gtk-info</property>
|
||||
<property name="label">_Information</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-info</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="history_menuitem">
|
||||
<property name="label" translatable="yes">_History</property>
|
||||
<property name="label">_History</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image1718">
|
||||
<widget class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-justify-fill</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
|
|
@ -167,6 +167,8 @@ class P2PClient(IdleObject):
|
|||
self.conn_holder.ids_of_awaiting_messages[self.fd] = [(id_,
|
||||
thread_id)]
|
||||
|
||||
self.on_responses = {}
|
||||
|
||||
def add_stanza(self, stanza, is_message=False):
|
||||
if self.Connection:
|
||||
if self.Connection.state == -1:
|
||||
|
@ -282,6 +284,9 @@ class P2PClient(IdleObject):
|
|||
self.onreceive(None)
|
||||
return True
|
||||
|
||||
def remove_timeout(self):
|
||||
pass
|
||||
|
||||
def _register_handlers(self):
|
||||
self.RegisterHandler('message', lambda conn, data:self._caller._messageCB(
|
||||
self.Server, conn, data))
|
||||
|
@ -297,6 +302,8 @@ class P2PClient(IdleObject):
|
|||
common.xmpp.NS_BYTESTREAM)
|
||||
self.RegisterHandler('iq', self._caller._bytestreamErrorCB, 'error',
|
||||
common.xmpp.NS_BYTESTREAM)
|
||||
self.RegisterHandler('iq', self._caller._DiscoverItemsGetCB, 'get',
|
||||
common.xmpp.NS_DISCO_ITEMS)
|
||||
|
||||
class P2PConnection(IdleObject, PlugIn):
|
||||
def __init__(self, sock_hash, _sock, host=None, port=None, caller=None,
|
||||
|
@ -717,4 +724,35 @@ class ClientZeroconf:
|
|||
P2PClient(None, item['address'], item['port'], self,
|
||||
[(stanza, is_message)], to, on_ok=on_ok, on_not_ok=on_not_ok)
|
||||
|
||||
def SendAndWaitForResponse(self, stanza, timeout=None, func=None, args=None):
|
||||
'''
|
||||
Send stanza and wait for recipient's response to it. Will call transports
|
||||
on_timeout callback if response is not retrieved in time.
|
||||
|
||||
Be aware: Only timeout of latest call of SendAndWait is active.
|
||||
'''
|
||||
# if timeout is None:
|
||||
# timeout = DEFAULT_TIMEOUT_SECONDS
|
||||
def on_ok(_waitid):
|
||||
# if timeout:
|
||||
# self._owner.set_timeout(timeout)
|
||||
to = stanza.getTo()
|
||||
conn = None
|
||||
if to in self.recipient_to_hash:
|
||||
conn = self.connections[self.recipient_to_hash[to]]
|
||||
elif item['address'] in self.ip_to_hash:
|
||||
hash_ = self.ip_to_hash[item['address']]
|
||||
if self.hash_to_port[hash_] == item['port']:
|
||||
conn = self.connections[hash_]
|
||||
if func:
|
||||
conn.Dispatcher.on_responses[_waitid] = (func, args)
|
||||
conn.onreceive(conn.Dispatcher._WaitForData)
|
||||
conn.Dispatcher._expected[_waitid] = None
|
||||
self.send(stanza, on_ok=on_ok)
|
||||
|
||||
def SendAndCallForResponse(self, stanza, func=None, args=None):
|
||||
''' Put stanza on the wire and call back when recipient replies.
|
||||
Additional callback arguments can be specified in args. '''
|
||||
self.SendAndWaitForResponse(stanza, 0, func, args)
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
|
@ -34,6 +34,10 @@ import common.xmpp
|
|||
from common import helpers
|
||||
from common import gajim
|
||||
from common.zeroconf import zeroconf
|
||||
from common.commands import ConnectionCommands
|
||||
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.z.connection_handlers_zeroconf')
|
||||
|
||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||
'invisible']
|
||||
|
@ -45,7 +49,7 @@ HAS_IDLE = True
|
|||
try:
|
||||
import idle
|
||||
except Exception:
|
||||
gajim.log.debug(_('Unable to load idle module'))
|
||||
log.debug(_('Unable to load idle module'))
|
||||
HAS_IDLE = False
|
||||
|
||||
from common import connection_handlers
|
||||
|
@ -156,7 +160,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
self.connection.send(iq)
|
||||
|
||||
def _bytestreamSetCB(self, con, iq_obj):
|
||||
gajim.log.debug('_bytestreamSetCB')
|
||||
log.debug('_bytestreamSetCB')
|
||||
target = unicode(iq_obj.getAttr('to'))
|
||||
id_ = unicode(iq_obj.getAttr('id'))
|
||||
query = iq_obj.getTag('query')
|
||||
|
@ -198,7 +202,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _ResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('_ResultCB')
|
||||
log.debug('_ResultCB')
|
||||
# if we want to respect jep-0065 we have to check for proxy
|
||||
# activation result in any result iq
|
||||
real_id = unicode(iq_obj.getAttr('id'))
|
||||
|
@ -215,7 +219,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _bytestreamResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('_bytestreamResultCB')
|
||||
log.debug('_bytestreamResultCB')
|
||||
frm = unicode(iq_obj.getFrom())
|
||||
real_id = unicode(iq_obj.getAttr('id'))
|
||||
query = iq_obj.getTag('query')
|
||||
|
@ -283,7 +287,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _siResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('_siResultCB')
|
||||
log.debug('_siResultCB')
|
||||
self.peerhost = con._owner.Connection._sock.getsockname()
|
||||
id_ = iq_obj.getAttr('id')
|
||||
if id_ not in self.files_props:
|
||||
|
@ -321,7 +325,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _siSetCB(self, con, iq_obj):
|
||||
gajim.log.debug('_siSetCB')
|
||||
log.debug('_siSetCB')
|
||||
jid = unicode(iq_obj.getFrom())
|
||||
si = iq_obj.getTag('si')
|
||||
profile = si.getAttr('profile')
|
||||
|
@ -353,7 +357,7 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _siErrorCB(self, con, iq_obj):
|
||||
gajim.log.debug('_siErrorCB')
|
||||
log.debug('_siErrorCB')
|
||||
si = iq_obj.getTag('si')
|
||||
profile = si.getAttr('profile')
|
||||
if profile != common.xmpp.NS_FILE:
|
||||
|
@ -371,10 +375,12 @@ class ConnectionBytestream(connection_handlers.ConnectionBytestream):
|
|||
self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, ''))
|
||||
raise common.xmpp.NodeProcessed
|
||||
|
||||
class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream, connection_handlers.ConnectionHandlersBase):
|
||||
class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream,
|
||||
ConnectionCommands, connection_handlers.ConnectionHandlersBase):
|
||||
def __init__(self):
|
||||
ConnectionVcard.__init__(self)
|
||||
ConnectionBytestream.__init__(self)
|
||||
ConnectionCommands.__init__(self)
|
||||
connection_handlers.ConnectionHandlersBase.__init__(self)
|
||||
|
||||
try:
|
||||
|
@ -386,7 +392,7 @@ class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream, connecti
|
|||
def _messageCB(self, ip, con, msg):
|
||||
'''Called when we receive a message'''
|
||||
|
||||
gajim.log.debug('Zeroconf MessageCB')
|
||||
log.debug('Zeroconf MessageCB')
|
||||
|
||||
frm = msg.getFrom()
|
||||
mtype = msg.getType()
|
||||
|
@ -480,4 +486,21 @@ class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream, connecti
|
|||
def remove_transfer(self, file_props, remove_from_list = True):
|
||||
pass
|
||||
|
||||
def _DiscoverItemsGetCB(self, con, iq_obj):
|
||||
log.debug('DiscoverItemsGetCB')
|
||||
|
||||
if not self.connection or self.connected < 2:
|
||||
return
|
||||
|
||||
if self.commandItemsQuery(con, iq_obj):
|
||||
raise common.xmpp.NodeProcessed
|
||||
node = iq_obj.getTagAttr('query', 'node')
|
||||
if node is None:
|
||||
result = iq_obj.buildReply('result')
|
||||
self.connection.send(result)
|
||||
raise common.xmpp.NodeProcessed
|
||||
if node==common.xmpp.NS_COMMANDS:
|
||||
self.commandListQuery(con, iq_obj)
|
||||
raise common.xmpp.NodeProcessed
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
|
@ -5305,6 +5305,7 @@ class RosterWindow:
|
|||
'zeroconf_contact_context_menu')
|
||||
|
||||
start_chat_menuitem = xml.get_widget('start_chat_menuitem')
|
||||
execute_command_menuitem = xml.get_widget('execute_command_menuitem')
|
||||
rename_menuitem = xml.get_widget('rename_menuitem')
|
||||
edit_groups_menuitem = xml.get_widget('edit_groups_menuitem')
|
||||
send_file_menuitem = xml.get_widget('send_file_menuitem')
|
||||
|
@ -5364,6 +5365,9 @@ class RosterWindow:
|
|||
else:
|
||||
send_file_menuitem.set_sensitive(False)
|
||||
|
||||
execute_command_menuitem.connect('activate',
|
||||
self.on_execute_command, contact, account)
|
||||
|
||||
rename_menuitem.connect('activate', self.on_rename, 'contact', jid,
|
||||
account)
|
||||
if contact.show in ('offline', 'error'):
|
||||
|
|
Loading…
Reference in New Issue