# HG changeset patch # User durandn # Date 1471510735 -7200 # Node ID 454e39dced1f0d27dbc5f32296eca4cc4068d54e # Parent 81d82b1f431a367f45c1d56d045f926f34c03084# Parent e13fed7f0837208731b2f9b1472fe2284966120d Merge with e13fed7f0837208731b2f9b1472fe2284966120d diff -r 81d82b1f431a -r 454e39dced1f .hgignore --- a/.hgignore Thu Aug 18 10:57:00 2016 +0200 +++ b/.hgignore Thu Aug 18 10:58:55 2016 +0200 @@ -7,7 +7,7 @@ ^src/iconolab/static/iconolab/js/node_modules/ ^src/iconolab/static/iconolab/js/iconolab-bundle/node_modules/ ^src/iconolab/static/iconolab/js/iconolab-bundle/dist/ - +\.orig$ ^web/* ^\.pydevproject$ diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/models.py --- a/src/iconolab/models.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/models.py Thu Aug 18 10:58:55 2016 +0200 @@ -266,6 +266,10 @@ return self.revisions.filter(state=AnnotationRevision.AWAITING).distinct().count() @property + def collection(self): + return self.image.collection + + @property def tags(self): return [tag.label for tag in self.current_revision.tags.all()] diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/__init__.py --- a/src/iconolab/search_indexes/__init__.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/search_indexes/__init__.py Thu Aug 18 10:58:55 2016 +0200 @@ -1,2 +1,2 @@ from .indexes import AnnotationIndex, ImageIndex -__all__ = ['AnnotationIndex', 'ImageIndex'] \ No newline at end of file +__all__ = ['AnnotationIndex', 'ImageIndex', 'RevisionSignalProcessor'] \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/forms.py --- a/src/iconolab/search_indexes/forms.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/search_indexes/forms.py Thu Aug 18 10:58:55 2016 +0200 @@ -5,42 +5,45 @@ -#def get_available_choices(): - -def get_selected_model(type): - - available_models = { - 'image': Image, - 'annotation': Annotation - } - - return available_models[type] - - class IconolabSearchForm(SearchForm): - realm = forms.ChoiceField(required=False, choices=(("image","Image"), ("annotation","Annotation")) ) + model_type = forms.ChoiceField(required=False, choices=(("images","Image"), ("annotations","Annotation")) ) def __init__(self, *args, **kwargs): - + self.collection_name = kwargs.pop("collection_name") + selected_model_type = kwargs.pop("model_type", None) + + if selected_model_type is not None: + data = kwargs.get("data", None) + if data: + data = data.copy() + data["model_type"] = selected_model_type + kwargs['data'] = data + super(IconolabSearchForm, self).__init__(*args, **kwargs) + + def no_query_found(self): + print("inside no_query_found") + return self.searchqueryset.all() - def get_realm_queryset(self, qs, realm): + def get_model_type_queryset(self, qs, model_type): - if realm == 'image': + if model_type == 'images': qs = qs.models(Image).load_all_queryset(Image, Image.objects.select_related('item', 'item__metadatas')) - if realm == 'annotation': + if model_type == 'annotations': qs = qs.models(Annotation).load_all_queryset(Annotation, Annotation.objects.select_related('image', 'stats', 'current_revision', 'author')) + + if self.collection_name is not None: + qs = qs.filter(collection = self.collection_name) + return qs def search(self): - - selected_realm = self.cleaned_data.get("realm") - selected_model = get_selected_model(selected_realm) + selected_type = self.cleaned_data.get("model_type") #load all if q empty qs = super(IconolabSearchForm, self).search() if qs.count() == 0: return qs else: - qs = self.get_realm_queryset(qs, selected_realm).load_all() + qs = self.get_model_type_queryset(qs, selected_type).load_all() return qs \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/indexes.py --- a/src/iconolab/search_indexes/indexes.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/search_indexes/indexes.py Thu Aug 18 10:58:55 2016 +0200 @@ -5,7 +5,7 @@ class ImageIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) - collection = indexes.CharField(model_attr='collection') + collection = indexes.CharField(model_attr="collection") authors = indexes.CharField(model_attr="authors") school = indexes.CharField(model_attr="school") designation = indexes.CharField(model_attr="designation") @@ -31,10 +31,11 @@ ##indexed field text = indexes.CharField(document=True, use_template=True) - title = indexes.CharField(model_attr='current_revision__title') - description = indexes.CharField(model_attr='current_revision__description') - tags = indexes.MultiValueField(model_attr='tags') - + title = indexes.CharField(model_attr="current_revision__title") + description = indexes.CharField(model_attr="current_revision__description") + collection = indexes.CharField(model_attr="collection") + tags = indexes.MultiValueField(model_attr="tags") + ## tags def get_model(self): return Annotation diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/query.py --- a/src/iconolab/search_indexes/query.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/search_indexes/query.py Thu Aug 18 10:58:55 2016 +0200 @@ -6,13 +6,15 @@ def __init__(self, using=None, query=None): super(IconolabRelatedQuerySet, self).__init__(using=using, query=query) - #def in_bulk(self, ids): - # results = {} - # int_ids = [ int(id) for id in ids] - # # Ne garder que les images - # annotations = Image.objects.filter(pk__in = int_ids) - # - # for annotation in annotations: - # results[annotation.pk] = annotation - # - # return results + def in_bulk(self, ids): + results = {} + int_ids = [ int(id) for id in ids] + print("in_bulk") + print(int_ids) + # Ne garder que les images + annotations = Annotation.objects.filter(pk__in = int_ids) + + for annotation in annotations: + results[annotation.pk] = annotation + + return results diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/signals.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iconolab/search_indexes/signals.py Thu Aug 18 10:58:55 2016 +0200 @@ -0,0 +1,26 @@ +from iconolab.models import Image, AnnotationRevision, Annotation +from haystack import signals +from django.db import models +from iconolab.signals.handlers import revision_created, revision_accepted +import logging + +logger = logging.getLogger(__name__) + +# update / create new index when a new revision is accepted +# Then update images tags related to this revision +class RevisionSignalProcessor(signals.BaseSignalProcessor): + + def setup(self): + revision_created.connect(self.handle_revision, sender=AnnotationRevision) + revision_accepted.connect(self.handle_revision, sender=AnnotationRevision) + + def handle_revision(self, **kwargs): + revision_instance = kwargs.get("instance", None) + if revision_instance and revision_instance.state in [AnnotationRevision.ACCEPTED]: + annotation = revision_instance.annotation + image_annotation = revision_instance.annotation.image + self.handle_save(Annotation, annotation) + self.handle_save(Image, image_annotation)##useful for tag + + def teardown(self): + revision_accepted.disconnect(self.handle_accepted_revision, sender=AnnotationRevision) \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/search_indexes/views.py --- a/src/iconolab/search_indexes/views.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/search_indexes/views.py Thu Aug 18 10:58:55 2016 +0200 @@ -1,41 +1,98 @@ from haystack.generic_views import SearchView +from haystack.query import RelatedSearchQuerySet from iconolab.search_indexes.forms import IconolabSearchForm from iconolab.search_indexes.query import IconolabRelatedQuerySet -from django.shortcuts import HttpResponse +from django.shortcuts import HttpResponse, redirect +from django.core.urlresolvers import reverse +from django.views.generic import RedirectView +from iconolab.models import Collection from pprint import pprint #override Search and Related QuerySet here class IconolabSearchView(SearchView): form_class = IconolabSearchForm - queryset = IconolabRelatedQuerySet() + queryset = RelatedSearchQuerySet() template_name = "search/default_search.html" paginate_by = 10 load_all = True templates_map = { - "image": "search/image_search.html", - "annotation": "search/annotation_search.html" + "images": "search/image_search.html", + "annotations": "search/annotation_search.html" } + def complete_url(self, url): + query = self.request.GET.get("q", None) + page = self.request.GET.get("page", None) + + queryargs = [] + query_string = "" + + if query is not None: + queryargs.append("q=" + query) + + if page is not None: + queryargs.append("page="+page) + + if len(queryargs): + query_string = "&".join(queryargs) + url += "?" + query_string + + return url + def get(self, request, *args, **kwargs): - self.current_realm = request.GET['realm'] - return super(IconolabSearchView, self).get(request,*args, **kwargs) + + self.model_type = request.GET.get('model_type', None) + collection_name = self.kwargs.get('collection_name', None) + + if self.model_type is not None: + if collection_name is None: + #redirect to all_model_type + redirect_url = reverse('model_search', kwargs={'model_type': self.model_type}) + return redirect(self.complete_url(redirect_url)) + else: + redirect_url = reverse('collection_with_model_search', kwargs={'collection_name': collection_name, 'model_type':self.model_type}) + return redirect(self.complete_url(redirect_url)) + else: + has_error, redirectView = self.check_kwargs(**kwargs) + if has_error: + return redirectView(request) + return super(IconolabSearchView, self).get(request, *args, **kwargs) + + def check_kwargs(self, **kwargs): + result = (False, None) + try: + collection_name = kwargs.get('collection_name', None) + if collection_name is None: + return result + collection = Collection.objects.get(name=kwargs.get('collection_name')) + except Collection.DoesNotExist: + result = (True, RedirectView.as_view(url=reverse('404error'))) + finally: + return result def get_queryset(self): qs = super(IconolabSearchView, self).get_queryset() + return IconolabSearchView.queryset return qs + def get_form_kwargs(self): + kwargs = super(IconolabSearchView, self).get_form_kwargs() + kwargs['collection_name'] = self.kwargs.get('collection_name', None) + kwargs['model_type'] = self.kwargs.get('model_type', None) + return kwargs + def get_template_names(self): - template = IconolabSearchView.templates_map[self.current_realm] - if template is None: + try : + model_type = self.kwargs.get('model_type', None) + template = IconolabSearchView.templates_map[model_type] + except KeyError: template = IconolabSearchView.template_name - - return [template] + finally: + return [template] def get_context_data(self, *args, **kwargs): - print("inside get_context_data", kwargs.get("q")) - print(kwargs.items()) context = super(IconolabSearchView, self).get_context_data(*args, **kwargs) context['collection_name'] = self.kwargs.get('collection_name', '') return context \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/settings/dev.py.tmpl --- a/src/iconolab/settings/dev.py.tmpl Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/settings/dev.py.tmpl Thu Aug 18 10:58:55 2016 +0200 @@ -178,6 +178,9 @@ }, } +# HAYSTACK_SIGNAL_PROCESSOR +HAYSTACK_SIGNAL_PROCESSOR = 'iconolab.search_indexes.signals.RevisionSignalProcessor' + CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/templates/partials/header_search_form.html --- a/src/iconolab/templates/partials/header_search_form.html Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/templates/partials/header_search_form.html Thu Aug 18 10:58:55 2016 +0200 @@ -1,15 +1,20 @@ -
diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/templates/search/annotation_search.html --- a/src/iconolab/templates/search/annotation_search.html Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/templates/search/annotation_search.html Thu Aug 18 10:58:55 2016 +0200 @@ -28,21 +28,26 @@ {% thumbnail result.object.image.media "400x400" crop=False as im %}+ {{ result.object.current_revision.title }} +
-- {{ result.object.current_revision.title }} -
+ + {% empty %}Aucune annotation n'a été trouvée.
{% endfor %} diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/templates/search/image_search.html --- a/src/iconolab/templates/search/image_search.html Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/templates/search/image_search.html Thu Aug 18 10:58:55 2016 +0200 @@ -28,14 +28,17 @@ {% thumbnail result.object.media "400x400" crop=False as im %}- {{ result.object.title }} + {{ result.object.title }} collection {{result.object.collection}}
+ {{result.object.item}} {% empty %}No results found.
{% endfor %} diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/templates/search/indexes/iconolab/annotation_text.txt --- a/src/iconolab/templates/search/indexes/iconolab/annotation_text.txt Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/templates/search/indexes/iconolab/annotation_text.txt Thu Aug 18 10:58:55 2016 +0200 @@ -3,3 +3,5 @@ {{ object.current_revision.description }} {{ object.tags }} + +samedi \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/templates/search/indexes/iconolab/image_text.txt --- a/src/iconolab/templates/search/indexes/iconolab/image_text.txt Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/templates/search/indexes/iconolab/image_text.txt Thu Aug 18 10:58:55 2016 +0200 @@ -9,4 +9,4 @@ {{ object.item.metadatas.discovery_context }} {{ object.item.metadatas.conservation_location }} -{{ object.tags }} +{{ object.tags }} \ No newline at end of file diff -r 81d82b1f431a -r 454e39dced1f src/iconolab/urls.py --- a/src/iconolab/urls.py Thu Aug 18 10:57:00 2016 +0200 +++ b/src/iconolab/urls.py Thu Aug 18 10:58:55 2016 +0200 @@ -50,6 +50,12 @@ url(r'^comments/', include('django_comments_xtd.urls')), url(r'^comments/annotation/post', views.comments.post_comment_iconolab, name="post_comment"), url('^user/notifications/', include(notifications.urls, namespace='notifications')), + + url(r'collections/(?P