begining of XEP-0055 (search) implmentation. For the moment, works only with dataforms. see #1922
This commit is contained in:
parent
b415df15cc
commit
41bdb0c7f6
|
@ -584,7 +584,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkVBox" id="vbox114">
|
<widget class="GtkVBox" id="buttons_vbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="homogeneous">False</property>
|
<property name="homogeneous">False</property>
|
||||||
<property name="spacing">0</property>
|
<property name="spacing">0</property>
|
||||||
|
|
|
@ -1345,4 +1345,17 @@ class Connection(ConnectionHandlers):
|
||||||
else:
|
else:
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
|
|
||||||
|
def request_search_fields(self, jid):
|
||||||
|
iq = common.xmpp.Iq(typ = 'get', to = jid, queryNS = \
|
||||||
|
common.xmpp.NS_SEARCH)
|
||||||
|
self.connection.send(iq)
|
||||||
|
|
||||||
|
def send_search_form(self, jid, form, is_form):
|
||||||
|
if is_form:
|
||||||
|
iq = common.xmpp.Iq(typ = 'set', to = jid, queryNS = \
|
||||||
|
common.xmpp.NS_SEARCH)
|
||||||
|
item = iq.getTag('query')
|
||||||
|
item.addChild(node = form)
|
||||||
|
self.connection.send(iq)
|
||||||
|
|
||||||
# END Connection
|
# END Connection
|
||||||
|
|
|
@ -1932,6 +1932,23 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
self.dispatch('SIGNED_IN', ())
|
self.dispatch('SIGNED_IN', ())
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
|
|
||||||
|
def _search_fields_received(self, con, iq_obj):
|
||||||
|
jid = jid = helpers.get_jid_from_iq(iq_obj)
|
||||||
|
tag = iq_obj.getTag('query', namespace = common.xmpp.NS_SEARCH)
|
||||||
|
if not tag:
|
||||||
|
self.dispatch('SEARCH_RESULT', (jid, None, False))
|
||||||
|
return
|
||||||
|
df = tag.getTag('x', namespace = common.xmpp.NS_DATA)
|
||||||
|
if df:
|
||||||
|
self.dispatch('SEARCH_RESULT', (jid, df, True))
|
||||||
|
return
|
||||||
|
df = {}
|
||||||
|
for i in iq_obj.getQueryPayload():
|
||||||
|
if not isinstance(i, common.xmpp.Node):
|
||||||
|
pass
|
||||||
|
df[i.getName()] = i.getData()
|
||||||
|
self.dispatch('SEARCH_RESULT', (jid, df, False))
|
||||||
|
|
||||||
def _register_handlers(self, con, con_type):
|
def _register_handlers(self, con, con_type):
|
||||||
# try to find another way to register handlers in each class
|
# try to find another way to register handlers in each class
|
||||||
# that defines handlers
|
# that defines handlers
|
||||||
|
@ -1997,6 +2014,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
common.xmpp.NS_DISCO_ITEMS)
|
common.xmpp.NS_DISCO_ITEMS)
|
||||||
con.RegisterHandler('iq', self._IqPingCB, 'get',
|
con.RegisterHandler('iq', self._IqPingCB, 'get',
|
||||||
common.xmpp.NS_PING)
|
common.xmpp.NS_PING)
|
||||||
|
con.RegisterHandler('iq', self._search_fields_received, 'result',
|
||||||
|
common.xmpp.NS_SEARCH)
|
||||||
con.RegisterHandler('iq', self._PubSubCB, 'result')
|
con.RegisterHandler('iq', self._PubSubCB, 'result')
|
||||||
con.RegisterHandler('iq', self._ErrorCB, 'error')
|
con.RegisterHandler('iq', self._ErrorCB, 'error')
|
||||||
con.RegisterHandler('iq', self._IqCB)
|
con.RegisterHandler('iq', self._IqCB)
|
||||||
|
|
|
@ -1446,7 +1446,7 @@ class AccountModificationWindow:
|
||||||
# change account variable for chat / gc controls
|
# change account variable for chat / gc controls
|
||||||
gajim.interface.msg_win_mgr.change_account_name(self.account, name)
|
gajim.interface.msg_win_mgr.change_account_name(self.account, name)
|
||||||
# upgrade account variable in opened windows
|
# upgrade account variable in opened windows
|
||||||
for kind in ('infos', 'disco', 'gc_config'):
|
for kind in ('infos', 'disco', 'gc_config', 'search'):
|
||||||
for j in gajim.interface.instances[name][kind]:
|
for j in gajim.interface.instances[name][kind]:
|
||||||
gajim.interface.instances[name][kind][j].account = name
|
gajim.interface.instances[name][kind][j].account = name
|
||||||
|
|
||||||
|
@ -2056,7 +2056,7 @@ class AccountsWindow:
|
||||||
connection_zeroconf.ConnectionZeroconf(gajim.ZEROCONF_ACC_NAME)
|
connection_zeroconf.ConnectionZeroconf(gajim.ZEROCONF_ACC_NAME)
|
||||||
# update variables
|
# update variables
|
||||||
gajim.interface.instances[gajim.ZEROCONF_ACC_NAME] = {'infos': {},
|
gajim.interface.instances[gajim.ZEROCONF_ACC_NAME] = {'infos': {},
|
||||||
'disco': {}, 'gc_config': {}}
|
'disco': {}, 'gc_config': {}, 'search': {}}
|
||||||
gajim.connections[gajim.ZEROCONF_ACC_NAME].connected = 0
|
gajim.connections[gajim.ZEROCONF_ACC_NAME].connected = 0
|
||||||
gajim.groups[gajim.ZEROCONF_ACC_NAME] = {}
|
gajim.groups[gajim.ZEROCONF_ACC_NAME] = {}
|
||||||
gajim.contacts.add_account(gajim.ZEROCONF_ACC_NAME)
|
gajim.contacts.add_account(gajim.ZEROCONF_ACC_NAME)
|
||||||
|
@ -3080,7 +3080,7 @@ class AccountCreationWizardWindow:
|
||||||
|
|
||||||
# update variables
|
# update variables
|
||||||
gajim.interface.instances[self.account] = {'infos': {}, 'disco': {},
|
gajim.interface.instances[self.account] = {'infos': {}, 'disco': {},
|
||||||
'gc_config': {}}
|
'gc_config': {}, 'search': {}}
|
||||||
gajim.connections[self.account].connected = 0
|
gajim.connections[self.account].connected = 0
|
||||||
gajim.groups[self.account] = {}
|
gajim.groups[self.account] = {}
|
||||||
gajim.contacts.add_account(self.account)
|
gajim.contacts.add_account(self.account)
|
||||||
|
|
71
src/disco.py
71
src/disco.py
|
@ -49,6 +49,7 @@ import tooltips
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
import groups
|
import groups
|
||||||
import adhoc_commands
|
import adhoc_commands
|
||||||
|
import search
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import xmpp
|
from common import xmpp
|
||||||
|
@ -986,6 +987,7 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
self.register_button = None
|
self.register_button = None
|
||||||
self.join_button = None
|
self.join_button = None
|
||||||
self.execute_button = None
|
self.execute_button = None
|
||||||
|
self.search_button = None
|
||||||
# Keep track of our treeview signals
|
# Keep track of our treeview signals
|
||||||
self._view_signals = []
|
self._view_signals = []
|
||||||
self._scroll_signal = None
|
self._scroll_signal = None
|
||||||
|
@ -1142,7 +1144,7 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
AgentBrowser._add_actions(self)
|
AgentBrowser._add_actions(self)
|
||||||
self.execute_button = gtk.Button()
|
self.execute_button = gtk.Button()
|
||||||
image = gtk.image_new_from_stock(gtk.STOCK_EXECUTE, gtk.ICON_SIZE_BUTTON)
|
image = gtk.image_new_from_stock(gtk.STOCK_EXECUTE, gtk.ICON_SIZE_BUTTON)
|
||||||
label = gtk.Label(_('_Execute Command...'))
|
label = gtk.Label(_('_Execute Command'))
|
||||||
label.set_use_underline(True)
|
label.set_use_underline(True)
|
||||||
hbox = gtk.HBox()
|
hbox = gtk.HBox()
|
||||||
hbox.pack_start(image, False, True, 6)
|
hbox.pack_start(image, False, True, 6)
|
||||||
|
@ -1170,6 +1172,18 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
self.window.action_buttonbox.add(self.join_button)
|
self.window.action_buttonbox.add(self.join_button)
|
||||||
self.join_button.show_all()
|
self.join_button.show_all()
|
||||||
|
|
||||||
|
self.search_button = gtk.Button()
|
||||||
|
image = gtk.image_new_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON)
|
||||||
|
label = gtk.Label(_('_Search'))
|
||||||
|
label.set_use_underline(True)
|
||||||
|
hbox = gtk.HBox()
|
||||||
|
hbox.pack_start(image, False, True, 6)
|
||||||
|
hbox.pack_end(label, True, True)
|
||||||
|
self.search_button.add(hbox)
|
||||||
|
self.search_button.connect('clicked', self.on_search_button_clicked)
|
||||||
|
self.window.action_buttonbox.add(self.search_button)
|
||||||
|
self.search_button.show_all()
|
||||||
|
|
||||||
def _clean_actions(self):
|
def _clean_actions(self):
|
||||||
if self.execute_button:
|
if self.execute_button:
|
||||||
self.execute_button.destroy()
|
self.execute_button.destroy()
|
||||||
|
@ -1180,6 +1194,56 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
if self.join_button:
|
if self.join_button:
|
||||||
self.join_button.destroy()
|
self.join_button.destroy()
|
||||||
self.join_button = None
|
self.join_button = None
|
||||||
|
if self.search_button:
|
||||||
|
self.search_button.destroy()
|
||||||
|
self.search_button = None
|
||||||
|
AgentBrowser._clean_actions(self)
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
self.tooltip.hide_tooltip()
|
||||||
|
AgentBrowser.cleanup(self)
|
||||||
|
|
||||||
|
def update_theme(self):
|
||||||
|
theme = gajim.config.get('roster_theme')
|
||||||
|
bgcolor = gajim.config.get_per('themes', theme, 'groupbgcolor')
|
||||||
|
if bgcolor:
|
||||||
|
self._renderer.set_property('cell-background', bgcolor)
|
||||||
|
self.window.services_treeview.queue_draw()
|
||||||
|
|
||||||
|
def on_execute_button_clicked(self, widget = None):
|
||||||
|
'''When we want to execute a command:
|
||||||
|
open adhoc command window'''
|
||||||
|
model, iter = self.window.services_treeview.get_selection().get_selected()
|
||||||
|
if not iter:
|
||||||
|
return
|
||||||
|
service = model[iter][0].decode('utf-8')
|
||||||
|
adhoc_commands.CommandWindow(self.account, service)
|
||||||
|
|
||||||
|
def on_search_button_clicked(self, widget = None):
|
||||||
|
'''When we want to search something:
|
||||||
|
open search window'''
|
||||||
|
model, iter = self.window.services_treeview.get_selection().get_selected()
|
||||||
|
if not iter:
|
||||||
|
return
|
||||||
|
service = model[iter][0].decode('utf-8')
|
||||||
|
if gajim.interface.instances[self.account]['search'].has_key(service):
|
||||||
|
gajim.interface.instances[self.account]['search'][service].present()
|
||||||
|
else:
|
||||||
|
gajim.interface.instances[self.account]['search'][service] = \
|
||||||
|
search.SearchWindow(self.account, service)
|
||||||
|
|
||||||
|
def on_register_button_clicked(self, widget = None):
|
||||||
|
'''When we want to register an agent:
|
||||||
|
request information about registering with the agent and close the
|
||||||
|
window.'''
|
||||||
|
model, iter = self.window.services_treeview.get_selection().get_selected()
|
||||||
|
if not iter:
|
||||||
|
return
|
||||||
|
jid = model[iter][0].decode('utf-8')
|
||||||
|
if jid:
|
||||||
|
gajim.connections[self.account].request_register_agent_info(jid)
|
||||||
|
self.window.destroy(chain = True)
|
||||||
|
|
||||||
AgentBrowser._clean_actions(self)
|
AgentBrowser._clean_actions(self)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
|
@ -1239,6 +1303,9 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
self.browse_button.set_sensitive(False)
|
self.browse_button.set_sensitive(False)
|
||||||
if self.join_button:
|
if self.join_button:
|
||||||
self.join_button.set_sensitive(False)
|
self.join_button.set_sensitive(False)
|
||||||
|
if self.search_button:
|
||||||
|
self.search_button.set_sensitive(False)
|
||||||
|
model, iter = self.window.services_treeview.get_selection().get_selected()
|
||||||
model, iter = self.window.services_treeview.get_selection().get_selected()
|
model, iter = self.window.services_treeview.get_selection().get_selected()
|
||||||
if not iter:
|
if not iter:
|
||||||
return
|
return
|
||||||
|
@ -1271,6 +1338,8 @@ class ToplevelAgentBrowser(AgentBrowser):
|
||||||
AgentBrowser._update_actions(self, jid, node, identities, features, data)
|
AgentBrowser._update_actions(self, jid, node, identities, features, data)
|
||||||
if self.execute_button and xmpp.NS_COMMANDS in features:
|
if self.execute_button and xmpp.NS_COMMANDS in features:
|
||||||
self.execute_button.set_sensitive(True)
|
self.execute_button.set_sensitive(True)
|
||||||
|
if self.search_button and xmpp.NS_SEARCH in features:
|
||||||
|
self.search_button.set_sensitive(True)
|
||||||
if self.register_button and xmpp.NS_REGISTER in features:
|
if self.register_button and xmpp.NS_REGISTER in features:
|
||||||
# We can register this agent
|
# We can register this agent
|
||||||
registered_transports = []
|
registered_transports = []
|
||||||
|
|
11
src/gajim.py
11
src/gajim.py
|
@ -1671,6 +1671,13 @@ class Interface:
|
||||||
ctrl = self.msg_win_mgr.get_control(contact.jid, account)
|
ctrl = self.msg_win_mgr.get_control(contact.jid, account)
|
||||||
ctrl.print_conversation(_('Error.'), 'status')
|
ctrl.print_conversation(_('Error.'), 'status')
|
||||||
|
|
||||||
|
def handle_event_search_result(self, account, data):
|
||||||
|
# ('SEARCH_RESULT', account, (jid, dataform, is_dataform))
|
||||||
|
if not self.instances[account]['search'].has_key(data[0]):
|
||||||
|
return
|
||||||
|
self.instances[account]['search'][data[0]].on_form_arrived(data[1],
|
||||||
|
data[2])
|
||||||
|
|
||||||
def read_sleepy(self):
|
def read_sleepy(self):
|
||||||
'''Check idle status and change that status if needed'''
|
'''Check idle status and change that status if needed'''
|
||||||
if not self.sleeper.poll():
|
if not self.sleeper.poll():
|
||||||
|
@ -1986,6 +1993,7 @@ class Interface:
|
||||||
'PING_SENT': self.handle_event_ping_sent,
|
'PING_SENT': self.handle_event_ping_sent,
|
||||||
'PING_REPLY': self.handle_event_ping_reply,
|
'PING_REPLY': self.handle_event_ping_reply,
|
||||||
'PING_ERROR': self.handle_event_ping_error,
|
'PING_ERROR': self.handle_event_ping_error,
|
||||||
|
'SEARCH_RESULT': self.handle_event_search_result,
|
||||||
}
|
}
|
||||||
gajim.handlers = self.handlers
|
gajim.handlers = self.handlers
|
||||||
|
|
||||||
|
@ -2169,7 +2177,8 @@ class Interface:
|
||||||
self.instances = {'logs': {}}
|
self.instances = {'logs': {}}
|
||||||
|
|
||||||
for a in gajim.connections:
|
for a in gajim.connections:
|
||||||
self.instances[a] = {'infos': {}, 'disco': {}, 'gc_config': {}}
|
self.instances[a] = {'infos': {}, 'disco': {}, 'gc_config': {},
|
||||||
|
'search': {}}
|
||||||
gajim.contacts.add_account(a)
|
gajim.contacts.add_account(a)
|
||||||
gajim.groups[a] = {}
|
gajim.groups[a] = {}
|
||||||
gajim.gc_connected[a] = {}
|
gajim.gc_connected[a] = {}
|
||||||
|
|
Loading…
Reference in New Issue