From 41bdb0c7f6406a1be05faed2864571f8066e72ff Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Thu, 19 Apr 2007 13:31:28 +0000 Subject: [PATCH] begining of XEP-0055 (search) implmentation. For the moment, works only with dataforms. see #1922 --- data/glade/data_form_window.glade | 2 +- src/common/connection.py | 13 ++++++ src/common/connection_handlers.py | 19 +++++++++ src/config.py | 12 +++--- src/disco.py | 71 ++++++++++++++++++++++++++++++- src/gajim.py | 13 +++++- 6 files changed, 120 insertions(+), 10 deletions(-) diff --git a/data/glade/data_form_window.glade b/data/glade/data_form_window.glade index 7cc9d8803..2d73ee5dd 100644 --- a/data/glade/data_form_window.glade +++ b/data/glade/data_form_window.glade @@ -584,7 +584,7 @@ - + True False 0 diff --git a/src/common/connection.py b/src/common/connection.py index fbf1992cc..c63071a8a 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -1345,4 +1345,17 @@ class Connection(ConnectionHandlers): else: 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 diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index ced062544..e80749c4c 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -1932,6 +1932,23 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, self.dispatch('SIGNED_IN', ()) 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): # try to find another way to register handlers in each class # that defines handlers @@ -1997,6 +2014,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, common.xmpp.NS_DISCO_ITEMS) con.RegisterHandler('iq', self._IqPingCB, 'get', 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._ErrorCB, 'error') con.RegisterHandler('iq', self._IqCB) diff --git a/src/config.py b/src/config.py index a95651e3a..346d28a85 100644 --- a/src/config.py +++ b/src/config.py @@ -1408,7 +1408,7 @@ class AccountModificationWindow: config['keyname'] = self.xml.get_widget('gpg_name_label').get_text().\ decode('utf-8') - if config['keyname'] == '': #no key selected + if config['keyname'] == '': # no key selected config['keyid'] = '' config['savegpgpass'] = False config['gpgpassword'] = '' @@ -1419,9 +1419,9 @@ class AccountModificationWindow: 'gpg_save_password_checkbutton').get_active() config['gpgpassword'] = self.xml.get_widget('gpg_password_entry' ).get_text().decode('utf-8') - #if we modify the name of the account + # if we modify the name of the account if name != self.account: - #update variables + # update variables gajim.interface.instances[name] = gajim.interface.instances[ self.account] gajim.nicks[name] = gajim.nicks[self.account] @@ -1446,7 +1446,7 @@ class AccountModificationWindow: # change account variable for chat / gc controls gajim.interface.msg_win_mgr.change_account_name(self.account, name) # 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]: gajim.interface.instances[name][kind][j].account = name @@ -2056,7 +2056,7 @@ class AccountsWindow: connection_zeroconf.ConnectionZeroconf(gajim.ZEROCONF_ACC_NAME) # update variables gajim.interface.instances[gajim.ZEROCONF_ACC_NAME] = {'infos': {}, - 'disco': {}, 'gc_config': {}} + 'disco': {}, 'gc_config': {}, 'search': {}} gajim.connections[gajim.ZEROCONF_ACC_NAME].connected = 0 gajim.groups[gajim.ZEROCONF_ACC_NAME] = {} gajim.contacts.add_account(gajim.ZEROCONF_ACC_NAME) @@ -3080,7 +3080,7 @@ class AccountCreationWizardWindow: # update variables gajim.interface.instances[self.account] = {'infos': {}, 'disco': {}, - 'gc_config': {}} + 'gc_config': {}, 'search': {}} gajim.connections[self.account].connected = 0 gajim.groups[self.account] = {} gajim.contacts.add_account(self.account) diff --git a/src/disco.py b/src/disco.py index bbed4c142..938931ab1 100644 --- a/src/disco.py +++ b/src/disco.py @@ -49,6 +49,7 @@ import tooltips import gtkgui_helpers import groups import adhoc_commands +import search from common import gajim from common import xmpp @@ -986,6 +987,7 @@ class ToplevelAgentBrowser(AgentBrowser): self.register_button = None self.join_button = None self.execute_button = None + self.search_button = None # Keep track of our treeview signals self._view_signals = [] self._scroll_signal = None @@ -1142,7 +1144,7 @@ class ToplevelAgentBrowser(AgentBrowser): AgentBrowser._add_actions(self) self.execute_button = gtk.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) hbox = gtk.HBox() hbox.pack_start(image, False, True, 6) @@ -1170,6 +1172,18 @@ class ToplevelAgentBrowser(AgentBrowser): self.window.action_buttonbox.add(self.join_button) 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): if self.execute_button: self.execute_button.destroy() @@ -1180,6 +1194,56 @@ class ToplevelAgentBrowser(AgentBrowser): if self.join_button: self.join_button.destroy() 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) def cleanup(self): @@ -1239,6 +1303,9 @@ class ToplevelAgentBrowser(AgentBrowser): self.browse_button.set_sensitive(False) if self.join_button: 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() if not iter: return @@ -1271,6 +1338,8 @@ class ToplevelAgentBrowser(AgentBrowser): AgentBrowser._update_actions(self, jid, node, identities, features, data) if self.execute_button and xmpp.NS_COMMANDS in features: 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: # We can register this agent registered_transports = [] diff --git a/src/gajim.py b/src/gajim.py index 2b0d29de2..cf34016d7 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -1670,7 +1670,14 @@ class Interface: if ctrl == None: ctrl = self.msg_win_mgr.get_control(contact.jid, account) 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): '''Check idle status and change that status if needed''' if not self.sleeper.poll(): @@ -1986,6 +1993,7 @@ class Interface: 'PING_SENT': self.handle_event_ping_sent, 'PING_REPLY': self.handle_event_ping_reply, 'PING_ERROR': self.handle_event_ping_error, + 'SEARCH_RESULT': self.handle_event_search_result, } gajim.handlers = self.handlers @@ -2169,7 +2177,8 @@ class Interface: self.instances = {'logs': {}} 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.groups[a] = {} gajim.gc_connected[a] = {}