From 26ad07e3e85149db51423f3bf4f2c8976699b492 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Tue, 6 Jul 2010 10:51:50 +0200 Subject: [PATCH] haystack --- pandora/backend/managers.py | 113 +++++++++++++++++++++++++++++++++++- pandora/backend/views.py | 2 +- pandora/settings.py | 6 ++ requirements.txt | 2 + 4 files changed, 120 insertions(+), 3 deletions(-) diff --git a/pandora/backend/managers.py b/pandora/backend/managers.py index a0cb622..c54603e 100644 --- a/pandora/backend/managers.py +++ b/pandora/backend/managers.py @@ -8,7 +8,8 @@ import json from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q, Manager - +from haystack.query import SearchQuerySet + import models @@ -41,7 +42,7 @@ class MovieManager(Manager): qs = qs.filter(listitem__list__id=lqs[0].id) return qs - def find(self, data, user): + def finddb(self, data, user): ''' query: { conditions: [ @@ -158,6 +159,114 @@ class MovieManager(Manager): qs = self.filter_list(qs, l, user) return qs + def find(self, data, user): + ''' + query: { + conditions: [ + { + value: "war"" + } + { + key: "year", + value: "1970-1980, + operator: "!=" + }, + { + key: "country", + value: "f", + operator: "^" + } + ], + operator: "&" + } + ''' + qs = SearchQuerySet() + query_operator = data['query'].get('operator', '&') + conditions = [] + for condition in data['query']['conditions']: + k = condition.get('key', 'all') + v = qs.query.clean(condition['value']) + op = condition.get('operator', None) + if op.startswith('!'): + op = op[1:] + exclude = True + else: + exclude = False + if keyType(k) == "string": + if op == '=': + k = '%s__exact' % k + elif op == '^': + v = v[1:] + k = '%s__startswith' % k + elif op == '$': + v = v[:-1] + k = '%s__endswith' % k + else: # elif op == '~': + k = '%s' % k + k = str(k) + print k,v + if exclude: + conditions.append(~Q(**{k:v})) + else: + conditions.append(Q(**{k:v})) + else: #number or date + def parseDate(d): + while len(d) < 3: + d.append(1) + return datetime(*[int(i) for i in d]) + if op == '-': + v1 = v[1] + v2 = v[2] + if keyType(k) == "date": + v1 = parseDate(v1.split('.')) + v2 = parseDate(v2.split('.')) + + if exclude: #!1960-1970 + k1 = str('%s__lt' % k) + k2 = str('%s__gte' % k) + conditions.append(Q(**{k1:v1})|Q(**{k2:v2})) + else: #1960-1970 + k1 = str('%s__gte' % k) + k2 = str('%s__lt' % k) + conditions.append(Q(**{k1:v1})&Q(**{k2:v2})) + else: + if keyType(k) == "date": + v = parseDate(v.split('.')) + if op == '=': + k = '%s__exact' % k + elif op == '>': + k = '%s__gt' % k + elif op == '>=': + k = '%s__gte' % k + elif op == '<': + k = '%s__lt' % k + elif op == '<=': + k = '%s__lte' % k + + k = str(k) + print k,v + if exclude: #!1960 + conditions.append(~Q(**{k:v})) + else: #1960 + conditions.append(Q(**{k:v})) + + #join query with operator + #only include movies that have hard metadata + qs = qs.filter(available=True) + if conditions: + q = conditions[0] + for c in conditions[1:]: + if query_operator == '|': + q = q | c + else: + q = q & c + qs = qs.filter(q) + return qs + # filter list, works for own or public lists + l = data.get('list', 'all') + qs = self.filter_list(qs, l, user) + return qs + class FileManager(Manager): def get_query_set(self): return super(FileManager, self).get_query_set() diff --git a/pandora/backend/views.py b/pandora/backend/views.py index 30163d2..57c3d8d 100644 --- a/pandora/backend/views.py +++ b/pandora/backend/views.py @@ -95,7 +95,7 @@ def _parse_query(data, user): for key in ('sort', 'keys', 'group', 'list', 'range', 'ids'): if key in data: query[key] = data[key] - query['qs'] = models.Movie.objects.find(data, user) + query['qs'] = models.Movie.objects.finddb(data, user) #group by only allows sorting by name or number of itmes return query diff --git a/pandora/settings.py b/pandora/settings.py index 4c842d1..88c990f 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -40,6 +40,11 @@ BROKER_USER = "pandora" BROKER_PASSWORD = "box" BROKER_VHOST = "/pandora" + +HAYSTACK_SITECONF='backend.find' +HAYSTACK_SOLR_URL = 'http://127.0.0.1:8983/solr' +HAYSTACK_SEARCH_ENGINE = 'solr' + # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. @@ -109,6 +114,7 @@ INSTALLED_APPS = ( 'south', 'djcelery', + 'haystack', 'app', 'backend', 'oxuser', diff --git a/requirements.txt b/requirements.txt index 18c97f9..130cd0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,5 @@ django_extensions -e bzr+http://firefogg.org/dev/python-firefogg/#egg=python-firefogg -e git+git://github.com/dcramer/django-devserver#egg=django_devserver transmissionrpc +-e git+git://github.com/toastdriven/django-haystack.git#egg=django-haystack +pysolr