# www.jquigley.com # Sat Aug 18 21:27:04 CDT 2007 import logging from search.engine import XpathQuery from search.engine import InotifyWatcher class ChumpQuery(XpathQuery): logger = logging.getLogger('ChumpQuery') def __init__(self): self.dispatch_dict = { 'search' : self.search, 'alpha' : self.alpha, 'title' : self.title, 'nick' : self.nick, 'url' : self.url, 'comment' : self.comment, 'commenter' : self.commenter, 'date_1' : self.first_date, 'date_2' : self.blank, 'button' : self.blank, 'type' : self.blank } def transform(self, q): """Constructs an Xpath query. @param q a search.util.HotAttrDict object representing the query @return a string representing the Xpath query """ self.logger.debug("query map: " + repr(q)) xpath_query = '//link[' for k, v in q.items(): if v != '': xpath_query = xpath_query + self.dispatch_dict.get(k)(v, q) # truncate final 'and' while appending a closing bracket # TODO: xpath_query should be '' if problem arose above xpath_query = xpath_query[:len(xpath_query)-5] + ']' self.logger.debug("xpath query: " + xpath_query) return xpath_query def create_contains(self, node, s): terms = s.split(' ') query = "" for x in terms: query = query + "contains(lower-case(" + node +"), lower-case(\"" + x + "\")) and " return query def create_equals(self, node, s): terms = s.split(' ') query = "" for x in terms: query = query + node + "=\"" + x + "\" or " return query def search(self, s, q): return self.create_contains(".", s) def url(self, s, q): return self.create_contains("url", s) def title(self, s, q): return self.create_contains("title", s) def alpha(self, s, q): return self.create_contains("title", "["+s+"]") def nick(self, s, q): # TODO: nick is not case-insensitive, should this be create_contains() ? return self.create_equals("nick", s) def commenter(self, s, q): return self.create_equals("comment/@nick", s) def comment(self, s, q): return self.create_contains("comment", s) def date_compare(self, node, date, op): return "xs:date(" + node + ")" + op + "xs:date(\"" + date + "\") or " def date_between(self, node, date_1, date_2): return "xs:date(\"" + date_1 + "\") <= xs:date(" + node + ") and xs:date(" + node + ") <= xs:date(\"" + date_2 + "\") or " def build_date(self, d): date = "" if d.has_key('day'): date = date + d['day'] if d.has_key('month'): date = date + " " + d['month'] if d.has_key('hours'): date = date + " " + d['hours'] + ":" if d.has_key('minutes'): date = date + d['minutes'] + ":" if d.has_key('seconds'): date = date + d['seconds'] if d.has_key('year'): date = date + " " + d['year'] return date def first_date(self, date_dict, q): date = self.build_date(date_dict) query = "" if q['date_type'] == 'on': query = self.date_compare("time", date, "=") elif q['date_type'] == 'before': query = self.date_compare("time", date, "<=") elif q['date_type'] == 'after': query = self.date_compare("time", date, ">=") elif q['date_type'] == 'between': date_2 = self.build_date(q['date_2']) query = self.date_between("time", date, date_2) return query def blank(self, s, q): return "" #------------------------------------------------------------------------------ # Unit tests def test_transform(): """Some test shit here. TODO: turn this into an actual test query = {'title':'world', 'alpha_index':'A', 'nick':'kungfooguru', 'url':'http://google.com', 'comment_nick':'kungfooguru', 'comment':'awesome', 'search':'gnome screen', 'advanced':'true'} date_dict = {'day':'Mon', 'month':'Jan', 'date':'1', 'hours':'11', 'minutes':'11', 'seconds':'11', 'year':'2007'} date_2_dict = {'day':'Mon', 'month':'Jan', 'date':'1', 'hours':'11', 'minutes':'11', 'seconds':'11', 'year':'2007'} query = {'title':'world', 'date_type':'between', 'date_1':date_dict, 'date_2':date_2_dict, 'advanced':'t'} """ pass def run_tests(test): print "Running test: %(test)s" % locals() globals()['test_%(test)s' % locals()]() #------------------------------------------------------------------------------ # Begin execution if __name__ == '__main__': import sys sys.exit(run_tests(sys.argv[1])) # EOF