changeset 2650:2b4be3be9835

First implementation of search, will be changed later to optionally use oob.
author Karol 'grzywacz' Nowak <grzywacz@sul.uni.lodz.pl>
date Tue, 07 Aug 2007 18:33:18 +0200
parents 3878ffc317da
children c0a85041f623 11447cada25e
files jabberbot/commands.py jabberbot/xmlrpcbot.py jabberbot/xmppbot.py
diffstat 3 files changed, 67 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/jabberbot/commands.py	Tue Aug 07 03:14:32 2007 +0200
+++ b/jabberbot/commands.py	Tue Aug 07 18:33:18 2007 +0200
@@ -129,10 +129,14 @@
     description = u"perform a wiki search"
     parameter_list = u"{title|text} term"
 
-    def __init__(self, jid, term, search_type):
+    def __init__(self, jid, search_type, *args):
         BaseDataCommand.__init__(self, jid)
-        self.term = term
+        self.term = ' '.join(args)
         self.search_type = search_type
+        self.presentation = "text" # "text" or "dataforms"
+        self.case = False
+        self.mtime = None
+        self.regexp = False
 
 class GetUserLanguage:
     """Request user's language information from wiki"""
--- a/jabberbot/xmlrpcbot.py	Tue Aug 07 03:14:32 2007 +0200
+++ b/jabberbot/xmlrpcbot.py	Tue Aug 07 18:33:18 2007 +0200
@@ -122,13 +122,15 @@
             self.get_page_info(command)
         elif isinstance(command, cmd.GetUserLanguage):
             self.get_language_by_jid(command)
+        elif isinstance(command, cmd.Search):
+            self.do_search(command)
 
     def report_error(self, jid, text, data={}):
         # Dummy function, so that the string appears in a .po file
         _ = lambda x: x
 
-        cmddata = {'text': text, 'subject': _("Error"), 'data': data}
-        report = cmd.NotificationCommandI18n(jid, cmddata, async=False)
+        cmddata = {'text': text, 'data': data}
+        report = cmd.NotificationCommandI18n(jid, cmddata, msg_type=u"chat", async=False)
         self.commands_out.put_nowait(report)
 
     def get_auth_token(self, jid):
@@ -152,7 +154,7 @@
         # Dummy function, so that the string appears in a .po file
         _ = lambda x: x
 
-        cmddata = {'text': _("Credentials check failed, you may be unable to see all information.")}
+        cmddata = {'text': _("Credentials check failed, you might be unable to see all information.")}
         warning = cmd.NotificationCommandI18n([jid], cmddata, async=False)
         self.commands_out.put_nowait(warning)
 
@@ -230,6 +232,29 @@
 
     get_page_info = _xmlrpc_decorator(get_page_info)
 
+    def do_search(self, command):
+        """Performs a search"""
+
+        token_result = u"FAILURE"
+        _ = lambda x: x
+
+        cmd_data = {'text': _("This command may take a while to complete, please be patient...")}
+        info = cmd.NotificationCommandI18n([command.jid], cmd_data, async=False, msg_type=u"chat")
+        self.commands_out.put_nowait(info)
+
+        c = command
+        self.multicall.searchPagesEx(c.term, c.search_type, 30, c.case, c.mtime, c.regexp)
+
+        if not self.token:
+            getpageinfo_result = self.multicall()[0]
+        else:
+            token_result, search_result = self.multicall()
+
+        command.data = search_result
+        return token_result
+
+    do_search = _xmlrpc_decorator(do_search)
+
     def get_language_by_jid(self, command):
         """Returns language of the a user identified by the given JID"""
 
--- a/jabberbot/xmppbot.py	Tue Aug 07 03:14:32 2007 +0200
+++ b/jabberbot/xmppbot.py	Tue Aug 07 18:33:18 2007 +0200
@@ -246,6 +246,7 @@
         except Queue.Empty:
             return False
 
+    # XXX: refactor this, if-elif sequence is already too long
     def handle_command(self, command, ignore_dnd=False):
         """Excecutes commands from other components
 
@@ -340,6 +341,32 @@
             if command.jid in self.contacts:
                 self.contacts[command.jid].language = command.language
 
+        elif isinstance(command, cmd.Search):
+            if command.presentation == u"text":
+                if not command.data:
+                    msg = _("There are no pages matching your search criteria!")
+                    self.send_message(command.jid, {'text': msg})
+                    return
+
+                # This hardcoded limitation relies on (mostly correct) assumption that Jabber
+                # servers have rather tight traffic limits. Sending more than 25 results is likely
+                # to take a second or two - users should not have to wait longer (+search time!).
+                elif len(command.data) > 25:
+                    msg =  _("There are too many results (%(number)s). Limiting to first 25 entries.") % {'number': str(len(command.data))}
+                    self.send_message(command.jid, {'text': msg})
+                    command.data = command.data[:25]
+
+                #intro = _("Following pages match your search:\n%(results)s")
+
+                results = [{'description': result[0], 'url': result[2]} for result in command.data]
+
+                # One-space text to work around a bug in Psi
+                data = {'text': ' ', 'url_list': results}
+                self.send_message(command.jid, data, u"chat")
+            else:
+                pass
+                # TODO: implement data forms here
+
     def ask_for_subscription(self, jid):
         """Sends a <presence/> stanza with type="subscribe"
 
@@ -394,7 +421,7 @@
         search_type2 = _("Full-text search")
         search_label = _("Search type")
         search_label2 = _("Search text")
-
+        forms_warn = _("If you see this, your client probably doesn't support Data Forms.")
 
         title_search = forms.Option("t", search_type1)
         full_search = forms.Option("f", search_type2)
@@ -403,7 +430,7 @@
         form.add_field(name="search_type", options=[title_search, full_search], field_type="list-single", label=search_label)
         form.add_field(name="search", field_type="text-single", label=search_label2)
 
-        message = Message(to_jid=jid, body=_("Please specify the search criteria."), subject=_("Wiki search"))
+        message = Message(to_jid=jid, body=forms_warn, subject=_("Wiki search"))
         message.add_content(form)
         self.get_stream().send(message)
 
@@ -489,7 +516,7 @@
             # For unknown command return a generic help message
             return self.reply_help(sender)
 
-    def do_search(self, jid, term, search_type):
+    def do_search(self, jid, search_type, presentation, *args):
         """Performs a Wiki search of term
 
         @param jid: Jabber ID of user performing a search
@@ -498,9 +525,11 @@
         @type term: unicode
         @param search_type: type of search; either "text" or "title"
         @type search_type: unicode
+        @param presentation: how to present the results; "text" or "dataforms"
+        @type presentation: unicode
 
         """
-        search = cmd.Search(jid, term, search_type)
+        search = cmd.Search(jid, search_type, presentation=presentation, *args)
         self.from_commands.put_nowait(search)
 
     def help_on(self, jid, command):