Example #1
0
class LuceneQuery(object):
    MANDATORY = "mandatory"
    PROHIBITED = "prohibited"
    OPTIONAL = "optional"

    required_modifiers = {MANDATORY: "+", PROHIBITED: "-", OPTIONAL: ""}

    def __init__(self, *args, **kw):
        first_arg = args[0]
        if hasattr(first_arg, "solr_field_name"):
            self.field, args = first_arg, args[1:]
        elif isinstance(first_arg, LuceneQuery):
            # Only pass LuceneQuery if all the other args are LuceneQueries
            self.field = None
            self.components = itertools.chain([query.components for query in args])
        else:
            self.field = None

        self.use_colon = True
        self.components = list(args)
        self.local_params = MultiDict()
        self.required = LuceneQuery.OPTIONAL
        self.boost_factor = None

    def __pow__(self, power):
        if not self.components:
            self.use_colon = False
        self.boost_factor = power
        return self

    def tag(self, tag):
        self.local_params.add("tag", tag)
        return self

    def require(self):
        self.required = LuceneQuery.MANDATORY
        return self

    def negate(self):
        self.required = LuceneQuery.PROHIBITED
        return self

    def fuzzy(self, factor=NotGiven):
        self.components.append("~")
        if factor != NotGiven:
            self.components.append(factor)
        return self

    def __unicode__(self):
        modifier = self.required_modifiers[self.required]
        field_clause = "" if not self.field else unicode(self.field)
        separator = ":" if self.use_colon else ""
        local_params = ""
        if self.local_params:
            local_params = (
                "{!" + " ".join(["%s=%s" % (key, unicode(val)) for key, val in self.local_params.iteritems()]) + "}"
            )
        component_clause = "".join([unicode(component) for component in self.components])
        boost_factor = "^%s" % self.boost_factor if self.boost_factor else ""
        return u"".join([local_params, modifier, field_clause, separator, component_clause, boost_factor])
Example #2
0
 def __init__(self, environ):
     self.environ = environ
     self.path = environ.get("PATH_INFO", "").decode("utf8")
     self.method = environ.get("REQUEST_METHOD", "")
     self.cookies = Cookie.SimpleCookie(str(environ.get("HTTP_COOKIE", "")))
     self.GET = MultiDict(
         cgi.parse_qsl(urllib2.unquote(environ.get("QUERY_STRING", "")).decode("utf8"), keep_blank_values=1)
     )
     self.POST = {}
     self.FILES = {}
     if self.method == "POST":
         post = cgi.FieldStorage(fp=environ.get("wsgi.input", ""), environ=environ, keep_blank_values=1)
         self.POST = MultiDict([(item.name, item.value) for item in post.list if not item.filename])
         self.FILES = MultiDict([(item.name, item) for item in post.list if item.filename])
     self.REQUEST = MultiDict(self.GET.items() + self.POST.items())  # + self.FILES.items())
Example #3
0
class Response(object):
    def __init__(
        self, body="", content_type="text/html", charset="utf8", redirect=None, status_code=None, status_msg=None
    ):
        self.headers = MultiDict()
        self.content_type = content_type
        self.charset = charset
        self.body = body
        self.redirect = redirect
        self.status_code = status_code
        self.status_msg = status_msg
        self.cookies = Cookie.SimpleCookie()

    @property
    def status(self):
        status_map = {200: "OK", 301: "Moved Permanently", 302: "Found", 404: "Not Found", 500: "Internal Server Error"}
        if not self.status_msg:
            self.status_msg = status_map.get(self.status_code, "")
        return "%s %s" % (self.status_code, self.status_msg)

    def finalize(self):
        self.headers["Content-Type"] = "%s; charset=%s" % (self.content_type, self.charset)
        self.headers["Content-Length"] = len(self.body)
        if self.redirect:
            self.headers["Location"] = self.redirect
            self.status_code = self.status_code or 302
        for key in self.cookies:
            self.cookies[key]["path"] = self.cookies[key]["path"] or "/"
            self.headers["Set-Cookie"] = self.cookies[key].OutputString()
        self.status_code = self.status_code or 200
        self.headers = MultiDict(
            [(safestr(k, self.charset), safestr(v, self.charset)) for (k, v) in self.headers.items()]
        )
Example #4
0
 def __init__(
     self, body="", content_type="text/html", charset="utf8", redirect=None, status_code=None, status_msg=None
 ):
     self.headers = MultiDict()
     self.content_type = content_type
     self.charset = charset
     self.body = body
     self.redirect = redirect
     self.status_code = status_code
     self.status_msg = status_msg
     self.cookies = Cookie.SimpleCookie()
Example #5
0
 def finalize(self):
     self.headers["Content-Type"] = "%s; charset=%s" % (self.content_type, self.charset)
     self.headers["Content-Length"] = len(self.body)
     if self.redirect:
         self.headers["Location"] = self.redirect
         self.status_code = self.status_code or 302
     for key in self.cookies:
         self.cookies[key]["path"] = self.cookies[key]["path"] or "/"
         self.headers["Set-Cookie"] = self.cookies[key].OutputString()
     self.status_code = self.status_code or 200
     self.headers = MultiDict(
         [(safestr(k, self.charset), safestr(v, self.charset)) for (k, v) in self.headers.items()]
     )
Example #6
0
    def __init__(self, *args, **kw):
        first_arg = args[0]
        if hasattr(first_arg, "solr_field_name"):
            self.field, args = first_arg, args[1:]
        elif isinstance(first_arg, LuceneQuery):
            # Only pass LuceneQuery if all the other args are LuceneQueries
            self.field = None
            self.components = itertools.chain([query.components for query in args])
        else:
            self.field = None

        self.use_colon = True
        self.components = list(args)
        self.local_params = MultiDict()
        self.required = LuceneQuery.OPTIONAL
        self.boost_factor = None
Example #7
0
 def __init__(self, connections=None, index=None):
     self.params = MultiDict()
     self.connections = connections
     self.conn = self.connections.get("main", None)
     self.index = index
     self.params_joined = False
Example #8
0
class SolrQuery(object):
    separators = {}

    def __init__(self, connections=None, index=None):
        self.params = MultiDict()
        self.connections = connections
        self.conn = self.connections.get("main", None)
        self.index = index
        self.params_joined = False

    def use_index(self, index):
        self.index = index

    def handle_row(self, row):
        return self.index(row)

    def join_params(self):
        return MultiDict(
            (k, self.separators[k].join([unicode(v) for v in val]) if k in self.separators else unicode(val))
            for k, val in self.params.iteritems()
        )

    def execute(self, handler=handle_row, conn="main"):
        if not self.params_joined:
            self.params = self.join_params()
            self.params_joined = True
        return SolrResult(self._execute_search(), handler=partial(handler, self))

    def query(self, query):
        self.params.add("q", query)
        return self

    def filter(self, *filters):
        [self.params.add("fq", filter) for filter in filters]
        return self

    def facet(self, field, method="enum", missing_facet=NotGiven, sort=NotGiven, min_count=1):
        self.params["facet"] = "true"
        field_name = SolrQuery._name_or_val(field)
        self.params.add("facet.field", field_name)
        self.params["f.%s.facet.method" % field_name] = method
        if sort != NotGiven:
            self.params["f.%s.facet.sort" % field_name] = sort
        if missing_facet != NotGiven:
            self.params["f.%s.facet.missing" % field_name] = missing_facet
        self.params["f.%s.facet.mincount" % field_name] = min_count
        return self

    def facet_date(
        self, date_field, start_date=NotGiven, end_date=NotGiven, gap=NotGiven, hard_end=NotGiven, other=NotGiven
    ):
        self.params["facet"] = "true"
        field_name = SolrQuery._name_or_val(date_field)
        self.params.add("facet.date", field_name)

        if start_date != NotGiven:
            self.params["f.%s.facet.date.start" % field_name] = start_date

        if end_date != NotGiven:
            self.params["f.%s.facet.date.end" % field_name] = end_date

        if gap != NotGiven:
            self.params["f.%s.facet.date.gap" % field_name] = gap

        if hard_end != NotGiven:
            self.params["f.%s.facet.date.hardend" % field_name] = hard_end

        if other != NotGiven:
            self.params["f.%s.facet.date.other" % field_name] = other

        return self

    def facet_query(self, *queries):
        self.params["facet"] = "true"
        [self.params.add("facet.query", query) for query in queries]
        return self

    def facet_prefix(self, field, prefix):
        self.facet(field)
        self.params["facet.prefix"] = prefix
        return self

    def default_operator(self, op):
        self.params["q.op"] = op
        return self

    def default_field(self, field):
        self.params["df"] = field
        return self

    def def_type(self, type):
        self.params["defType"] = type
        return self

    def tie(self, tie):
        self.params["tie"] = tie
        return self

    def default_query(self, query):
        self.params["q.alt"] = query
        return self

    @join_with_separator(separators, "mm", " ")
    def min_should_match(self, *args):
        self._add_items_to_key("mm", *args)
        return self

    def query_type(self, query_type):
        self.params["qt"] = query_type
        return self

    def paginate(self, limit, offset):
        self.params["start"] = limit
        self.params["rows"] = offset
        return self

    def limit(self, limit):
        self.params["rows"] = limit
        return self

    def offset(self, offset):
        self.params["start"] = offset
        return self

    @join_with_separator(separators, "bf", " ")
    def boost(self, *fields):
        self._add_items_to_key("bf", *fields)
        return self

    @join_with_separator(separators, "pf", " ")
    def phrase_boost(self, *fields):
        self._add_items_to_key("pf", *fields)
        return self

    def query_slop(self, slop):
        self.params["qs"] = slop
        return self

    def phrase_slop(self, slop):
        self.params["ps"] = slop
        return self

    def boost_query(self, query):
        self.params.add("bq", query)

    @staticmethod
    def _name_or_val(arg):
        return arg.solr_field_name if hasattr(arg, "solr_field_name") else arg

    # Emulating defaultdict but on MultiDict
    def _add_items_to_key(self, param, *args):
        list_args = self.params.get(param, [])
        list_args.extend([SolrQuery._name_or_val(arg) for arg in args])
        self.params[param] = list_args

    @join_with_separator(separators, "qf", " ")
    def queried_fields(self, *fields):
        self._add_items_to_key("qf", *fields)
        return self

    def dismax_of(self, *fields):
        # Wrapper for queries using the dismax query parser
        self.def_type("dismax")
        self.queried_fields(*fields)
        self.tie(0.1)
        return self

    @join_with_separator(separators, "fl", ",")
    def fields(self, *args):
        self._add_items_to_key("fl", *args)
        return self

    @join_with_separator(separators, "sort", ",")
    def sort_by(self, *args):
        self._add_items_to_key("sort", *args)
        return self

    def indent(self, indent):
        self.params["indent"] = indent
        return self

    def debug(self, debug):
        self.params["debugQuery"] = debug
        return self

    def echo_handler(self, echo):
        self.params["echoHandler"] = echo
        return self

    def echo_params(self, echo):
        self.params["echoParams"] = echo
        return self

    def _execute_search(self):
        return self.conn.search(self)