diff --git a/pandora/document/managers.py b/pandora/document/managers.py index 807b1083..1b6e31ca 100644 --- a/pandora/document/managers.py +++ b/pandora/document/managers.py @@ -4,7 +4,7 @@ from django.db.models import Q, Manager from ox.django.query import QuerySet -def parseCondition(condition, user): +def parseCondition(condition, user, item=None): ''' ''' k = condition.get('key', 'name') @@ -14,6 +14,11 @@ def parseCondition(condition, user): }.get(k, k) if not k: k = 'name' + if item and k == 'description': + item_conditions = condition.copy() + item_conditions['key'] = 'items__itemproperties__description' + return parseCondition(condition, user) | parseCondition(item_condition, user) + v = condition['value'] op = condition.get('operator') if not op: @@ -50,7 +55,7 @@ def parseCondition(condition, user): q = Q(**{key: v}) return q -def parseConditions(conditions, operator, user): +def parseConditions(conditions, operator, user, item=None): ''' conditions: [ { @@ -73,12 +78,12 @@ def parseConditions(conditions, operator, user): for condition in conditions: if 'conditions' in condition: q = parseConditions(condition['conditions'], - condition.get('operator', '&'), user) + condition.get('operator', '&'), user, item) if q: conn.append(q) pass else: - conn.append(parseCondition(condition, user)) + conn.append(parseCondition(condition, user, item)) if conn: q = conn[0] for c in conn[1:]: @@ -95,7 +100,7 @@ class DocumentManager(Manager): def get_query_set(self): return QuerySet(self.model) - def find(self, data, user): + def find(self, data, user, item=None): ''' query: { conditions: [ @@ -121,7 +126,7 @@ class DocumentManager(Manager): qs = self.get_query_set() conditions = parseConditions(data['query'].get('conditions', []), data['query'].get('operator', '&'), - user) + user, item) if conditions: qs = qs.filter(conditions) diff --git a/pandora/document/migrations/0008_item_desciption_sort.py b/pandora/document/migrations/0008_item_desciption_sort.py new file mode 100644 index 00000000..f84935f6 --- /dev/null +++ b/pandora/document/migrations/0008_item_desciption_sort.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'ItemProperties.description_sort' + db.add_column('document_itemproperties', 'description_sort', + self.gf('django.db.models.fields.CharField')(max_length=512, null=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'ItemProperties.description_sort' + db.delete_column('document_itemproperties', 'description_sort') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'document.document': { + 'Meta': {'unique_together': "(('user', 'name', 'extension'),)", 'object_name': 'Document'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'description_sort': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}), + 'dimensions_sort': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'extension': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'documents'", 'symmetrical': 'False', 'through': "orm['document.ItemProperties']", 'to': "orm['item.Item']"}), + 'matches': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'oshash': ('django.db.models.fields.CharField', [], {'max_length': '16', 'unique': 'True', 'null': 'True'}), + 'pages': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'ratio': ('django.db.models.fields.FloatField', [], {'default': '1'}), + 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True'}), + 'uploading': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['auth.User']"}), + 'width': ('django.db.models.fields.IntegerField', [], {'default': '-1'}) + }, + 'document.itemproperties': { + 'Meta': {'unique_together': "(('item', 'document'),)", 'object_name': 'ItemProperties'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'description_sort': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'descriptions'", 'to': "orm['document.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['item.Item']"}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'item.item': { + 'Meta': {'object_name': 'Item'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'data': ('ox.django.fields.DictField', [], {'default': '{}'}), + 'external_data': ('ox.django.fields.DictField', [], {'default': '{}'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'items'", 'blank': 'True', 'to': "orm['auth.Group']"}), + 'icon': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'itemId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}), + 'json': ('ox.django.fields.DictField', [], {'default': '{}'}), + 'level': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'oxdbId': ('django.db.models.fields.CharField', [], {'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'poster': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}), + 'poster_frame': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'poster_source': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'rendered': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'stream_aspect': ('django.db.models.fields.FloatField', [], {'default': '1.3333333333333333'}), + 'stream_info': ('ox.django.fields.DictField', [], {'default': '{}'}), + 'torrent': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '1000', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'null': 'True', 'to': "orm['auth.User']"}) + } + } + + complete_apps = ['document'] \ No newline at end of file diff --git a/pandora/document/models.py b/pandora/document/models.py index 2931602c..00bb26a7 100644 --- a/pandora/document/models.py +++ b/pandora/document/models.py @@ -173,6 +173,8 @@ class Document(models.Model): elif hasattr(self, _map.get(key, key)): response[key] = getattr(self, _map.get(key,key)) or '' if item: + if isinstance(item, basestring): + item = Item.objects.get(itemId=item) d = self.descriptions.filter(item=item) if d.exists(): if 'description' in keys and d[0].description: @@ -299,3 +301,12 @@ class ItemProperties(models.Model): description = models.TextField(default="") index = models.IntegerField(default=0) + description_sort = models.CharField(max_length=512, null=True) + + def save(self, *args, **kwargs): + if self.description: + self.description_sort = ox.sort_string(self.description)[:512].lower() + else: + self.description_sort = self.document.description_sort + + super(ItemProperties, self).save(*args, **kwargs) diff --git a/pandora/document/views.py b/pandora/document/views.py index 553978f3..9916b56d 100644 --- a/pandora/document/views.py +++ b/pandora/document/views.py @@ -77,7 +77,7 @@ def editDocument(request): actions.register(editDocument, cache=False) -def _order_query(qs, sort): +def _order_query(qs, sort, item=None): order_by = [] for e in sort: operator = e['operator'] @@ -85,7 +85,8 @@ def _order_query(qs, sort): operator = '' key = { 'name': 'name_sort', - 'description': 'description_sort', + 'description': 'items__itemproperties__description_sort' + if item else 'description_sort', 'dimensions': 'dimensions_sort', 'index': 'items__itemproperties__index', }.get(e['key'], e['key']) @@ -100,6 +101,12 @@ def _order_query(qs, sort): qs = qs.distinct() return qs +def get_item(query): + for c in query.get('conditions'): + if c.get('key') == 'item': + return c.get('value') + return None + def parse_query(data, user): query = {} query['range'] = [0, 100] @@ -108,6 +115,7 @@ def parse_query(data, user): if key in data: query[key] = data[key] query['qs'] = models.Document.objects.find(data, user).exclude(name='') + query['item'] = get_item(data['query']) return query @@ -144,12 +152,12 @@ def findDocuments(request): query = parse_query(data, request.user) #order - qs = _order_query(query['qs'], query['sort']) + qs = _order_query(query['qs'], query['sort'], query['item']) response = json_response() if 'keys' in data: qs = qs[query['range'][0]:query['range'][1]] - response['data']['items'] = [l.json(data['keys'], request.user) for l in qs] + response['data']['items'] = [l.json(data['keys'], request.user, query['item']) for l in qs] elif 'position' in data: #FIXME: actually implement position requests response['data']['position'] = 0 diff --git a/static/js/documentsPanel.js b/static/js/documentsPanel.js index d3a5f58e..9a44ea70 100644 --- a/static/js/documentsPanel.js +++ b/static/js/documentsPanel.js @@ -550,6 +550,9 @@ pandora.ui.documentsPanel = function(options) { .bindEvent({ change: function(event) { var data = Ox.extend({id: item.id}, event.id, event.data.value); + if (isItemView) { + data.item = ui.item; + } pandora.api.editDocument(data, function(result) { $list.value(result.data.id, event.id, result.data[event.id]); if (event.id == 'name') { @@ -567,7 +570,7 @@ pandora.ui.documentsPanel = function(options) { items: pandora.api.findDocuments, keys: ['dimensions', 'extension', 'id', 'name', 'ratio', 'size'], query: { - conditions: isItemView ? [{ key: 'item', value: ui.item }] : [], + conditions: isItemView ? [{ key: 'item', value: ui.item, operator: '==' }] : [], operator: '&' }, selected: ui.documentsSelection[isItemView ? ui.item : ''], @@ -699,7 +702,7 @@ pandora.ui.documentsPanel = function(options) { query = { conditions: [].concat( isItemView - ? [{ key: 'item', value: ui.item }] + ? [{ key: 'item', value: ui.item, operator: '==' }] : [], value ? {