--- a/src/python/xesam/xesam-recoll-service
+++ b/src/python/xesam/xesam-recoll-service
@@ -73,6 +73,8 @@
def __init__ (self, searcher, session, search_handle, \
query=None, xml=None) :
+ # Our parent class does possible xml-to-query parsing. We end up
+ # with a query
xesam.server.Search.__init__ (self, searcher, session, search_handle, \
query=query, xml=xml)
@@ -85,11 +87,9 @@
xesam.debug ("Created %s with handle %s and query:\n%s" %
(self.__class__, self.get_handle(), self.get_query()))
- # Only user queries for now...
- if not isinstance(self.get_query(), xesam.query.UserQuery):
- raise Exception ("Only UserQuery supported ATM, sorry.")
+ # Instantiate a recoll query
self.rclquery = self._searcher.rcldb.query()
-
+
# In the latest version (>0.95), primary/secondary is replaced by
# a field list.
sortfield = session.get_property(xesam.SESSION_SORT_PRIMARY)
@@ -105,26 +105,37 @@
if sortfield:
self.rclquery.sortby(sortfield, order == "ascending" and 1 or 0)
+ def doc_to_hit(self, doc):
+ data = []
+ for fld in self._hit_fields:
+ # Need to handle ContentCategory and SourceCategory
+ fld = fld.lower().replace("xesam:", "")
+ xesam.debug("Adding data for fld %s" % (fld))
+ if fld == "snippet":
+ data.append(self._searcher.rcldb.makeDocAbstract(doc,
+ self.rclquery))
+ elif fld == "contentmodified":
+ data.append(timestampToIso8601(getattr(doc, "mtime")))
+ else:
+ data.append(getattr(doc, fld, ""))
+ return data
+
def start (self):
- xesam.debug ("RecollSearch '%s' got [%s]" %
- (self.get_handle(), self.get_query().get_string()))
- self.nres = self.rclquery.execute(self.get_query().get_string())
+ xesam.debug ("RecollSearch")
+
+ if isinstance(self.get_query(), xesam.query.UserQuery):
+ self.nres = self.rclquery.execute(self.get_query().get_string())
+ elif isinstance(self.get_query(), xesam.query.CompositeQuery):
+ self.build_search(None)
+ self.nres = self.rclquery.executesd(self.searchdata)
+ else:
+ raise Exception ("Neither UserQuery nor composite query ??")
+
hits = 0
done = 0
while self.rclquery.next >= 0 and self.rclquery.next < self.nres:
doc = self.rclquery.fetchone()
- data = []
- for fld in self._hit_fields:
- # Need to handle ContentCategory and SourceCategory
- fld = fld.lower().replace("xesam:", "")
- xesam.debug("Adding data for fld %s" % (fld))
- if fld == "snippet":
- data.append(self._searcher.rcldb.makeDocAbstract(doc,
- self.rclquery))
- elif fld == "contentmodified":
- data.append(timestampToIso8601(getattr(doc, "mtime")))
- else:
- data.append(getattr(doc, fld, ""))
+ data = self.doc_to_hit(doc)
self.add_new_hit (self._hit_fields, data)
hits += 1
if hits >= self.SLICE:
@@ -149,15 +160,10 @@
return xesam.server.Search.get_hits(self, num_hits)
hits = 0
- done = 0;
+ done = 0
while self.rclquery.next >= 0 and self.rclquery.next < self.nres:
doc = self.rclquery.fetchone()
- data = []
- for fld in self._hit_fields:
- if self.FLDTRANS.has_key (fld):
- data.append(self.FLDTRANS[fld](doc))
- else:
- data.append("")
+ data = self.doc_to_hit(doc)
self.add_new_hit (self._hit_fields, data)
hits += 1
if hits >= self.SLICE or hits >= num_hits:
@@ -176,6 +182,50 @@
return xesam.server.Search.get_hits(self, num_hits)
+ # Build Recoll searchData tree out of Xesam CompositeQuery
+ # This is recursive, parent is the current SearchData into which we are
+ # adding clauses/subsearches.
+ def build_search(self, parent = None):
+
+Arrete apres le hackfest parce qu'apparemment il y a de gros changements la
+dedans.
+
+Il manque plein de trucs, comme traiter les "names" des selectors (see
+xesam/query.py: SELECTORS, traiter les differents types de values, et leurs
+attributs (phrase, slack, ordered etc, cf xesam/query.py: StringValue
+
+
+ xq = self.get_query()
+ cl = xq.get_clause()
+ if isinstance(cl, xesam.query.SelectorClause):
+ xesam.debug ("Selector clause")
+ if parent is None:
+ # Top clause is a selector. Needs to have a parent
+ self.searchdata = recoll.SearchData()
+ parent = self.searchdata
+
+ # Fields. If there are several we must turn this into an OR
+ # combination of searches on the different fields
+ nfields = length(cl.get_fields())
+ if nfields > 1:
+ orsearch = recoll.SearchData(type = "or")
+ for fld in cl.get_fields():
+ simple_selec_addclause(self, orsearch, cl, fld)
+ parent.addclause(type = "sub", subSearch = orsearch)
+ elif nfields == 1:
+ simple_selec_addclause(self, parent, cl, cl.get_fields[0])
+ else:
+ simple_selec_addclause(self, parent, cl)
+ elif isinstance(cl, xesam.query.CollectorClause):
+ xesam.debug ("Collector clause")
+ else:
+ raise Exception("Non Collector or Selector Clause found")
+
+ # Add Recoll clause for xesam selector clause, dealing with at most
+ # one field.
+ def simple_selec_addclause(self, parent, cl, fld = ""):
+ parent.addclause(type = "and", field = fld,
+ qstring = cl.get_value().get())
if __name__ == "__main__":
RecollServer().start()