#! /usr/bin/python import string,re import sys,readline,os from popen2 import popen2 import urllib class AppURLopener(urllib.FancyURLopener): def __init__(self, *args): self.version = "Mozilla" urllib.FancyURLopener.__init__(self, *args) urllib._urlopener = AppURLopener() class SearchLet: def __init__(self, name, invocations): self.name=name self.invocations=invocations def answer(self,question): return ["Not found"] def help(self,text): return ["No help available"] def command(self,text): return ["Command not implemented"] class ParseFileLet(SearchLet): def __init__(self, name, invocations, request, regexp="", format=""): SearchLet.__init__(self, name, invocations) self.request=request if regexp: self.r=re.compile(regexp) else: self.r=None self.format=format def getfile(self): pass def answer(self, question): f=self.getfile(self.request,question) a=[] if self.r: for l in f.readlines(): m=self.r.search(l) if m: if self.format: a.append(m.expand(self.format)) else: a.append(l) else: a=f.readlines() f.close() return a class WebLet(ParseFileLet): def __init__(self, name, invocations, request, regexp="", format=""): ParseFileLet.__init__(self, name, invocations+["search","find"],request,regexp,format) def getfile(self, request, question): qu=question.split() q=string.join(qu[1:]) r=request print "connect to [%s]" % r f=urllib.urlopen(r) return f class WebGetLet(ParseFileLet): def getfile(self, request, question): qu=question.split() q=string.join(qu[1:]) r=request % urllib.quote_plus(q) print "connect to [%s]" % r f=urllib.urlopen(r) return f class WebPostLet(WebLet): def __init__(self, name, invocations, request, queryvar, postdata=[], regexp="", format=""): WebLet.__init__(self, name, invocations,request,regexp,format) self.queryvar=queryvar self.postdata=postdata def getfile(self, request, question): qu=question.split() q=string.join(qu[1:]) r=request post=urllib.urlencode(self.postdata+[(self.queryvar,q)]) print "connect to [%s]" % r f=urllib.urlopen(r,post) return f class TranslatorLet(WebPostLet): def __init__(self, name, invocations, lang_in, lang_out): WebPostLet.__init__(self,name,invocations,"http://babelfish.altavista.com/tr", "urltext",[("tt","urltext"),("lp","%s_%s" % (lang_in,lang_out))], "]*>(.*)","TR=\\1"), class SystemCommandLet(ParseFileLet): def getfile(self, request, question): q=question.split() print "exec [%s]" % (request % string.join(q[1:])) outf, inf= popen2(request % string.join(q[1:])) return outf class Commands: WHAT="what" HELP="help" MAKE="make" SEARCH="search" FIND="find" internals=["help","make","what","search", "find"] class DispatchEngine: def __init__(self,commands): self.c=commands self.com={} for i in self.c.internals: self.com[i]=[] def add_searchlet(self, searchlet): self.com[self.c.WHAT].append(searchlet) for k in searchlet.invocations: if self.com.has_key(k): self.com[k].append(searchlet) else: self.com[k]=[searchlet] def __answer(self, question): c=self.c ans=[] q=question.split() if not q: return [] if question.startswith("!"): os.system(question[1:]) return [] command=q[0] if command==c.HELP: if len(q) == 1: return self.com.keys() else: command=q[1] if command in c.internals: return ["Internal command"] elif self.com.has_key(command): for s in self.com[command]: a=s.help(question) for l in a: ans.append("%s: %s" % (s.name,l)) return ans else: return ["Unknown command"] if command==c.MAKE: if len(q) == 1: return self.com.keys() else: command=q[1] if command in c.internals: return ["Bad syntax. Usage: %s action" % c.MAKE] elif self.com.has_key(command): for s in self.com[command]: a=s.command(question) for l in a: ans.append("%s: %s" % (s.name,l)) return ans else: return ["Unknown searchlet"] if self.com.has_key(command): for s in self.com[command]: a=s.answer(question) for l in a: ans.append("%s: %s" % (s.name,l)) else: return ["Command not found"] return ans def answer(self, question): ans=self.__answer(question) for i in range(len(ans)): while ans[i].endswith("\n"): ans[i]=ans[i][:-1] return ans def complete(self, text, state): if state == 0: self.matches = self.get_matches(text) try: return self.matches[state] except IndexError: return None def get_matches(self, text): if " " in text.lstrip(): return [] m=[] for w in self.com.keys(): if w.startswith(text): m.append(w) return m if(__name__=="__main__"): engine=DispatchEngine(Commands()) searchlets=[ WebGetLet("google",["google"],"http://www.google.com/search?q=%s", "^

]*)>","URL=\\1") , WebGetLet("groups",["groups"],"http://groups.google.com/groups?q=%s", "^

]*)>(.*)([^<>]*)<',"SITE=\\1"), WebGetLet("slashdot",["slashdot","/."],"http://slashdot.org/search.pl?query=%s&op=stories&author=&topic=§ion=&sort=1", 'HREF="[^"]*article[^"]*".([^<]*)<',"NEWS=\\1"), WebLet("linuxfr",["linuxfr"],"http://linuxfr.org", "^