correct data import (on tags)
authorymh <ymh.work@gmail.com>
Wed, 13 Feb 2013 10:13:56 +0100
changeset 36 daa526d27044
parent 35 365c73a0e8c1
child 37 3f2e65ff8169
correct data import (on tags) add indexation and very first version of serach
src/egonomy/__init__.py
src/egonomy/config.py.tmpl
src/egonomy/management/commands/importRmn.py
src/egonomy/migrations/0001_initial.py
src/egonomy/migrations/0002_update_site.py
src/egonomy/search_indexes/__init__.py
src/egonomy/search_indexes/backends/__init__.py
src/egonomy/search_indexes/backends/elasticsearch_backend.py
src/egonomy/search_indexes/indexes.py
src/egonomy/search_indexes/processor.py
src/egonomy/search_indexes/query_parser.py
src/egonomy/settings.py
src/egonomy/templates/egonomy_base.html
src/egonomy/templates/search/indexes/egonomy/fragment_text.txt
src/egonomy/templates/search/indexes/egonomy/imagemetadata_text.txt
src/egonomy/views.py
virtualenv/res/lib/lib_create_env.py
virtualenv/res/src/django-haystack-V2.0.0-beta.tar.gz
virtualenv/res/src/django-haystack-v2.0.0.tar.gz
--- a/src/egonomy/__init__.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/__init__.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,17 @@
+VERSION = (0, 0, 0, "alpha", 0)
+
+VERSION_STR = unicode(".".join(map(lambda i:"%02d" % (i,), VERSION[:2])))
+
+
+def get_version():
+    version = '%s.%s' % (VERSION[0], VERSION[1])
+    if VERSION[2]:
+        version = '%s.%s' % (version, VERSION[2])
+    if VERSION[3:] == ('alpha', 0):
+        version = '%s pre-alpha' % version
+    else:
+        if VERSION[3] != 'final':
+            version = '%s %s %s' % (version, VERSION[3], VERSION[4])
+    return version
+
+__version__ = get_version()
--- a/src/egonomy/config.py.tmpl	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/config.py.tmpl	Wed Feb 13 10:13:56 2013 +0100
@@ -20,6 +20,14 @@
     }
 }
 
+HAYSTACK_CONNECTIONS = {
+    'default': {
+        'ENGINE': 'egonomy.search_indexes.backends.elasticsearch_backend.ElasticsearchSearchEngine',
+        'URL': 'http://127.0.0.1:9200/',
+        'INDEX_NAME': 'egonomy',
+    },
+}
+
 # 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.
@@ -122,3 +130,5 @@
         'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
     },
 }
+
+IMAGES_PER_PAGE = 32
--- a/src/egonomy/management/commands/importRmn.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/management/commands/importRmn.py	Wed Feb 13 10:13:56 2013 +0100
@@ -203,7 +203,7 @@
                                 site = self.__safe_get(urow, 'SITE'),
                                 lieu = self.__safe_get(urow, 'LIEU'),
                                 localisation = self.__safe_get(urow, 'LOCALISATION'),
-                                mots_cles = self.__safe_get(urow, 'MOT_CLES')                            
+                                mots_cles = self.__safe_get(urow, 'MOTS_CLES')                            
                             )                        
     
                             img_info_obj = None
--- a/src/egonomy/migrations/0001_initial.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/migrations/0001_initial.py	Wed Feb 13 10:13:56 2013 +0100
@@ -1,15 +1,13 @@
 # -*- 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 model 'ImageMetadata'
-        db.create_table(u'egonomy_imagemetadata', (
+        db.create_table(u'egonomy_imagemetadata', ( #@UndefinedVariable
             ('id', self.gf('django.db.models.fields.CharField')(max_length=15, primary_key=True)),
             ('date_inserted', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
             ('date_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
@@ -36,10 +34,10 @@
             ('description_pertimm', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
             ('thesaurus_pertimm', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
         ))
-        db.send_create_signal(u'egonomy', ['ImageMetadata'])
+        db.send_create_signal(u'egonomy', ['ImageMetadata']) #@UndefinedVariable
 
         # Adding model 'ImageInfo'
-        db.create_table(u'egonomy_imageinfo', (
+        db.create_table(u'egonomy_imageinfo', ( #@UndefinedVariable
             ('id', self.gf('django.db.models.fields.CharField')(max_length=15, primary_key=True)),
             ('image_file', self.gf('django.db.models.fields.files.ImageField')(max_length=2048)),
             ('width', self.gf('django.db.models.fields.IntegerField')()),
@@ -47,18 +45,18 @@
             ('mimetype', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True, blank=True)),
             ('exif', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
         ))
-        db.send_create_signal(u'egonomy', ['ImageInfo'])
+        db.send_create_signal(u'egonomy', ['ImageInfo']) #@UndefinedVariable
 
         # Adding model 'Image'
-        db.create_table(u'egonomy_image', (
+        db.create_table(u'egonomy_image', ( #@UndefinedVariable
             ('id', self.gf('django.db.models.fields.CharField')(max_length=15, primary_key=True)),
             ('metadata', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['egonomy.ImageMetadata'])),
             ('info', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['egonomy.ImageInfo'], null=True, blank=True)),
         ))
-        db.send_create_signal(u'egonomy', ['Image'])
+        db.send_create_signal(u'egonomy', ['Image']) #@UndefinedVariable
 
         # Adding model 'Fragment'
-        db.create_table(u'egonomy_fragment', (
+        db.create_table(u'egonomy_fragment', ( #@UndefinedVariable
             (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
             ('image', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['egonomy.Image'])),
             ('date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
@@ -69,21 +67,21 @@
             ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
             ('tags', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
         ))
-        db.send_create_signal(u'egonomy', ['Fragment'])
+        db.send_create_signal(u'egonomy', ['Fragment']) #@UndefinedVariable
 
 
     def backwards(self, orm):
         # Deleting model 'ImageMetadata'
-        db.delete_table(u'egonomy_imagemetadata')
+        db.delete_table(u'egonomy_imagemetadata') #@UndefinedVariable
 
         # Deleting model 'ImageInfo'
-        db.delete_table(u'egonomy_imageinfo')
+        db.delete_table(u'egonomy_imageinfo') #@UndefinedVariable
 
         # Deleting model 'Image'
-        db.delete_table(u'egonomy_image')
+        db.delete_table(u'egonomy_image') #@UndefinedVariable
 
         # Deleting model 'Fragment'
-        db.delete_table(u'egonomy_fragment')
+        db.delete_table(u'egonomy_fragment') #@UndefinedVariable
 
 
     models = {
--- a/src/egonomy/migrations/0002_update_site.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/migrations/0002_update_site.py	Wed Feb 13 10:13:56 2013 +0100
@@ -1,9 +1,6 @@
 # -*- coding: utf-8 -*-
-import datetime
-from south.db import db
 from south.v2 import DataMigration
 from django.conf import settings
-from django.db import models
 
 class Migration(DataMigration):
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/search_indexes/__init__.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,6 @@
+
+from .indexes import FragmentIndex,ImageMetadataIndex
+from .processor import EgonomySignalProcessor
+from .query_parser import QueryParser
+
+__all__ = ['FragmentIndex', 'ImageMetadataIndex', 'EgonomySignalProcessor', 'QueryParser']
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/search_indexes/backends/elasticsearch_backend.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Feb 12, 2013
+
+@author: ymh
+'''
+
+from django.db.models.loading import get_model
+from egonomy.models import ImageMetadata, Fragment
+from haystack.backends import BaseEngine, SearchResult, elasticsearch_backend
+from haystack.constants import DJANGO_CT, DJANGO_ID
+import datetime
+
+class ElasticsearchSearchBackend(elasticsearch_backend.ElasticsearchSearchBackend):
+
+    def build_search_kwargs(self, query_string, sort_by=None, start_offset=0, end_offset=None,
+                        fields='', highlight=False, facets=None,
+                        date_facets=None, query_facets=None,
+                        narrow_queries=None, spelling_query=None,
+                        within=None, dwithin=None, distance_point=None,
+                        models=None, limit_to_registered_models=None,
+                        result_class=None):
+        
+        kwargs = super(ElasticsearchSearchBackend, self).build_search_kwargs(query_string, sort_by=sort_by, start_offset=start_offset, end_offset=end_offset,
+                        fields=fields, highlight=highlight, facets=facets,
+                        date_facets=date_facets, query_facets=query_facets,
+                        narrow_queries=narrow_queries, spelling_query=spelling_query,
+                        within=within, dwithin=dwithin, distance_point=distance_point,
+                        models=models, limit_to_registered_models=limit_to_registered_models,
+                        result_class=result_class)
+                
+        #TODO : try to make list of field dynamic
+        #TODO : How to handle multiple 
+        if highlight:
+            highlight_def = kwargs.get('highlight', {})
+            
+            fields_def = highlight_def.get('fields', {})
+ 
+            if models is None or len(models) == 0 or ImageMetadata in models or Fragment in models:
+                fields_def['tags'] = {}
+                fields_def['title'] = {}
+                fields_def['description'] = {}
+            
+            kwargs['highlight'] = highlight_def.update({
+                'pre_tags' : ["<span class='highlight'>"],
+                'post_tags' : ["</span>"],
+                "number_of_fragments" : 0,
+                'fields': fields_def                
+            })
+        
+        return kwargs
+
+    def _process_results(self, raw_results, highlight=False,
+                         result_class=None, distance_point=None,
+                         geo_sort=False):
+        from haystack import connections
+        results = []
+        hits = raw_results.get('hits', {}).get('total', 0)
+        facets = {}
+        spelling_suggestion = None
+
+        if result_class is None:
+            result_class = SearchResult
+
+        if 'facets' in raw_results:
+            facets = {
+                'fields': {},
+                'dates': {},
+                'queries': {},
+            }
+
+            for facet_fieldname, facet_info in raw_results['facets'].items():
+                if facet_info.get('_type', 'terms') == 'terms':
+                    facets['fields'][facet_fieldname] = [(individual['term'], individual['count']) for individual in facet_info['terms']]
+                elif facet_info.get('_type', 'terms') == 'date_histogram':
+                    # Elasticsearch provides UTC timestamps with an extra three
+                    # decimals of precision, which datetime barfs on.
+                    facets['dates'][facet_fieldname] = [(datetime.datetime.utcfromtimestamp(individual['time'] / 1000), individual['count']) for individual in facet_info['entries']]
+                elif facet_info.get('_type', 'terms') == 'query':
+                    facets['queries'][facet_fieldname] = facet_info['count']
+
+        unified_index = connections[self.connection_alias].get_unified_index()
+        indexed_models = unified_index.get_indexed_models()
+
+        for raw_result in raw_results.get('hits', {}).get('hits', []):
+            source = raw_result['_source']
+            app_label, model_name = source[DJANGO_CT].split('.')
+            additional_fields = {}
+            model = get_model(app_label, model_name)
+
+            if model and model in indexed_models:
+                for key, value in source.items():
+                    index = unified_index.get_index(model)
+                    string_key = str(key)
+
+                    if string_key in index.fields and hasattr(index.fields[string_key], 'convert'):
+                        additional_fields[string_key] = index.fields[string_key].convert(value)
+                    else:
+                        additional_fields[string_key] = self.conn.to_python(value)
+
+                del(additional_fields[DJANGO_CT])
+                del(additional_fields[DJANGO_ID])
+
+                if 'highlight' in raw_result:
+                    additional_fields['highlighted'] = raw_result['highlight']
+
+                if distance_point:
+                    additional_fields['_point_of_origin'] = distance_point
+
+                    if geo_sort and raw_result.get('sort'):
+                        from haystack.utils.geo import Distance
+                        additional_fields['_distance'] = Distance(km=float(raw_result['sort'][0]))
+                    else:
+                        additional_fields['_distance'] = None
+
+                result = result_class(app_label, model_name, source[DJANGO_ID], raw_result['_score'], **additional_fields)
+                results.append(result)
+            else:
+                hits -= 1
+
+        return {
+            'results': results,
+            'hits': hits,
+            'facets': facets,
+            'spelling_suggestion': spelling_suggestion,
+        }
+    
+
+class ElasticsearchSearchEngine(BaseEngine):
+    backend = ElasticsearchSearchBackend
+    query = elasticsearch_backend.ElasticsearchSearchQuery
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/search_indexes/indexes.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Feb 12, 2013
+
+@author: ymh
+'''
+
+from haystack import indexes
+from egonomy.models import ImageMetadata
+from egonomy.models import Fragment
+
+
+class ImageMetadataIndex(indexes.SearchIndex, indexes.Indexable):
+    
+    text = indexes.CharField(document=True, use_template=True)
+    
+    id = indexes.CharField(model_attr='id', indexed=False, stored=True)
+    title = indexes.CharField(model_attr='titre', null=True)
+    description = indexes.CharField(model_attr='description', null=True)
+    photograph = indexes.CharField(model_attr='photographe', null=True)
+    author = indexes.CharField(model_attr='auteur', null=True)
+    period = indexes.CharField(model_attr='periode', null=True)
+    technic = indexes.CharField(model_attr='technique', null=True)
+    site = indexes.CharField(model_attr='site', null=True)
+    location = indexes.CharField(model_attr='lieu', null=True)
+    localization = indexes.CharField(model_attr='localisation', null=True)
+    tags = indexes.CharField(model_attr='mots_cles', null=True)
+    
+    def get_model(self):
+        return ImageMetadata
+
+
+class FragmentIndex(indexes.SearchIndex, indexes.Indexable):
+    
+    text = indexes.CharField(document=True, use_template=True)
+    
+    id = indexes.IntegerField(model_attr='id', indexed=False, stored=True)
+    image = indexes.CharField(model_attr='image', indexed=False, stored=True)
+    author = indexes.CharField(model_attr='author', null=True)
+    title = indexes.CharField(model_attr='title', null=True)
+    description = indexes.CharField(model_attr='description', null=True)
+    tags = indexes.CharField(model_attr='tags', null=True)
+    
+    def get_model(self):
+        return Fragment
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/search_indexes/processor.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Feb 12, 2013
+
+@author: ymh
+'''
+
+from egonomy.models import Fragment
+from django.db import models
+from haystack import signals
+
+class EgonomySignalProcessor(signals.BaseSignalProcessor):
+    def setup(self):
+        # Listen only to the ``User`` model.
+        models.signals.post_save.connect(self.handle_save, sender=Fragment)
+        models.signals.post_delete.connect(self.handle_delete, sender=Fragment)
+
+    def teardown(self):
+        # Disconnect only for the ``User`` model.
+        models.signals.post_save.disconnect(self.handle_save, sender=Fragment)
+        models.signals.post_delete.disconnect(self.handle_delete, sender=Fragment)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/search_indexes/query_parser.py	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Aug 1, 2012
+
+@author: ymh
+'''
+
+#TODO: unitest for 
+
+from whoosh.qparser import SimpleParser, FieldsPlugin, OperatorsPlugin, PhrasePlugin, SingleQuotePlugin, GroupPlugin, PrefixPlugin, GtLtPlugin, RangePlugin
+from whoosh.query import Term, And, AndMaybe, Or, AndNot, Not, Phrase, Prefix, TermRange
+from haystack.query import SQ
+from django.conf import settings
+
+HAYSTACK_DEFAULT_OPERATOR = getattr(settings,'HAYSTACK_DEFAULT_OPERATOR','AND')
+
+class QueryParser(object):
+
+
+    def __init__(self, fieldname):
+        '''
+        Constructor
+        '''
+        self.w_parser = SimpleParser(fieldname, None)
+        self.w_parser.add_plugin(FieldsPlugin())
+        self.w_parser.add_plugin(OperatorsPlugin())
+        self.w_parser.add_plugin(PhrasePlugin())
+        self.w_parser.add_plugin(SingleQuotePlugin())
+        self.w_parser.add_plugin(GroupPlugin())
+        self.w_parser.add_plugin(PrefixPlugin())
+        self.w_parser.add_plugin(GtLtPlugin())
+        self.w_parser.add_plugin(RangePlugin())
+        self.query = None
+        self.current_node_stack = []        
+        
+    def parse(self, query):
+        
+        self.query = SQ()
+        self.current_node_stack = [(self.query, HAYSTACK_DEFAULT_OPERATOR)]
+
+        wquery = self.w_parser.parse(query)
+        
+        self.visit(wquery)
+        
+        if len(self.query) == 1 and isinstance(self.query.children[0], SQ):
+            return self.query.children[0]
+        else:
+            return self.query 
+        
+        
+    def visit(self, q):
+        
+        if isinstance(q, Term):
+            current_node, current_connector = self.current_node_stack.pop() 
+            current_node.add(SQ(**{q.fieldname:q.text}), current_connector)
+            self.current_node_stack.append((current_node,current_connector))
+        elif isinstance(q, And):
+            self._add_compound_query(q, SQ.AND)
+        elif isinstance(q, AndMaybe):
+            self._add_andmaybe(q)
+        elif isinstance(q, Or):
+            self._add_compound_query(q, SQ.OR)
+        elif isinstance(q, AndNot):
+            self._add_andnot(q)
+        elif isinstance(q, Not):
+            self._add_not(q)
+        elif isinstance(q, Phrase):
+            self._add_phrase(q)
+        elif isinstance(q, Prefix):
+            self._add_prefix(q)
+        elif isinstance(q, TermRange):
+            self._add_range(q)
+            
+    def _add_compound_query(self, q, connector):
+
+        new_node = SQ()
+        self.current_node_stack.append((new_node, connector))
+        for subquery in q.subqueries:
+            self.visit(subquery)
+        self.current_node_stack.pop()
+                        
+        if len(new_node)==1 and isinstance(new_node.children[0], SQ) :
+            new_node = new_node.children[0]
+        
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+        
+        
+    def _add_andnot(self, q):
+        
+        new_node = SQ()
+        self.current_node_stack.append((new_node, SQ.AND))
+        self.visit(q.a)
+        self.visit(Not(q.b))
+        self.current_node_stack.pop()
+        
+        if len(new_node)==1 and isinstance(new_node.children[0], SQ) :
+            new_node = new_node.children[0]
+        
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+
+    def _add_andmaybe(self, q):
+        
+        new_node = SQ()
+        self.current_node_stack.append((new_node, SQ.AND))
+        self.visit(q.a)
+        self.visit(q.b)
+        self.current_node_stack.pop()
+        
+        if len(new_node)==1 and isinstance(new_node.children[0], SQ) :
+            new_node = new_node.children[0]
+        
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+
+        
+    def _add_not(self, q):
+        
+        new_node = SQ()
+        self.current_node_stack.append((new_node, SQ.AND))
+        self.visit(q.query)
+        self.current_node_stack.pop()
+        
+        if len(new_node)==1 and isinstance(new_node.children[0], SQ) :
+            new_node = new_node.children[0]
+            
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(~new_node, current_connector)
+        
+    def _add_phrase(self, q):
+        new_node = SQ(**{q.fieldname+"__exact":" ".join(q.words)})            
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+
+    def _add_prefix(self, q):
+        new_node = SQ(**{q.fieldname+"__startswith":q.text})            
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+
+    def _add_range(self, q):
+        
+        if q.start is None:
+            if q.endexcl:
+                postfix = "__lt"
+            else:
+                postfix = "__lte"
+            new_node = SQ(**{q.fieldname+postfix:self.__convert_nb(q.end)})
+        elif q.end is None:
+            if q.startexcl:
+                postfix = "__gt"
+            else:
+                postfix = "__gte"
+            new_node = SQ(**{q.fieldname+postfix:self.__convert_nb(q.start)})
+        else:
+            new_node = SQ(**{q.fieldname+"__range":[self.__convert_nb(q.start),self.__convert_nb(q.end)]})
+        
+        current_node, current_connector = self.current_node_stack[-1]
+        current_node.add(new_node, current_connector)
+
+    def __convert_nb(self, str_nb):        
+        try:
+            res = int(str_nb)
+            return res
+        except ValueError:
+            try:
+                res = float(str_nb)
+                return res
+            except ValueError:
+                return str_nb
+        
+        
+        
\ No newline at end of file
--- a/src/egonomy/settings.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/settings.py	Wed Feb 13 10:13:56 2013 +0100
@@ -21,6 +21,14 @@
     }
 }
 
+HAYSTACK_CONNECTIONS = {
+    'default': {
+        'ENGINE': '',
+        'URL': '',
+        'INDEX_NAME': '',
+    },
+}
+
 # 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.
@@ -121,6 +129,7 @@
     'django_extensions',
     'south',
     'sorl.thumbnail',
+    'haystack',
     'egonomy',
 )
 
@@ -159,6 +168,9 @@
     }
 }
 
+
+HAYSTACK_SIGNAL_PROCESSOR = 'egonomy.search_indexes.EgonomySignalProcessor'
+
 from .config import * #@UnusedWildImport
 
 if not "SRC_BASE_URL" in locals():
@@ -167,3 +179,5 @@
 if not "LOGIN_URL" in locals():
     LOGIN_URL = SRC_BASE_URL + 'login/'
 
+if not "IMAGES_PER_PAGE" in locals():
+    IMAGES_PER_PAGE = 32
--- a/src/egonomy/templates/egonomy_base.html	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/templates/egonomy_base.html	Wed Feb 13 10:13:56 2013 +0100
@@ -20,7 +20,7 @@
         <div class="header-wrap fullwidth">
             <header>
                 <h1 class="column column-third"><a href="{% url 'home' %}">TagItAll {% trans "by" %} eGonomy</a></h1>
-                <form class="column column-third" action="{% url 'home' %}" method="GET">
+                <form class="column column-third" action="." method="GET">
                     <input class="search-field" type="search" placeholder="{% trans 'Search' %}" id="id_search" name="search"/>
                     <input type="hidden" value="all" name="field">
                 </form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/search/indexes/egonomy/fragment_text.txt	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,4 @@
+{{ object.title }}
+{{ object.description }}
+{{ object.tags }}
+{{ object.author.name }}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/search/indexes/egonomy/imagemetadata_text.txt	Wed Feb 13 10:13:56 2013 +0100
@@ -0,0 +1,9 @@
+{{ object.titre }}
+{{ object.description }}
+{{ object.photographe }}
+{{ object.auteur }}
+{{ object.periode }}
+{{ object.site }}
+{{ object.lieu }}
+{{ object.localisation }}
+{{ object.mots_cles }}
\ No newline at end of file
--- a/src/egonomy/views.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/src/egonomy/views.py	Wed Feb 13 10:13:56 2013 +0100
@@ -6,6 +6,9 @@
 from models import Image, Fragment
 from django.db.models.aggregates import Max
 import logging
+from haystack.query import SearchQuerySet
+from egonomy.search_indexes import QueryParser
+from egonomy.models import ImageMetadata
 
 logger = logging.getLogger(__name__)
 
@@ -94,9 +97,25 @@
     # Get the cur_page_nb number parameter if possible
     cur_page_nb = request.GET.get("page") or 1
     cur_page_nb = int(cur_page_nb)
+
+    search = None
+    if "search" in request.GET:
+        search = request.GET["search"]
+        field = "all"
+        if "field" in request.GET:
+            field = request.GET["field"]
+
+    img_list = Image.objects.order_by('pk').select_related('info', 'metadata')
+    if search:
+        if not field or field == 'all':
+            field = 'text'        
+        qp = QueryParser(field)        
+        res = SearchQuerySet().filter(qp.parse(search)).models(ImageMetadata)
+        img_list = Image.objects.filter(id__in=[r.pk for r in res])
+    else:
+        img_list = img_list.all()
     
-    img_list = Image.objects.all().order_by('pk').select_related('info', 'metadata')
-    nb = 32
+    nb = getattr(settings,"IMAGES_PER_PAGE", 32)
     paginator = Paginator(img_list, nb)
     try:
         results = paginator.page(cur_page_nb)
@@ -115,7 +134,7 @@
     cur_page_nb = int(cur_page_nb)
     
     frg_list = Fragment.objects.all().order_by('pk').select_related('image', 'image__info', 'image__metadata','author')
-    nb = 32
+    nb = getattr(settings,"IMAGES_PER_PAGE", 32)
     paginator = Paginator(frg_list, nb)
     try:
         results = paginator.page(cur_page_nb)
--- a/virtualenv/res/lib/lib_create_env.py	Mon Feb 11 15:13:19 2013 +0100
+++ b/virtualenv/res/lib/lib_create_env.py	Wed Feb 13 10:13:56 2013 +0100
@@ -28,7 +28,7 @@
     'PARAMIKO': {'setup': 'paramiko', 'url':'https://github.com/paramiko/paramiko/archive/v1.9.0.tar.gz', 'local':'paramiko-1.9.0.tar.gz', 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
     'FABRIC': {'setup': 'fabric', 'url':'https://github.com/fabric/fabric/tarball/1.5.1', 'local':'fabric-1.5.1.tar.gz', 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
     'MERCURIAL': {'setup': 'mercurial', 'url':'http://mercurial.selenic.com/release/mercurial-2.2.3.tar.gz', 'local':'mercurial-2.2.3.tar.gz', 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
-    'HAYSTACK': {'setup': 'django-haystack', 'url': 'https://github.com/toastdriven/django-haystack/tarball/master', 'local': 'django-haystack-v2.0.0.tar.gz', 'install':{'method':'pip', 'option_str': None, 'dict_extra_env': None}},
+    'HAYSTACK': {'setup': 'django-haystack', 'url': 'https://github.com/toastdriven/django-haystack/tarball/master', 'local': 'django-haystack-v2.0.0-beta.tar.gz', 'install':{'method':'pip', 'option_str': None, 'dict_extra_env': None}},
     'REQUESTS': {'setup': 'requests', 'url':'https://github.com/kennethreitz/requests/archive/v1.1.0.tar.gz', 'local':'requests-1.1.0.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
     'PYELASTICSEARCH': {'setup': 'pyelasticsearch', 'url':'https://github.com/rhec/pyelasticsearch/archive/0.3.tar.gz', 'local':'pyelasticsearch-0.3.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
     'WHOOSH': {'setup': 'whoosh', 'url':'https://bitbucket.org/mchaput/whoosh/get/tip.tar.gz', 'local':'whoosh-2.5.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
Binary file virtualenv/res/src/django-haystack-V2.0.0-beta.tar.gz has changed
Binary file virtualenv/res/src/django-haystack-v2.0.0.tar.gz has changed