]> git.parisson.com Git - telemeta.git/commitdiff
finally add saved searches with links (closes #89)
authorGuillaume Pellerin <guillaume.pellerin@ircam.fr>
Mon, 28 Mar 2016 10:16:41 +0000 (12:16 +0200)
committerGuillaume Pellerin <guillaume.pellerin@ircam.fr>
Mon, 28 Mar 2016 10:16:41 +0000 (12:16 +0200)
12 files changed:
app/deploy/app.sh
app/sandbox/settings.py
requirements-dev.txt
telemeta/haystack_urls.py [deleted file]
telemeta/search_indexes.py
telemeta/templates/telemeta/inc/module_searches.html
telemeta/templatetags/telemeta_utils.py
telemeta/urls.py
telemeta/views/__init__.py
telemeta/views/haystack_search.py [deleted file]
telemeta/views/home.py
telemeta/views/search.py [new file with mode: 0644]

index 02aba8e814e5085e513d78ef91b61f1cdf3f084d..9420bb6d27a9117d5fa47f8dcc22420ef8c7fcd7 100644 (file)
@@ -17,8 +17,9 @@ uid='www-data'
 gid='www-data'
 
 # stating apps
+pip install --upgrade pip
 pip install -U django==1.6.11 django-environ redis django-angular
-pip install -e git+https://github.com/django-haystack/saved_searches.git#egg=saved_searches-2.0.0-alpha
+pip install -U git+https://github.com/Parisson/saved_searches.git#egg=saved_searches-2.0.0-beta
 
 # waiting for other services
 sh $app/deploy/wait.sh
index e9dc02cf4592fc4543bf1943ae158e13955a83b2..5590b2ed1014db8b71a9a801222bd8bb833ca571 100644 (file)
@@ -319,12 +319,12 @@ BOWER_INSTALLED_APPS = (
     'underscore',
     'bootstrap',
     'bootstrap-select#1.5.4',
-    'font-awesome#~4.4.0',
+    'font-awesome#4.4.0',
     'angular#1.2.26',
     'angular-bootstrap-select',
     'angular-resource#1.2.26',
     'raphael',
-    'soundmanager',
+    'soundmanager#V2.97a.20150601',
     'https://github.com/Parisson/loaders.git',
     'https://github.com/Parisson/ui.git',
     'jquery-ui',
index 552e7311cdfdb7f201f4ec70eaf3163e6a604fef..f4b078c9a50ed1f1ce3e8d9e593a565bb60d044a 100644 (file)
@@ -1,4 +1,4 @@
 
 -e git+https://github.com/mariocesar/sorl-thumbnail.git@v12.2#egg=sorl-thumbnail-12.2
 -e git+https://github.com/Parisson/ebooklib.git#egg=ebooklib-0.16
--e git+https://github.com/django-haystack/saved_searches.git#egg=saved_searches-2.0.0-alpha
+-e git+https://github.com/Parisson/saved_searches.git#egg=saved_searches-2.0.0-beta
diff --git a/telemeta/haystack_urls.py b/telemeta/haystack_urls.py
deleted file mode 100644 (file)
index 28f3701..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from django.views.generic.base import TemplateView
-from telemeta.views.haystack_search import *
-from telemeta.views.new_playlist import *
-from haystack.forms import *
-
-urlpatterns = patterns('',
-    url(r'^$', HaystackSearch(), name='haystack_search'),
-    url(r'^quick/(?P<type>[A-Za-z0-9._-]+)/$', HaystackSearch(), name='haystack_search_type'),
-    url(r'^advance/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search'),
-    url(r'^advance/(?P<type>[A-Za-z0-9._-]+)/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search_type'),
-    url(r'^playlist_add/(?P<type>[A-Za-z0-9._-]+)/$', NewPlaylistView().display, name='haystack_playlist'),
-    url(r'^playlist_confirmation/(?P<type>[A-Za-z0-9._-]+)/$',NewPlaylistView().addToPlaylist, name='add_confirmation'),
-)
index 6162cbfe1e3b70e895ee326fcf72c871965f1a9d..804a8d8fbe8df9c614ab76d490e8c8f8cbeb720a 100644 (file)
@@ -1,4 +1,36 @@
 # -*- coding: utf-8 -*-
+
+# Copyright (C) 2015 Angy Fils-Aimé, Killian Mary
+
+# This software is a computer program whose purpose is to backup, analyse,
+# transcode and stream any audio content with its metadata over a views frontend.
+
+# This software is governed by the CeCILL  license under French law and
+# abiding by the rules of distribution of free software.  You can  use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability.
+
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and,  more generally, to use and operate it in the
+# same conditions as regards security.
+
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
 from haystack import indexes
 from telemeta.models import *
 
@@ -214,4 +246,3 @@ class MediaFondsIndex(indexes.SearchIndex, indexes.Indexable):
 
     def get_model(self):
         return MediaFonds
-
index 91dfc65e51de44cd356af5a44105d39a4f2c6099..c2331859eeba024c92730f56fe59e29032b1fbc6 100644 (file)
@@ -1,5 +1,5 @@
-{% load telemeta_utils %}
-{% load i18n %}
+{% load i18n telemeta_utils saved_searches_tags %}
+{% most_recent_searches as searches for_user request.user %}
 
    <div class="module">
     <h3>
@@ -9,21 +9,27 @@
     <div class="vscroll">
     <table class="listing" bgcolor="#FFFFFF" style="width: 100%">
       <tr>
-        <th class="highlight">{% trans "Date" %}</th>
-        <th>{% trans "Criteria" %}</th>
+        <th>{% trans "Date" %}</th>
+        <th>{% trans "Query" %}</th>
       </tr>
     {% for s in searches %}
      <tr {% if not forloop.counter0|divisibleby:"2" %}class="odd"{% endif %}>
-        <td>{{ s.date }}</td>
-        <td><a href="{% url "telemeta-search" %}?{{s.criteria.all|build_pattern_string|build_query_string}}">
-            {% for c in s.criteria.all %}
-                <li>{% trans c.key %} : {{ c.value}}</li>
-            {% endfor %}
-          </a>
+        <td>{{ s.created }}</td>
+        <td>{% if s.search_key == 'quick' %}
+                <a href="{% url "haystack_search" %}?q={{s.user_query}}">{{ s.user_query }}</a>
+            {% elif s.search_key == 'advanced' %}
+              {% with s.user_query|build_pattern_dict as queries %}
+                <a href="{% url "haystack_advance_search" %}?{{queries|build_query_string}}">
+
+                {% for k, v in queries.items %}
+                 {% if v %}<li>{{ k }}: {{ v }}</li>{% endif %}
+                {% endfor %}
+                </a>
+              {% endwith %}
+            {% endif %}
         </td>
       </tr>
     {% endfor %}
     </table>
     </div>
    </div>
-
index 02aa0dc10c7b08fd8aced59a9314f67519cc8b4b..a085034424fbe2011158341026c206b5776d792f 100644 (file)
@@ -13,6 +13,7 @@ from django.utils.safestring import mark_safe
 from django import db
 import re
 import os
+import ast
 import datetime
 from django.conf import settings
 from django.template.defaultfilters import stringfilter
@@ -74,11 +75,8 @@ def escapejs(value):
     return value
 
 @register.filter
-def build_pattern_string(criteria):
-    dict = {}
-    for c in criteria:
-        dict[c.key] = c.value
-    return dict
+def build_pattern_dict(query):
+    return ast.literal_eval(query.rstrip())
 
 @register.filter
 def build_query_string(vars):
@@ -92,8 +90,7 @@ def build_query_string(vars):
           elif not isinstance(v, basestring):
               v = unicode(v)
           args.append(urlquote(k) + '=' + urlquote(v))
-
-      return "&amp;".join(args)
+      return "&".join(args)
     return ''
 
 @register.filter
@@ -470,4 +467,3 @@ def get_googletools():
 @register.assignment_tag
 def settings_value(name):
     return getattr(settings, name, "")
-
index dbd1bf8e5814b53150b9818ccc3373467dd4582a..64082dcf07104e8dd5eee946e54db8421bcd7001 100644 (file)
@@ -40,6 +40,8 @@ from django.views.generic.base import RedirectView, TemplateView
 from django.views.generic.list import ListView
 from telemeta.models import MediaItem, MediaCollection, MediaItemMarker, MediaCorpus, MediaFonds
 from telemeta.views import *
+from haystack.forms import *
+
 from jsonrpc import jsonrpc_site
 import os.path
 import telemeta.config
@@ -94,14 +96,10 @@ urlpatterns = patterns('',
     url(r'^archives/markers/(?P<marker_id>[A-Za-z0-9]+)/$', item_view.item_detail, name="telemeta-item-detail-marker"),
 
     # Redirections to old URLs
-    url(r'^items/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/items/%(path)s/',
-                                                 permanent= True), name="telemeta-item-redir"),
-    url(r'^collections/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/collections/%(path)s/',
-                                                 permanent= True), name="telemeta-collection-redir"),
-    url(r'^corpus/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/corpus/%(path)s/',
-                                                 permanent= True), name="telemeta-corpus-redir"),
-    url(r'^fonds/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/fonds/%(path)s/',
-                                                 permanent= True), name="telemeta-fonds-redir"),
+    url(r'^items/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/items/%(path)s/', permanent= True), name="telemeta-item-redir"),
+    url(r'^collections/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/collections/%(path)s/', permanent= True), name="telemeta-collection-redir"),
+    url(r'^corpus/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/corpus/%(path)s/', permanent= True), name="telemeta-corpus-redir"),
+    url(r'^fonds/(?P<path>[A-Za-z0-9._-s/]+)/$', RedirectView.as_view(url='/archives/fonds/%(path)s/', permanent= True), name="telemeta-fonds-redir"),
 
     # collections
     url(r'^archives/collections/$', CollectionListView.as_view(), name="telemeta-collections"),
@@ -141,15 +139,15 @@ urlpatterns = patterns('',
 
     # search
     # url(r'^archives/$', home_view.search, name="telemeta-archives"),
-    url(r'^search/$', SearchView.as_view(), name="telemeta-search"),
-    url(r'^search_published/(?P<type>[A-Za-z0-9._-]+)/$', SearchViewPublished.as_view(), name="telemeta-search-published"),
-    url(r'^search_unpublished/(?P<type>[A-Za-z0-9._-]+)/$', SearchViewUnpublished.as_view(), name="telemeta-search-unpublished"),
-    url(r'^search_full/(?P<type>[A-Za-z0-9._-]+)/$', SearchViewFullAccess.as_view(), name="telemeta-search-full"),
-    url(r'^search_none/(?P<type>[A-Za-z0-9._-]+)/$', SearchViewRestrictedAccess.as_view(), name="telemeta-search-none"),
-    url(r'^search/(?P<type>[A-Za-z0-9._-]+)/$', SearchView.as_view(), name="telemeta-search-type"),
-    url(r'^search_criteria/$', home_view.edit_search, name="telemeta-search-criteria"),
+    url(r'^search/$', HaystackSearch(), name='haystack_search'),
+    url(r'^search/quick/(?P<type>[A-Za-z0-9._-]+)/$', HaystackSearch(), name='haystack_search_type'),
+    url(r'^search/advance/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search'),
+    url(r'^search/advance/(?P<type>[A-Za-z0-9._-]+)/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search_type'),
+
+    url(r'^search/playlist_add/(?P<type>[A-Za-z0-9._-]+)/$', NewPlaylistView().display, name='haystack_playlist'),
+    url(r'^search/playlist_confirmation/(?P<type>[A-Za-z0-9._-]+)/$',NewPlaylistView().addToPlaylist, name='add_confirmation'),
+
     url(r'^complete_location/$', home_view.complete_location, name="telemeta-complete-location"),
-    url(r'^haystack/', include('telemeta.haystack_urls')),
 
     # administration
     url(r'^admin/$', admin_view.admin_index, name="telemeta-admin"),
index 81519b5a8bca4c44d6dda19688d8075c950dd436..9b12abc0aa0182d5bb5bf98c751d9b8d530f6ef2 100644 (file)
@@ -44,4 +44,5 @@ from telemeta.views.profile import *
 from telemeta.views.feed import *
 from telemeta.views.resource import *
 from telemeta.views.epub import *
-
+from telemeta.views.search import *
+from telemeta.views.new_playlist import *
diff --git a/telemeta/views/haystack_search.py b/telemeta/views/haystack_search.py
deleted file mode 100644 (file)
index 7f5b6a5..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from haystack.views import *
-from haystack.query import SearchQuerySet
-from telemeta.models import *
-from telemeta.forms.haystack_form import *
-from saved_searches.views import SavedSearchView
-
-
-class HaystackSearch(FacetedSearchView, SavedSearchView):
-
-    def __call__(self, request, type=None):
-        self.type = type
-        self.form_class = HaySearchForm
-        self.selected_facet = self.selected_facet_list(request.GET.getlist('selected_facets', ['a']))
-        print(self.selected_facet)
-        if request.GET.get('results_page'):
-            self.results_per_page = int(request.GET.get('results_page'))
-        else:
-            self.results_per_page = 20
-        return super(HaystackSearch, self).__call__(request)
-
-    def get_query(self):
-        return super(HaystackSearch, self).get_query()
-
-    def get_results(self):
-        if(self.type == 'item'):
-            return super(HaystackSearch, self).get_results().models(MediaItem)
-        elif(self.type == 'corpus'):
-            return super(HaystackSearch, self).get_results().models(MediaCorpus)
-        elif(self.type == 'fonds'):
-            return super(HaystackSearch, self).get_results().models(MediaFonds)
-        else:
-            return super(HaystackSearch, self).get_results().models(MediaCollection)
-
-    def selected_facet_list(self, selected_facets):
-        facet_list = []
-        for facet in selected_facets:
-            if ":" not in facet:
-                continue
-
-            field, value = facet.split(":", 1)
-
-            if value and not value in facet_list:
-                if field == 'digitized_exact':
-                    facet_list.append('Sound')
-                else:
-                    facet_list.append(value)
-
-        return facet_list
-
-    def extra_context(self):
-        extra = super(HaystackSearch, self).extra_context()
-        extra['collection_count'] = super(HaystackSearch, self).get_results().models(MediaCollection).count()
-        extra['item_count'] = super(HaystackSearch, self).get_results().models(MediaItem).count()
-        extra['corpus_count'] = super(HaystackSearch, self).get_results().models(MediaCorpus).count()
-        extra['fonds_count'] = super(HaystackSearch, self).get_results().models(MediaFonds).count()
-
-        if extra['facets']:
-            viewable_total = 0
-            for viewable in extra['facets']['fields']['item_acces']:
-                if viewable == 'none':
-                    pass
-                else:
-                    viewable_total = viewable_total + viewable[1]
-
-            extra['Published_count'] = self.get_results().narrow('item_status:Published').count()
-            extra['Unpublished_count'] = self.get_results().narrow('item_status:Unpublished').count()
-            extra['viewable_count'] = self.get_results().narrow('item_acces:full OR item_acces:mixed').narrow('digitized:T').count()
-            extra['digitized_count'] = self.get_results().narrow('digitized:T').count()
-            extra['CDR_count'] = self.get_results().narrow('physical_format:CDR').count()
-            extra['Disque_count'] = self.get_results().narrow('physical_format:Disque').count()
-            extra['Cylindre_count'] = self.get_results().narrow('physical_format:Cylindre').count()
-            extra['Studio_count'] = self.get_results().narrow('recording_context:Studio').count()
-            extra['Terrain_count'] = self.get_results().narrow('recording_context:Terrain').count()
-            extra['Radio_count'] = self.get_results().narrow('recording_context:Radio').count()
-            extra['Video_count'] = self.get_results().narrow('media_type:Video').count()
-            extra['Audio_count'] = self.get_results().narrow('media_type:Audio').count()
-
-        if self.type == 'item':
-            extra['type'] = 'item'
-        elif self.type == 'fonds':
-            extra['type'] = 'fonds'
-        elif self.type == 'corpus':
-            extra['type'] = 'corpus'
-        else:
-            extra['type'] = 'collection'
-
-        extra['selected_facets'] = self.selected_facet
-        extra['selected_facets_url'] = self.request.GET.getlist('selected_facets')
-        extra['results_page'] = self.results_per_page
-        return extra
-
-    #def auto_complete(request):
-        #content = SearchQuerySet().autocomplete(content_auto=request.POST.get('seatch_text', ''))
-        #return render_to_response('', {'content' : content])
-
-
-class HaystackAdvanceSearch(SavedSearchView):
-
-    def __call__(self, request, type=None):
-        self.type = type
-        if request.GET.get('results_page'):
-            self.results_per_page = int(request.GET.get('results_page'))
-        else:
-            self.results_per_page = 20
-        return super(HaystackAdvanceSearch, self).__call__(request)
-
-    def get_query(self):
-        #overwrite the get_query for begin search with any form
-        if self.form.is_valid():
-            return self.form.cleaned_data
-        return ''
-
-    def get_results(self):
-        if(self.type == 'item'):
-            return self.form.search().models(MediaItem)
-        elif(self.type == 'fonds'):
-            return self.form.search().models(MediaFonds)
-        elif(self.type == 'corpus'):
-            return self.form.search().models(MediaCorpus)
-        else:
-            return self.form.search().models(MediaCollection)
-
-    def extra_context(self):
-        extra = super(HaystackAdvanceSearch, self).extra_context()
-        extra['fonds_count'] = self.form.search().models(MediaFonds).count()
-        extra['corpus_count'] = self.form.search().models(MediaCorpus).count()
-        extra['collection_count'] = self.form.search().models(MediaCollection).count()
-        extra['item_count'] = self.form.search().models(MediaItem).count()
-
-        if self.type == 'item':
-            extra['type'] = 'item'
-        elif  self.type == 'fonds':
-            extra['type'] = 'fonds'
-        elif(self.type == 'corpus'):
-            extra['type'] = 'corpus'
-        else:
-            extra['type'] = 'collection'
-
-        extra['results_page'] = self.results_per_page
-        return extra
index 7574307caca66dec0a7994c8ef5f83f63f782f2e..ea84f720b4bdf05f29aca60031e17c1542b985db 100644 (file)
@@ -36,6 +36,7 @@
 
 
 from telemeta.views.core import *
+from saved_searches.models import SavedSearch
 
 
 class HomeView(object):
@@ -82,9 +83,8 @@ class HomeView(object):
             template='telemeta/lists.html'
             playlists = get_playlists(request)
             revisions = get_revisions(100)
-            searches = Search.objects.filter(username=request.user)
             user_revisions = get_revisions(25, request.user)
-            return render(request, template, {'playlists': playlists, 'searches': searches,
+            return render(request, template, {'playlists': playlists,
                                               'revisions': revisions, 'user_revisions': user_revisions })
         else:
             template = 'telemeta/messages.html'
@@ -94,23 +94,6 @@ class HomeView(object):
             messages.error(request, title)
             return render(request, template, {'description' : description})
 
-    def edit_search(self, request, criteria=None):
-        year_min, year_max = MediaCollection.objects.all().recording_year_range()
-        rec_years = year_min and year_max and range(year_min, year_max + 1) or []
-        year_min, year_max = MediaCollection.objects.all().publishing_year_range()
-        pub_years = year_min and year_max and range(year_min, year_max + 1) or []
-        if request.user.is_authenticated():
-            searches = Search.objects.filter(username=request.user)
-        else:
-            searches = []
-        return render(request, 'telemeta/search_criteria.html', {
-            'rec_years': rec_years,
-            'pub_years': pub_years,
-            'ethnic_groups': MediaItem.objects.all().ethnic_groups(),
-            'criteria': criteria,
-            'searches': searches,
-        })
-
     def handle_oai_request(self, request):
         host = request.META['HTTP_HOST']
         datasource  = TelemetaOAIDataSource()
@@ -137,127 +120,6 @@ class HomeView(object):
         auth.logout(request)
         return redirect('telemeta-home')
 
-    def search(self, request, type = None):
-        """Perform a search through collections and items metadata"""
-        collections = MediaCollection.objects.enriched()
-        items = MediaItem.objects.enriched()
-        corpus = MediaCorpus.objects.all()
-        fonds  = MediaFonds.objects.all()
-        input = request.REQUEST
-        criteria = {}
-
-        switch = {
-            'pattern': lambda value: (
-                collections.quick_search(value),
-                items.quick_search(value),
-                corpus.quick_search(value),
-                fonds.quick_search(value),
-                ),
-            'title': lambda value: (
-                collections.word_search('title', value),
-                items.by_title(value),
-                corpus.word_search('title', value),
-                fonds.word_search('title', value)),
-            'location': lambda value: (
-                collections.by_location(Location.objects.get(name=value)),
-                items.by_location(Location.objects.get(name=value))),
-            'continent': lambda value: (
-                collections.by_continent(value),
-                items.filter(continent = value)),
-            'ethnic_group': lambda value: (
-                collections.by_ethnic_group(value),
-                items.filter(ethnic_group = value),
-                EthnicGroup.objects.get(pk=value)),
-            'creator': lambda value: (
-                collections.word_search('creator', value),
-                items.word_search('collection__creator', value)),
-            'collector': lambda value: (
-                collections.by_fuzzy_collector(value),
-                items.by_fuzzy_collector(value)),
-            'rec_year_from': lambda value: (
-                collections.by_recording_year(int(value), int(input.get('rec_year_to', value))),
-                items.by_recording_date(datetime.date(int(value), 1, 1),
-                                        datetime.date(int(input.get('rec_year_to', value)), 12, 31))),
-            'rec_year_to': lambda value: (collections, items),
-            'pub_year_from': lambda value: (
-                collections.by_publish_year(int(value), int(input.get('pub_year_to', value))),
-                items.by_publish_year(int(value), int(input.get('pub_year_to', value)))),
-            'pub_year_to': lambda value: (collections, items),
-            'sound': lambda value: (
-                collections.sound(),
-                items.sound()),
-            'instrument': lambda value: (
-                collections.by_instrument(value),
-                items.by_instrument(value)),
-        }
-
-        for key, value in input.items():
-            func = switch.get(key)
-            if func and value and value != "0":
-                try:
-                    res = func(value)
-                    if len(res)  > 4:
-                        collections, items, corpus, fonds, value = res
-                    elif len(res) == 4:
-                        collections, items, corpus, fonds = res
-                    elif len(res) == 3:
-                        collections, items, value = res
-                        corpus = corpus.none()
-                        fonds = fonds.none()
-                    else:
-                        collections, items = res
-                        corpus = corpus.none()
-                        fonds = fonds.none()
-
-                except ObjectDoesNotExist:
-                    collections = collections.none()
-                    items = items.none()
-                    corpus = corpus.none()
-                    fonds = fonds.none()
-
-                criteria[key] = value
-
-        # Save the search
-        user = request.user
-        if user:
-            if user.is_authenticated():
-                search = Search(username=user)
-                search.save()
-                if criteria:
-                    for key in criteria.keys():
-                        value = criteria[key]
-                        if key == 'ethnic_group':
-                            try:
-                                group = EthnicGroup.objects.get(value=value)
-                                value = group.id
-                            except:
-                                value = ''
-                        criter = Criteria(key=key, value=value)
-                        criter.save()
-                        search.criteria.add(criter)
-                    search.save()
-
-        if type is None:
-            if collections.count():
-                type = 'collections'
-            else:
-                type = 'items'
-
-        if type == 'items':
-            objects = items
-        elif type == 'collections':
-            objects = collections
-        elif type == 'corpus':
-            objects = corpus
-        elif type == 'fonds':
-            objects = fonds
-
-        return list_detail.object_list(request, objects,
-            template_name='telemeta/search_results.html', paginate_by=20,
-            extra_context={'criteria': criteria, 'collections_num': collections.count(),
-                'items_num': len(items), 'corpus_num': corpus.count(), 'fonds_num': fonds.count(),
-                'type' : type,})
-
     def complete_location(self, request, with_items=True):
         input = request.REQUEST
 
@@ -277,254 +139,3 @@ class HomeView(object):
     def users(self, request):
         users = User.objects.all().order_by('last_name')
         return render(request, 'telemeta/users.html', {'users': users})
-
-class SearchView(ListView):
-    """Perform a search through resources"""
-
-    template_name='telemeta/search_results.html'
-    paginate_by = 20
-
-    def get_queryset(self):
-        input = self.request.GET
-        self.criteria = {}
-
-        self.type = None
-        if 'type' in self.kwargs:
-            self.type = self.kwargs['type']
-
-        self.collections = MediaCollection.objects.enriched()
-        self.items = MediaItem.objects.enriched()
-        self.corpus = MediaCorpus.objects.all()
-        self.fonds  = MediaFonds.objects.all()
-
-        switch = {
-            'pattern': lambda value: (
-                self.collections.quick_search(value),
-                self.items.quick_search(value),
-                self.corpus.quick_search(value),
-                self.fonds.quick_search(value),
-                ),
-            'title': lambda value: (
-                self.collections.word_search('title', value),
-                self.items.by_title(value),
-                self.corpus.word_search('title', value),
-                self.fonds.word_search('title', value)),
-            'location': lambda value: (
-                self.collections.by_location(Location.objects.get(name=value)),
-                self.items.by_location(Location.objects.get(name=value))),
-            'continent': lambda value: (
-                self.collections.by_continent(value),
-                self.items.filter(continent = value)),
-            'ethnic_group': lambda value: (
-                self.collections.by_ethnic_group(value),
-                self.items.filter(ethnic_group = value),
-                EthnicGroup.objects.get(pk=value)),
-            'creator': lambda value: (
-                self.collections.word_search('creator', value),
-                self.items.word_search('collection__creator', value)),
-            'collector': lambda value: (
-                self.collections.by_fuzzy_collector(value),
-                self.items.by_fuzzy_collector(value)),
-            'rec_year_from': lambda value: (
-                self.collections.by_recording_year(int(value), int(input.get('rec_year_to', value))),
-                self.items.by_recording_date(datetime.date(int(value), 1, 1),
-                                        datetime.date(int(input.get('rec_year_to', value)), 12, 31))),
-            'rec_year_to': lambda value: (self.collections, self.items),
-            'pub_year_from': lambda value: (
-                self.collections.by_publish_year(int(value), int(input.get('pub_year_to', value))),
-                self.items.by_publish_year(int(value), int(input.get('pub_year_to', value)))),
-            'pub_year_to': lambda value: (self.collections, self.items),
-            'sound': lambda value: (
-                self.collections.sound(),
-                self.items.sound()),
-            'instrument': lambda value: (
-                self.collections.by_instrument(value),
-                self.items.by_instrument(value)),
-        }
-
-        for key, value in input.items():
-            func = switch.get(key)
-            if func and value and value != "0":
-                try:
-                    res = func(value)
-                    if len(res)  > 4:
-                        self.collections, self.items, self.corpus, self.fonds, value = res
-                    elif len(res) == 4:
-                        self.collections, self.items, self.corpus, self.fonds = res
-                    elif len(res) == 3:
-                        self.collections, self.items, value = res
-                        self.corpus = self.corpus.none()
-                        self.fonds = self.fonds.none()
-                    else:
-                        self.collections, self.items = res
-                        self.corpus = self.corpus.none()
-                        self.fonds = self.fonds.none()
-
-                except ObjectDoesNotExist:
-                    self.collections = self.collections.none()
-                    self.items = self.items.none()
-                    self.corpus = self.corpus.none()
-                    self.fonds = self.fonds.none()
-
-                self.criteria[key] = value
-
-        # Save the search
-        user = self.request.user
-        if user:
-            if user.is_authenticated():
-                search = Search(username=user)
-                search.save()
-                if self.criteria:
-                    for key in self.criteria.keys():
-                        value = self.criteria[key]
-                        if key == 'ethnic_group':
-                            try:
-                                group = EthnicGroup.objects.get(value=value)
-                                value = group.id
-                            except:
-                                value = ''
-                        criter = Criteria(key=key, value=value)
-                        criter.save()
-                        search.criteria.add(criter)
-                    search.save()
-
-        if self.type is None:
-            if self.collections.count():
-                self.type = 'collections'
-            else:
-                self.type = 'items'
-
-        if self.type == 'items':
-            objects = self.items
-        elif self.type == 'collections':
-            objects = self.collections
-        elif self.type == 'corpus':
-            objects = self.corpus
-        elif self.type == 'fonds':
-            objects = self.fonds
-
-        self.objects = objects
-        return objects
-
-    def get_context_data(self, *args, **kwargs):
-        context = super(SearchView, self).get_context_data(*args, **kwargs)
-        context['criteria'] = self.criteria
-        context['collections_num'] =  self.collections.count()
-        context['items_num'] = self.items.count()
-        context['corpus_num']  = self.corpus.count()
-        context['fonds_num'] = self.fonds.count()
-        context['type'] = self.type
-        context['count'] = self.object_list.count()
-        return context
-
-
-
-class SearchViewPublished(SearchView):
-    """Perform a search through published resources"""
-
-    template_name='telemeta/search_results.html'
-    paginate_by = 20
-
-    def get_queryset(self):
-        self.type = None
-        if 'type' in self.kwargs:
-            self.type = self.kwargs['type']
-        if(self.type=='items'):
-            return SearchView.get_queryset(self).filter(collection__code__contains="_E_")
-        else:
-            return SearchView.get_queryset(self).filter(code__contains="_E_")
-
-    def get_context_data(self, *args, **kwargs):
-        context = super(SearchView, self).get_context_data(*args, **kwargs)
-        context['criteria'] = self.criteria
-        context['collections_num'] =  self.collections.filter(code__contains="_E_").count()
-        context['items_num'] = self.items.filter(collection__code__contains="_E_").count()
-        context['corpus_num']  = self.corpus.filter(code__contains="_E_").count()
-        context['fonds_num'] = self.fonds.filter(code__contains="_E_").count()
-        context['type'] = self.type
-        context['count'] = self.object_list.count()
-        context['result_filter'] = "published"
-        return context
-
-class SearchViewUnpublished(SearchView):
-    """Perform a search through published resources"""
-
-    template_name='telemeta/search_results.html'
-    paginate_by = 20
-
-    def get_queryset(self):
-        self.type = None
-        if 'type' in self.kwargs:
-            self.type = self.kwargs['type']
-        if(self.type=='items'):
-            return SearchView.get_queryset(self).filter(collection__code__contains="_I_")
-        else:
-            return SearchView.get_queryset(self).filter(code__contains="_I_")
-
-    def get_context_data(self, *args, **kwargs):
-        context = super(SearchView, self).get_context_data(*args, **kwargs)
-        context['criteria'] = self.criteria
-        context['collections_num'] =  self.collections.filter(code__contains="_I_").count()
-        context['items_num'] = self.items.filter(collection__code__contains="_I_").count()
-        context['corpus_num']  = self.corpus.filter(code__contains="_I_").count()
-        context['fonds_num'] = self.fonds.filter(code__contains="_I_").count()
-        context['type'] = self.type
-        context['count'] = self.object_list.count()
-        context['result_filter'] = "unpublished"
-        return context
-
-class SearchViewFullAccess(SearchView):
-    """Perform a search through published resources"""
-
-    template_name='telemeta/search_results.html'
-    paginate_by = 20
-
-    def get_queryset(self):
-        self.type = None
-        if 'type' in self.kwargs:
-            self.type = self.kwargs['type']
-        if(self.type=='items'):
-            search = SearchView.get_queryset(self).filter(Q(collection__public_access="full")|Q(public_access="full")).exclude(collection__public_access="none")
-            return search;
-        else :
-            return SearchView.get_queryset(self).filter(public_access="full")
-
-    def get_context_data(self, *args, **kwargs):
-        context = super(SearchView, self).get_context_data(*args, **kwargs)
-        context['criteria'] = self.criteria
-        context['collections_num'] =  self.collections.filter(public_access="full").count()
-        context['items_num'] = self.items.filter(Q(collection__public_access="full")|Q(public_access="full")).exclude(collection__public_access="none").count()
-        context['corpus_num']  = self.corpus.filter(public_access="full").count()
-        context['fonds_num'] = self.fonds.filter(public_access="full").count()
-        context['type'] = self.type
-        context['count'] = self.object_list.count()
-        context['result_filter'] = "full"
-        return context
-
-class SearchViewRestrictedAccess(SearchView):
-    """Perform a search through published resources"""
-
-    template_name='telemeta/search_results.html'
-    paginate_by = 20
-
-    def get_queryset(self):
-        self.type = None
-        if 'type' in self.kwargs:
-            self.type = self.kwargs['type']
-        if(self.type=='items'):
-            search = SearchView.get_queryset(self).filter(Q(collection__public_access="none")|Q(public_access="none")).exclude(collection__public_access="full")
-            return search;
-        else :
-            return SearchView.get_queryset(self).filter(public_access="none")
-
-    def get_context_data(self, *args, **kwargs):
-        context = super(SearchView, self).get_context_data(*args, **kwargs)
-        context['criteria'] = self.criteria
-        context['collections_num'] =  self.collections.filter(public_access="none").count()
-        context['items_num'] = self.items.filter(Q(collection__public_access="none")|Q(public_access="none")).exclude(collection__public_access="full").count()
-        context['corpus_num']  = self.corpus.filter(public_access="none").count()
-        context['fonds_num'] = self.fonds.filter(public_access="none").count()
-        context['type'] = self.type
-        context['count'] = self.object_list.count()
-        context['result_filter'] = "none"
-        return context
\ No newline at end of file
diff --git a/telemeta/views/search.py b/telemeta/views/search.py
new file mode 100644 (file)
index 0000000..ba9c6ed
--- /dev/null
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2015 Angy Fils-Aimé, Killian Mary
+
+# This software is a computer program whose purpose is to backup, analyse,
+# transcode and stream any audio content with its metadata over a views frontend.
+
+# This software is governed by the CeCILL  license under French law and
+# abiding by the rules of distribution of free software.  You can  use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability.
+
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and,  more generally, to use and operate it in the
+# same conditions as regards security.
+
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from haystack.views import *
+from haystack.query import SearchQuerySet
+from telemeta.models import *
+from telemeta.forms.haystack_form import *
+from saved_searches.views import SavedSearchView
+
+
+class HaystackSearch(FacetedSearchView, SavedSearchView):
+
+    search_key = 'quick'
+
+    def __call__(self, request, type=None):
+        self.type = type
+        self.form_class = HaySearchForm
+        self.selected_facet = self.selected_facet_list(request.GET.getlist('selected_facets', ['a']))
+        print(self.selected_facet)
+        if request.GET.get('results_page'):
+            self.results_per_page = int(request.GET.get('results_page'))
+        else:
+            self.results_per_page = 20
+        return super(HaystackSearch, self).__call__(request)
+
+    def get_query(self):
+        return super(HaystackSearch, self).get_query()
+
+    def get_results(self):
+        if(self.type == 'item'):
+            return super(HaystackSearch, self).get_results().models(MediaItem)
+        elif(self.type == 'corpus'):
+            return super(HaystackSearch, self).get_results().models(MediaCorpus)
+        elif(self.type == 'fonds'):
+            return super(HaystackSearch, self).get_results().models(MediaFonds)
+        else:
+            return super(HaystackSearch, self).get_results().models(MediaCollection)
+
+    def selected_facet_list(self, selected_facets):
+        facet_list = []
+        for facet in selected_facets:
+            if ":" not in facet:
+                continue
+
+            field, value = facet.split(":", 1)
+
+            if value and not value in facet_list:
+                if field == 'digitized_exact':
+                    facet_list.append('Sound')
+                else:
+                    facet_list.append(value)
+
+        return facet_list
+
+    def extra_context(self):
+        extra = super(HaystackSearch, self).extra_context()
+        extra['collection_count'] = super(HaystackSearch, self).get_results().models(MediaCollection).count()
+        extra['item_count'] = super(HaystackSearch, self).get_results().models(MediaItem).count()
+        extra['corpus_count'] = super(HaystackSearch, self).get_results().models(MediaCorpus).count()
+        extra['fonds_count'] = super(HaystackSearch, self).get_results().models(MediaFonds).count()
+
+        if extra['facets']:
+            viewable_total = 0
+            for viewable in extra['facets']['fields']['item_acces']:
+                if viewable == 'none':
+                    pass
+                else:
+                    viewable_total = viewable_total + viewable[1]
+
+            extra['Published_count'] = self.get_results().narrow('item_status:Published').count()
+            extra['Unpublished_count'] = self.get_results().narrow('item_status:Unpublished').count()
+            extra['viewable_count'] = self.get_results().narrow('item_acces:full OR item_acces:mixed').narrow('digitized:T').count()
+            extra['digitized_count'] = self.get_results().narrow('digitized:T').count()
+            extra['CDR_count'] = self.get_results().narrow('physical_format:CDR').count()
+            extra['Disque_count'] = self.get_results().narrow('physical_format:Disque').count()
+            extra['Cylindre_count'] = self.get_results().narrow('physical_format:Cylindre').count()
+            extra['Studio_count'] = self.get_results().narrow('recording_context:Studio').count()
+            extra['Terrain_count'] = self.get_results().narrow('recording_context:Terrain').count()
+            extra['Radio_count'] = self.get_results().narrow('recording_context:Radio').count()
+            extra['Video_count'] = self.get_results().narrow('media_type:Video').count()
+            extra['Audio_count'] = self.get_results().narrow('media_type:Audio').count()
+
+        if self.type == 'item':
+            extra['type'] = 'item'
+        elif self.type == 'fonds':
+            extra['type'] = 'fonds'
+        elif self.type == 'corpus':
+            extra['type'] = 'corpus'
+        else:
+            extra['type'] = 'collection'
+
+        extra['selected_facets'] = self.selected_facet
+        extra['selected_facets_url'] = self.request.GET.getlist('selected_facets')
+        extra['results_page'] = self.results_per_page
+        return extra
+
+    #def auto_complete(request):
+        #content = SearchQuerySet().autocomplete(content_auto=request.POST.get('seatch_text', ''))
+        #return render_to_response('', {'content' : content])
+
+
+class HaystackAdvanceSearch(SavedSearchView):
+
+    search_key = 'advanced'
+
+    def __call__(self, request, type=None):
+        self.type = type
+        if request.GET.get('results_page'):
+            self.results_per_page = int(request.GET.get('results_page'))
+        else:
+            self.results_per_page = 20
+        return super(HaystackAdvanceSearch, self).__call__(request)
+
+    def get_query(self):
+        #overwrite the get_query for begin search with any form
+        if self.form.is_valid():
+            return self.form.cleaned_data
+        return ''
+
+    def get_results(self):
+        if(self.type == 'item'):
+            return self.form.search().models(MediaItem)
+        elif(self.type == 'fonds'):
+            return self.form.search().models(MediaFonds)
+        elif(self.type == 'corpus'):
+            return self.form.search().models(MediaCorpus)
+        else:
+            return self.form.search().models(MediaCollection)
+
+    def extra_context(self):
+        extra = super(HaystackAdvanceSearch, self).extra_context()
+        extra['fonds_count'] = self.form.search().models(MediaFonds).count()
+        extra['corpus_count'] = self.form.search().models(MediaCorpus).count()
+        extra['collection_count'] = self.form.search().models(MediaCollection).count()
+        extra['item_count'] = self.form.search().models(MediaItem).count()
+
+        if self.type == 'item':
+            extra['type'] = 'item'
+        elif  self.type == 'fonds':
+            extra['type'] = 'fonds'
+        elif(self.type == 'corpus'):
+            extra['type'] = 'corpus'
+        else:
+            extra['type'] = 'collection'
+
+        extra['results_page'] = self.results_per_page
+        return extra