Use caps to determine remote clients' support for specific features.

Caps is now used for: File Transfers, MUC Invites, Ad-Hoc Commands.

TODO:
 * Also handle it this way for typing notifications
   (This might give some trouble / compatibility issues)
 * Fall back to service discovery if no caps are available. Otherwise,
   we break compatibility with a lot of clients. (Asterix?)
This commit is contained in:
js 2008-07-01 10:26:50 +00:00
parent a836c7eca9
commit 62fe1c72e3
2 changed files with 46 additions and 25 deletions

View File

@ -45,7 +45,7 @@ from common.contacts import GC_Contact
from common.logger import Constants from common.logger import Constants
constants = Constants() constants = Constants()
from common.rst_xhtml_generator import create_xhtml from common.rst_xhtml_generator import create_xhtml
from common.xmpp.protocol import NS_XHTML from common.xmpp.protocol import NS_XHTML, NS_FILE, NS_MUC
try: try:
import gtkspell import gtkspell
@ -1074,17 +1074,17 @@ class ChatControl(ChatControlBase):
# If we don't have resource, we can't do file transfer # If we don't have resource, we can't do file transfer
# in transports, contact holds our info we need to disable it too # in transports, contact holds our info we need to disable it too
if self.TYPE_ID == message_control.TYPE_PM and self.gc_contact.jid and \ if NS_FILE in gajim.capscache[(contact.caps_hash_method,
self.gc_contact.resource: contact.caps_hash)].features:
send_file_button.set_sensitive(True)
elif contact.resource and contact.jid.find('@') != -1:
send_file_button.set_sensitive(True) send_file_button.set_sensitive(True)
else: else:
send_file_button.set_sensitive(False) send_file_button.set_sensitive(False)
# check if it's possible to convert to groupchat # check if it's possible to convert to groupchat
if gajim.get_transport_name_from_jid(self.contact.jid) or \ if NS_MUC in gajim.capscache[(contact.caps_hash_method,
gajim.connections[self.account].is_zeroconf: contact.caps_hash)].features:
convert_to_gc_button.set_sensitive(True)
else:
convert_to_gc_button.set_sensitive(False) convert_to_gc_button.set_sensitive(False)
# keep timeout id and window obj for possible big avatar # keep timeout id and window obj for possible big avatar
@ -1821,17 +1821,17 @@ class ChatControl(ChatControlBase):
# If we don't have resource, we can't do file transfer # If we don't have resource, we can't do file transfer
# in transports, contact holds our info we need to disable it too # in transports, contact holds our info we need to disable it too
if self.TYPE_ID == message_control.TYPE_PM and self.gc_contact.jid and \ if NS_FILE in gajim.capscache[(contact.caps_hash_method,
self.gc_contact.resource: contact.caps_hash)].features:
send_file_menuitem.set_sensitive(True)
elif contact.resource and contact.jid.find('@') != -1:
send_file_menuitem.set_sensitive(True) send_file_menuitem.set_sensitive(True)
else: else:
send_file_menuitem.set_sensitive(False) send_file_menuitem.set_sensitive(False)
# check if it's possible to convert to groupchat # check if it's possible to convert to groupchat
if gajim.get_transport_name_from_jid(jid) or \ if NS_MUC in gajim.capscache[(contact.caps_hash_method,
gajim.connections[self.account].is_zeroconf: contact.caps_hash)].features:
convert_to_gc_menuitem.set_sensitive(True)
else:
convert_to_gc_menuitem.set_sensitive(False) convert_to_gc_menuitem.set_sensitive(False)
# connect signals # connect signals

View File

@ -61,6 +61,8 @@ if dbus_support.supported:
import dbus import dbus
from lastfm_track_listener import LastFMTrackListener from lastfm_track_listener import LastFMTrackListener
from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC
try: try:
from osx import syncmenu from osx import syncmenu
except ImportError: except ImportError:
@ -4882,10 +4884,12 @@ class RosterWindow:
start_chat_menuitem.connect('activate', start_chat_menuitem.connect('activate',
self.on_roster_treeview_row_activated, tree_path) self.on_roster_treeview_row_activated, tree_path)
if contact.resource: if contact.resource and NS_FILE in gajim.capscache[
(contact.caps_hash_method, contact.caps_hash)].features:
send_file_menuitem.set_sensitive(True)
send_file_menuitem.connect('activate', send_file_menuitem.connect('activate',
self.on_send_file_menuitem_activate, contact, account) self.on_send_file_menuitem_activate, contact, account)
else: # if we do no have resource we cannot do much else:
send_file_menuitem.set_sensitive(False) send_file_menuitem.set_sensitive(False)
rename_menuitem.connect('activate', self.on_rename, titer, tree_path) rename_menuitem.connect('activate', self.on_rename, titer, tree_path)
@ -5035,15 +5039,22 @@ class RosterWindow:
start_chat_menuitem.set_submenu(self.build_resources_submenu(contacts, start_chat_menuitem.set_submenu(self.build_resources_submenu(contacts,
account, gajim.interface.on_open_chat_window)) account, gajim.interface.on_open_chat_window))
send_file_menuitem.set_submenu(self.build_resources_submenu(contacts, send_file_menuitem.set_submenu(self.build_resources_submenu(contacts,
account, self.on_send_file_menuitem_activate)) account, self.on_send_file_menuitem_activate,
cap=NS_FILE))
execute_command_menuitem.set_submenu(self.build_resources_submenu( execute_command_menuitem.set_submenu(self.build_resources_submenu(
contacts, account, self.on_execute_command)) contacts, account, self.on_execute_command,
cap=NS_COMMANDS))
else: # one resource else: # one resource
start_chat_menuitem.connect('activate', start_chat_menuitem.connect('activate',
gajim.interface.on_open_chat_window, contact, account) gajim.interface.on_open_chat_window, contact, account)
execute_command_menuitem.connect('activate', self.on_execute_command, if contact.resource and NS_FILE in gajim.capscache[
contact, account, contact.resource) (contact.caps_hash_method, contact.caps_hash)].features:
execute_command_menuitem.set_sensitive(True)
execute_command_menuitem.connect('activate', self.on_execute_command,
contact, account, contact.resource)
else:
execute_command_menuitem.set_sensitive(False)
our_jid_other_resource = None our_jid_other_resource = None
if our_jid: if our_jid:
@ -5051,10 +5062,12 @@ class RosterWindow:
our_jid_other_resource = contact.resource our_jid_other_resource = contact.resource
# Else this var is useless but harmless in next connect calls # Else this var is useless but harmless in next connect calls
if contact.resource: if contact.resource and NS_FILE in gajim.capscache[
(contact.caps_hash_method, contact.caps_hash)].features:
send_file_menuitem.set_sensitive(True)
send_file_menuitem.connect('activate', send_file_menuitem.connect('activate',
self.on_send_file_menuitem_activate, contact, account) self.on_send_file_menuitem_activate, contact, account)
else: # if we do not have resource we cannot send file else:
send_file_menuitem.set_sensitive(False) send_file_menuitem.set_sensitive(False)
send_single_message_menuitem.connect('activate', send_single_message_menuitem.connect('activate',
@ -5442,7 +5455,7 @@ class RosterWindow:
menu.popup(None, None, None, event_button, event.time) menu.popup(None, None, None, event_button, event.time)
def build_resources_submenu(self, contacts, account, action, room_jid=None, def build_resources_submenu(self, contacts, account, action, room_jid=None,
room_account=None): room_account=None, cap=None):
''' Build a submenu with contact's resources. ''' Build a submenu with contact's resources.
room_jid and room_account are for action self.on_invite_to_room ''' room_jid and room_account are for action self.on_invite_to_room '''
sub_menu = gtk.Menu() sub_menu = gtk.Menu()
@ -5466,6 +5479,9 @@ class RosterWindow:
item.connect('activate', action, [(c, account)], c.resource) item.connect('activate', action, [(c, account)], c.resource)
else: # start_chat, execute_command, send_file else: # start_chat, execute_command, send_file
item.connect('activate', action, c, account, c.resource) item.connect('activate', action, c, account, c.resource)
if cap and cap not in gajim.capscache[
(c.caps_hash_method, c.caps_hash)].features:
item.set_sensitive(False)
return sub_menu return sub_menu
def build_invite_submenu(self, invite_menuitem, list_): def build_invite_submenu(self, invite_menuitem, list_):
@ -5498,10 +5514,15 @@ class RosterWindow:
invite_to_new_room_menuitem.set_image(icon) invite_to_new_room_menuitem.set_image(icon)
if len(contact_list) > 1: # several resources if len(contact_list) > 1: # several resources
invite_to_new_room_menuitem.set_submenu(self.build_resources_submenu( invite_to_new_room_menuitem.set_submenu(self.build_resources_submenu(
contact_list, account, self.on_invite_to_new_room)) contact_list, account, self.on_invite_to_new_room, cap=NS_MUC))
else: else:
invite_to_new_room_menuitem.connect('activate', if NS_MUC in gajim.capscache[(contact.caps_hash_method,
self.on_invite_to_new_room, list_) contact.caps_hash)].features:
invite_menuitem.set_sensitive(True)
invite_to_new_room_menuitem.connect('activate',
self.on_invite_to_new_room, list_)
else:
invite_menuitem.set_sensitive(False)
# transform None in 'jabber' # transform None in 'jabber'
c_t = contacts_transport or 'jabber' c_t = contacts_transport or 'jabber'
muc_jid = {} muc_jid = {}