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 "float"
|
||||||
return "string"
|
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):
|
class MovieManager(Manager):
|
||||||
def get_query_set(self):
|
def get_query_set(self):
|
||||||
return super(MovieManager, self).get_query_set()
|
return super(MovieManager, self).get_query_set()
|
||||||
|
@ -59,100 +188,20 @@ class MovieManager(Manager):
|
||||||
operator: "^"
|
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
|
#join query with operator
|
||||||
qs = self.get_query_set()
|
qs = self.get_query_set()
|
||||||
#only include movies that have hard metadata
|
#only include movies that have hard metadata
|
||||||
qs = qs.filter(available=True)
|
qs = qs.filter(available=True)
|
||||||
|
conditions = parseConditions(data['query']['conditions'],
|
||||||
|
data['query'].get('operator', '&'))
|
||||||
if conditions:
|
if conditions:
|
||||||
q = conditions[0]
|
qs = qs.filter(conditions)
|
||||||
for c in conditions[1:]:
|
|
||||||
if query_operator == '|':
|
|
||||||
q = q | c
|
|
||||||
else:
|
|
||||||
q = q & c
|
|
||||||
qs = qs.filter(q)
|
|
||||||
|
|
||||||
|
#FIXME: lists are part of query now
|
||||||
# filter list, works for own or public lists
|
# filter list, works for own or public lists
|
||||||
l = data.get('list', 'all')
|
l = data.get('list', 'all')
|
||||||
qs = self.filter_list(qs, l, user)
|
qs = self.filter_list(qs, l, user)
|
||||||
|
|
|
@ -23,6 +23,11 @@ import load
|
||||||
import utils
|
import utils
|
||||||
import extract
|
import extract
|
||||||
|
|
||||||
|
def plural_key(term):
|
||||||
|
return {
|
||||||
|
'country': 'countries',
|
||||||
|
}.get(term, term + 's')
|
||||||
|
|
||||||
|
|
||||||
def getMovie(info):
|
def getMovie(info):
|
||||||
'''
|
'''
|
||||||
|
@ -242,20 +247,19 @@ class Movie(models.Model):
|
||||||
except MovieFind.DoesNotExist:
|
except MovieFind.DoesNotExist:
|
||||||
f = MovieFind(movie=self)
|
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
|
#FIXME: filter us/int title
|
||||||
#f.title += ' '.join([t.title for t in self.alternative_titles()])
|
#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', '')
|
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.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.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.summary = self.get('plot', '') + self.get('plot_outline', '')
|
||||||
f.trivia = ' '.join(self.get('trivia', []))
|
f.trivia = ' '.join(self.get('trivia', []))
|
||||||
f.location = '|%s|'%'|'.join(self.get('filming_locations', []))
|
f.location = '|%s|'%'|'.join(self.get('filming_locations', []))
|
||||||
|
@ -302,10 +306,11 @@ class Movie(models.Model):
|
||||||
s.year = self.get('year', '')
|
s.year = self.get('year', '')
|
||||||
|
|
||||||
for key in ('director', 'writer', 'producer', 'editor', 'cinematographer'):
|
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.runtime = self.get('runtime', 0)
|
||||||
|
|
||||||
s.keywords = len(self.get('keywords', []))
|
s.keywords = len(self.get('keywords', []))
|
||||||
|
@ -347,12 +352,8 @@ class Movie(models.Model):
|
||||||
def updateFacets(self):
|
def updateFacets(self):
|
||||||
#"year", is extra is it?
|
#"year", is extra is it?
|
||||||
#FIXME: what to do with Unkown Director, Year, Country etc.
|
#FIXME: what to do with Unkown Director, Year, Country etc.
|
||||||
def plural(term):
|
for key in ("director", "country", 'writer', 'producer', 'editor', 'cinematographer', "language", "genre"):
|
||||||
return {
|
current_values = self.get(plural_key(key), [])
|
||||||
'country': 'countries',
|
|
||||||
}.get(term, term + 's')
|
|
||||||
for key in ("director", "country", "language", "genre"):
|
|
||||||
current_values = self.get(plural(key), [])
|
|
||||||
saved_values = [i.value for i in Facet.objects.filter(movie=self, 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)
|
removed_values = filter(lambda x: x not in current_values, saved_values)
|
||||||
if removed_values:
|
if removed_values:
|
||||||
|
|
|
@ -188,7 +188,6 @@ Positions
|
||||||
query['sort'].append({'key': 'name', 'operator':'+'})
|
query['sort'].append({'key': 'name', 'operator':'+'})
|
||||||
else:
|
else:
|
||||||
query['sort'] = [{'key': 'name', 'operator':'+'}]
|
query['sort'] = [{'key': 'name', 'operator':'+'}]
|
||||||
#FIXME: also filter lists here
|
|
||||||
response['data']['items'] = []
|
response['data']['items'] = []
|
||||||
items = 'movies'
|
items = 'movies'
|
||||||
movie_qs = query['qs']
|
movie_qs = query['qs']
|
||||||
|
@ -237,7 +236,6 @@ Positions
|
||||||
qs = qs[query['range'][0]:query['range'][1]]
|
qs = qs[query['range'][0]:query['range'][1]]
|
||||||
response['data']['items'] = [only_p(m['json']) for m in qs.values('json')]
|
response['data']['items'] = [only_p(m['json']) for m in qs.values('json')]
|
||||||
else: # otherwise stats
|
else: # otherwise stats
|
||||||
#movies = models.Movie.objects.filter(available=True)
|
|
||||||
movies = query['qs']
|
movies = query['qs']
|
||||||
files = File.objects.all().filter(movie__in=movies)
|
files = File.objects.all().filter(movie__in=movies)
|
||||||
r = files.aggregate(
|
r = files.aggregate(
|
||||||
|
|
Loading…
Reference in a new issue