forked from 0x2620/pandora
cleanup, allow nested conditions
This commit is contained in:
parent
4b7be5402a
commit
bca6408974
3 changed files with 151 additions and 103 deletions
|
@ -21,6 +21,135 @@ def keyType(key):
|
|||
return "float"
|
||||
return "string"
|
||||
|
||||
def parseCondition(condition):
|
||||
'''
|
||||
condition: {
|
||||
value: "war"
|
||||
}
|
||||
or
|
||||
condition: {
|
||||
key: "year",
|
||||
value: "1970-1980,
|
||||
operator: "!="
|
||||
}
|
||||
...
|
||||
'''
|
||||
|
||||
k = condition.get('key', 'all')
|
||||
k = {'id': 'movieId'}.get(k, k)
|
||||
if not k: k = 'all'
|
||||
v = condition['value']
|
||||
op = condition.get('operator', None)
|
||||
if not op: op = '~'
|
||||
if op.startswith('!'):
|
||||
op = op[1:]
|
||||
exclude = True
|
||||
else:
|
||||
exclude = False
|
||||
if keyType(k) == "string":
|
||||
if op == '=':
|
||||
if k in ('director', 'country', 'language', 'genre',
|
||||
'keywords', 'location', 'writer', 'producer',
|
||||
'editor', 'cinematographer'):
|
||||
k = '%s__icontains' % k
|
||||
v = u'|%s|'%v
|
||||
else:
|
||||
k = '%s__iexact' % k
|
||||
elif op == '^':
|
||||
v = v[1:]
|
||||
k = '%s__istartswith' % k
|
||||
elif op == '$':
|
||||
v = v[:-1]
|
||||
k = '%s__iendswith' % k
|
||||
else: # elif op == '~':
|
||||
k = '%s__icontains' % k
|
||||
if not k.startswith('movieId'):
|
||||
k = 'find__%s' % k
|
||||
k = str(k)
|
||||
if exclude:
|
||||
return ~Q(**{k:v})
|
||||
else:
|
||||
return 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('.'))
|
||||
|
||||
k = 'find__%s' % k
|
||||
if exclude: #!1960-1970
|
||||
k1 = str('%s__lt' % k)
|
||||
k2 = str('%s__gte' % k)
|
||||
return Q(**{k1:v1})|Q(**{k2:v2})
|
||||
else: #1960-1970
|
||||
k1 = str('%s__gte' % k)
|
||||
k2 = str('%s__lt' % k)
|
||||
return 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 = 'find__%s' % k
|
||||
k = str(k)
|
||||
if exclude: #!1960
|
||||
return ~Q(**{k:v})
|
||||
else: #1960
|
||||
return Q(**{k:v})
|
||||
|
||||
def parseConditions(conditions, operator):
|
||||
'''
|
||||
conditions: [
|
||||
{
|
||||
value: "war"
|
||||
}
|
||||
{
|
||||
key: "year",
|
||||
value: "1970-1980,
|
||||
operator: "!="
|
||||
},
|
||||
{
|
||||
key: "country",
|
||||
value: "f",
|
||||
operator: "^"
|
||||
}
|
||||
],
|
||||
operator: "&"
|
||||
'''
|
||||
conn = []
|
||||
for condition in conditions:
|
||||
if 'conditions' in condition:
|
||||
q = parseConditions(condition['conditions'],
|
||||
condition.get('operator', '&'))
|
||||
if q: conn.append(q)
|
||||
pass
|
||||
else:
|
||||
conn.append(parseCondition(condition))
|
||||
if conn:
|
||||
q = conn[0]
|
||||
for c in conn[1:]:
|
||||
if operator == '|':
|
||||
q = q | c
|
||||
else:
|
||||
q = q & c
|
||||
return q
|
||||
return None
|
||||
|
||||
class MovieManager(Manager):
|
||||
def get_query_set(self):
|
||||
return super(MovieManager, self).get_query_set()
|
||||
|
@ -59,100 +188,20 @@ class MovieManager(Manager):
|
|||
operator: "^"
|
||||
}
|
||||
],
|
||||
operator: ","
|
||||
operator: "&"
|
||||
}
|
||||
'''
|
||||
query_operator = data['query'].get('operator', ',')
|
||||
conditions = []
|
||||
for condition in data['query']['conditions']:
|
||||
k = condition.get('key', 'all')
|
||||
k = {'id': 'movieId'}.get(k, k)
|
||||
if not k: k = 'all'
|
||||
v = condition['value']
|
||||
op = condition.get('operator', None)
|
||||
if not op: op = '~'
|
||||
if op.startswith('!'):
|
||||
op = op[1:]
|
||||
exclude = True
|
||||
else:
|
||||
exclude = False
|
||||
if keyType(k) == "string":
|
||||
if op == '=':
|
||||
if k in ('director', 'country', 'language', 'genre', 'keywords', 'location', 'writer', 'producer', 'editor', 'cinematographer'):
|
||||
k = '%s__icontains' % k
|
||||
v = u'|%s|'%v
|
||||
else:
|
||||
k = '%s__iexact' % k
|
||||
elif op == '^':
|
||||
v = v[1:]
|
||||
k = '%s__istartswith' % k
|
||||
elif op == '$':
|
||||
v = v[:-1]
|
||||
k = '%s__iendswith' % k
|
||||
else: # elif op == '~':
|
||||
k = '%s__icontains' % k
|
||||
if not k.startswith('movieId'):
|
||||
k = 'find__%s' % k
|
||||
k = str(k)
|
||||
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('.'))
|
||||
|
||||
k = 'find__%s' % k
|
||||
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 = 'find__%s' % k
|
||||
k = str(k)
|
||||
if exclude: #!1960
|
||||
conditions.append(~Q(**{k:v}))
|
||||
else: #1960
|
||||
conditions.append(Q(**{k:v}))
|
||||
|
||||
#join query with operator
|
||||
qs = self.get_query_set()
|
||||
#only include movies that have hard metadata
|
||||
qs = qs.filter(available=True)
|
||||
conditions = parseConditions(data['query']['conditions'],
|
||||
data['query'].get('operator', '&'))
|
||||
if conditions:
|
||||
q = conditions[0]
|
||||
for c in conditions[1:]:
|
||||
if query_operator == '|':
|
||||
q = q | c
|
||||
else:
|
||||
q = q & c
|
||||
qs = qs.filter(q)
|
||||
qs = qs.filter(conditions)
|
||||
|
||||
#FIXME: lists are part of query now
|
||||
# filter list, works for own or public lists
|
||||
l = data.get('list', 'all')
|
||||
qs = self.filter_list(qs, l, user)
|
||||
|
|
|
@ -23,6 +23,11 @@ import load
|
|||
import utils
|
||||
import extract
|
||||
|
||||
def plural_key(term):
|
||||
return {
|
||||
'country': 'countries',
|
||||
}.get(term, term + 's')
|
||||
|
||||
|
||||
def getMovie(info):
|
||||
'''
|
||||
|
@ -242,20 +247,19 @@ class Movie(models.Model):
|
|||
except MovieFind.DoesNotExist:
|
||||
f = MovieFind(movie=self)
|
||||
|
||||
f.title = self.get('title')
|
||||
f.title = '\n'.join([self.get('title'), self.get('original_title', '')])
|
||||
#FIXME: filter us/int title
|
||||
#f.title += ' '.join([t.title for t in self.alternative_titles()])
|
||||
f.director = '|%s|'%'|'.join(self.get('directors', []))
|
||||
f.country = '|%s|'%'|'.join(self.get('countries', []))
|
||||
|
||||
f.year = self.get('year', '')
|
||||
for key in ('language', 'writer', 'producer', 'editor', 'cinematographer'):
|
||||
setattr(f, key, '|%s|'%'|'.join(self.get('%ss'%key, [])))
|
||||
|
||||
for key in ('directors', 'country', 'language', 'writer', 'producer',
|
||||
'editor', 'cinematographer', 'genre', 'keyword'):
|
||||
setattr(f, key, '|%s|'%'|'.join(self.get(plural_key(key), [])))
|
||||
|
||||
f.actor = '|%s|'%'|'.join([i[0] for i in self.get('actor', [])])
|
||||
f.character = '|%s|'%'|'.join([stripTagsl(i[1]) for i in self.get('actor', [])])
|
||||
|
||||
f.genre = '|%s|'%'|'.join(self.get('genres', []))
|
||||
f.keyword = '|%s|'%'|'.join(self.get('keywords', []))
|
||||
f.summary = self.get('plot', '') + self.get('plot_outline', '')
|
||||
f.trivia = ' '.join(self.get('trivia', []))
|
||||
f.location = '|%s|'%'|'.join(self.get('filming_locations', []))
|
||||
|
@ -302,10 +306,11 @@ class Movie(models.Model):
|
|||
s.year = self.get('year', '')
|
||||
|
||||
for key in ('director', 'writer', 'producer', 'editor', 'cinematographer'):
|
||||
setattr(s, key, sortNames(self.get('%ss'%key, [])))
|
||||
setattr(s, key, sortNames(self.get(plural_key(key), [])))
|
||||
|
||||
for key in ('language', 'country'):
|
||||
setattr(s, key, ','.join(self.get(plural_key(key), [])))
|
||||
|
||||
s.language = ','.join(self.get('languages', []))
|
||||
s.country = ','.join(self.get('countries', []))
|
||||
s.runtime = self.get('runtime', 0)
|
||||
|
||||
s.keywords = len(self.get('keywords', []))
|
||||
|
@ -347,12 +352,8 @@ class Movie(models.Model):
|
|||
def updateFacets(self):
|
||||
#"year", is extra is it?
|
||||
#FIXME: what to do with Unkown Director, Year, Country etc.
|
||||
def plural(term):
|
||||
return {
|
||||
'country': 'countries',
|
||||
}.get(term, term + 's')
|
||||
for key in ("director", "country", "language", "genre"):
|
||||
current_values = self.get(plural(key), [])
|
||||
for key in ("director", "country", 'writer', 'producer', 'editor', 'cinematographer', "language", "genre"):
|
||||
current_values = self.get(plural_key(key), [])
|
||||
saved_values = [i.value for i in Facet.objects.filter(movie=self, key=key)]
|
||||
removed_values = filter(lambda x: x not in current_values, saved_values)
|
||||
if removed_values:
|
||||
|
|
|
@ -188,7 +188,6 @@ Positions
|
|||
query['sort'].append({'key': 'name', 'operator':'+'})
|
||||
else:
|
||||
query['sort'] = [{'key': 'name', 'operator':'+'}]
|
||||
#FIXME: also filter lists here
|
||||
response['data']['items'] = []
|
||||
items = 'movies'
|
||||
movie_qs = query['qs']
|
||||
|
@ -237,7 +236,6 @@ Positions
|
|||
qs = qs[query['range'][0]:query['range'][1]]
|
||||
response['data']['items'] = [only_p(m['json']) for m in qs.values('json')]
|
||||
else: # otherwise stats
|
||||
#movies = models.Movie.objects.filter(available=True)
|
||||
movies = query['qs']
|
||||
files = File.objects.all().filter(movie__in=movies)
|
||||
r = files.aggregate(
|
||||
|
|
Loading…
Reference in a new issue