src/iconolab/views/iconolab.py
changeset 94 a47934ff37ec
parent 90 8d7815ecd211
child 95 54d8dab80297
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/views/iconolab.py	Mon Aug 01 12:59:18 2016 +0200
@@ -0,0 +1,493 @@
+from django.shortcuts import HttpResponse, get_object_or_404, render
+from django.http import Http404
+from django.contrib.auth.decorators import login_required
+from django.views.generic import View, RedirectView
+from django.views.generic.base import ContextMixin
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from django.core.urlresolvers import reverse
+from django.core.exceptions import ObjectDoesNotExist
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.sites.models import Site
+from django.conf import settings
+from iconolab.models import Annotation, AnnotationRevision, Collection, Item, Image, IconolabComment, MetaCategory, MetaCategoryInfo
+from iconolab.forms.annotations import AnnotationRevisionForm
+
+
+class GlobalHomepageView(View):
+    def get(self, request, *args, **kwargs):
+        context = {}
+        context["collections"] = Collection.objects
+        return render(request, 'iconolab/home.html', context)
+
+
+class UserProfileView(View):
+    def get(self, request, *args, **kwargs):
+        context = {}
+        return render(request, 'iconolab/user_profile.html', context)
+
+
+class CollectionHomepageView(View, ContextMixin):
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection) = result
+        else:
+            return result(request)
+        context = super(CollectionHomepageView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['collection'] = collection
+        return render(request, 'iconolab/collection_home.html', context)
+    
+
+
+class ShowItemView(View, ContextMixin):
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            item = Item.objects.prefetch_related("images").get(item_guid=kwargs.get('item_guid'))
+        except Item.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, item)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, item) = result
+        else:
+            return result(request)
+        context = super(ShowItemView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['item_guid'] = self.kwargs.get('image_guid', '')
+        context['collection'] = collection
+        context['item'] = item
+        for image in item.images.all():
+            image.stats.views_count += 1
+            image.stats.save()
+        return render(request, 'iconolab/detail_item.html', context);
+
+class ShowImageView(View, ContextMixin):
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image) = result
+        else:
+            return result(request)
+        context = super(ShowImageView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        context['collection'] = collection
+        context['image'] = image
+        return render(request, 'iconolab/detail_image.html', context)
+    
+class CreateAnnotationView(View, ContextMixin):
+    
+    def get_context_data(self, **kwargs):
+        context = super(CreateAnnotationView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        return context
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image) = result
+        else:
+            return result(request)
+        annotation_form = AnnotationRevisionForm()
+        context = self.get_context_data(**kwargs)
+        context['image'] = image
+        context['form'] = annotation_form
+        context['tags_data'] = '[]'
+        return render(request, 'iconolab/change_annotation.html', context) 
+    
+    def post(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image) = result
+        else:
+            return result(request)
+        collection_name = kwargs['collection_name']
+        image_guid = kwargs['image_guid']
+        annotation_form = AnnotationRevisionForm(request.POST)
+        if annotation_form.is_valid():
+            author = request.user
+            title = annotation_form.cleaned_data['title']
+            description = annotation_form.cleaned_data['description']
+            fragment = annotation_form.cleaned_data['fragment']
+            tags_json = annotation_form.cleaned_data['tags']
+            new_annotation = Annotation.objects.create_annotation(author, image, title=title, description=description, fragment=fragment, tags_json=tags_json)
+            revision_comment = annotation_form.cleaned_data['comment']
+            IconolabComment.objects.create(
+                comment = revision_comment,
+                revision = new_annotation.current_revision,
+                content_type = ContentType.objects.get(app_label='iconolab', model='annotation'),
+                content_object = new_annotation,
+                site = Site.objects.get(id=settings.SITE_ID),
+                object_pk = new_annotation.id,
+                user = request.user,
+                user_name = request.user.username
+            )
+            return RedirectView.as_view(url=reverse('annotation_detail', kwargs={'collection_name': collection_name, 'image_guid': image_guid, 'annotation_guid': new_annotation.annotation_guid}))(request)
+        context = self.get_context_data(**kwargs)
+        context['image'] = image
+        context['form'] = annotation_form
+        context['tags_data'] = '[]'
+        render(request, 'iconolab/change_annotation.html', context)
+
+class ShowAnnotationView(View, ContextMixin):
+    
+    def get_context_data(self, **kwargs):
+        context = super(ShowAnnotationView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        context['annotation_guid'] = self.kwargs.get('annotation_guid', '')
+        return context
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            annotation = Annotation.objects.select_related('current_revision').get(annotation_guid=kwargs.get('annotation_guid'))
+        except Annotation.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image, annotation)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation) = result
+        else:
+            return result(request)
+        context = self.get_context_data(**kwargs)
+        context['collection'] = collection
+        context['image'] = image
+        context['annotation'] = annotation
+        context['tags_data'] = annotation.current_revision.get_tags_json()
+        
+        page = request.GET.get("page", 1)
+        per_page = request.GET.get("perpage", 10)
+        full_comments_list = IconolabComment.objects.for_app_models("iconolab.annotation").filter(object_pk = annotation.pk).order_by("thread_id", "-order")
+        paginator = Paginator(full_comments_list, per_page)
+        try:
+            comments_list = paginator.page(page)
+        except PageNotAnInteger:
+            comments_list = paginator.page(1)
+        except EmptyPage:
+            comments_list = paginator.page(paginator.num_pages)
+        context["comments"] = comments_list
+        
+        
+        image.stats.views_count += 1
+        image.stats.save()
+        annotation.stats.views_count += 1
+        annotation.stats.save()
+        return render(request, 'iconolab/detail_annotation.html', context)
+
+
+class EditAnnotationView(View, ContextMixin):
+    
+    def get_context_data(self, **kwargs):
+        context = super(EditAnnotationView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        context['annotation_guid'] = self.kwargs.get('annotation_guid', '')
+        return context
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            annotation = Annotation.objects.select_related('current_revision').get(annotation_guid=kwargs.get('annotation_guid'))
+        except Annotation.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image, annotation)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation) = result
+        else:
+            return result(request)
+        annotation_form = AnnotationRevisionForm(instance=annotation.current_revision)
+        context = self.get_context_data(**kwargs)
+        context['image'] = image
+        context['annotation'] = annotation
+        context['form'] = annotation_form
+        context['tags_data'] = annotation.current_revision.get_tags_json()
+        return render(request, 'iconolab/change_annotation.html', context) 
+    
+    def post(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation) = result
+        else:
+            return result(request)
+        collection_name = kwargs['collection_name']
+        image_guid = kwargs['image_guid']
+        annotation_guid = kwargs['annotation_guid']
+        annotation_form = AnnotationRevisionForm(request.POST)
+        if annotation_form.is_valid():
+            revision_author = request.user
+            revision_title = annotation_form.cleaned_data['title']
+            revision_description = annotation_form.cleaned_data['description']
+            revision_fragment = annotation_form.cleaned_data['fragment']
+            revision_tags_json = annotation_form.cleaned_data['tags']
+            new_revision = annotation.make_new_revision(revision_author, revision_title, revision_description, revision_fragment, revision_tags_json)
+            revision_comment = annotation_form.cleaned_data['comment']
+            comment = IconolabComment.objects.create(
+                comment = revision_comment,
+                revision = new_revision,
+                content_type = ContentType.objects.get(app_label='iconolab', model='annotation'),
+                content_object = annotation,
+                site = Site.objects.get(id=settings.SITE_ID),
+                object_pk = annotation.id,
+                user = request.user,
+                user_name = request.user.username
+            )
+            return RedirectView.as_view(url=reverse('annotation_detail', kwargs={'collection_name': collection_name, 'image_guid': image_guid, 'annotation_guid': annotation_guid}))(request)
+        context = self.get_context_data(**kwargs)
+        context['image'] = image
+        context['form'] = annotation_form
+        context['annotation'] = annotation
+        context['tags_data'] = annotation.current_revision.get_tags_json()
+        return render(request, 'iconolab/change_annotation.html', context)
+
+
+class ShowRevisionView(View, ContextMixin):
+    
+    def get_context_data(self, **kwargs):
+        context = super(ShowRevisionView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        context['annotation_guid'] = self.kwargs.get('annotation_guid', '')
+        context['revision_guid'] = self.kwargs.get('revision_guid', '')
+        return context
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            annotation = Annotation.objects.select_related('current_revision').get(annotation_guid=kwargs.get('annotation_guid'))
+        except Annotation.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            revision = AnnotationRevision.objects.select_related('parent_revision').get(revision_guid=kwargs.get('revision_guid'))
+        except AnnotationRevision.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image, annotation, revision)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation, revision) = result
+        else:
+            return result(request)
+        context = self.get_context_data(**kwargs)
+        context['collection'] = collection
+        context['image'] = image
+        context['annotation'] = annotation
+        context['revision'] = revision
+        context['tags_data'] = revision.get_tags_json()
+        context['comment'] = revision.creation_comment.first()
+        return render(request, 'iconolab/detail_revision.html', context)
+
+        
+class MergeProposalView(View, ContextMixin):
+    
+    def get_context_data(self, **kwargs):
+        context = super(MergeProposalView, self).get_context_data(**kwargs)
+        context['collection_name'] = self.kwargs.get('collection_name', '')
+        context['image_guid'] = self.kwargs.get('image_guid', '')
+        context['annotation_guid'] = self.kwargs.get('annotation_guid', '')
+        context['revision_guid'] = self.kwargs.get('revision_guid', '')
+        return context
+    
+    def check_kwargs(self, kwargs):
+        try:
+            collection = Collection.objects.prefetch_related("items", "items__images").get(name=kwargs.get('collection_name'))
+        except Collection.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            image = Image.objects.prefetch_related("annotations").get(image_guid=kwargs.get('image_guid'))
+        except Image.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            annotation = Annotation.objects.select_related('current_revision').get(annotation_guid=kwargs.get('annotation_guid'))
+        except Annotation.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        try:
+            revision = AnnotationRevision.objects.select_related('parent_revision').get(revision_guid=kwargs.get('revision_guid'))
+        except AnnotationRevision.DoesNotExist:
+            return False, RedirectView.as_view(url=reverse('404error'))
+        return True, (collection, image, annotation, revision)
+    
+    def get(self, request, *args, **kwargs):
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation, revision) = result
+        else:
+            return result(request)
+        # Only show merge form if there is a revision to merge AND the current user is the annotation author
+        if revision.state != AnnotationRevision.AWAITING or request.user != annotation.author:
+            return RedirectView.as_view(
+                url=reverse('revision_detail', 
+                    kwargs={
+                        'collection_name': collection.name, 
+                        'image_guid': image.image_guid, 
+                        'annotation_guid': annotation.annotation_guid,
+                        'revision_guid': revision.revision_guid
+                    }
+                )
+            )(request)
+        # Auto-accepts the revision only if the proper query arg is set and only if the revision parent is the current revision
+        if "auto_accept" in request.GET and request.GET["auto_accept"] in ["True", "true", "1", "yes"] and revision.parent_revision == annotation.current_revision:
+            annotation.validate_existing_revision(revision)
+            return RedirectView.as_view(
+                url=reverse('annotation_detail', 
+                    kwargs={
+                        'collection_name': collection.name, 
+                        'image_guid': image.image_guid, 
+                        'annotation_guid': annotation.annotation_guid
+                    }
+                )
+            )(request)
+        # Auto-reject the revision only if the proper query arg is set
+        if "auto_reject" in request.GET and request.GET["auto_reject"] in ["True", "true", "1", "yes"]:
+            annotation.reject_existing_revision(revision) 
+            return RedirectView.as_view(
+                url=reverse('annotation_detail', 
+                    kwargs={
+                        'collection_name': collection.name, 
+                        'image_guid': image.image_guid, 
+                        'annotation_guid': annotation.annotation_guid
+                    }
+                )
+            )(request)
+        
+        context = self.get_context_data(**kwargs)
+        context['collection'] = collection
+        context['image'] = image
+        context['annotation'] = annotation
+        # Proposal data
+        context['proposal_revision'] = revision
+        context['proposal_tags_data'] = revision.get_tags_json()
+        context['proposal_comment'] = revision.creation_comment.first()
+        # Parent data
+        context['parent_revision'] = revision.parent_revision
+        context['parent_tags_data'] = revision.parent_revision.get_tags_json()
+        context['parent_comment'] = revision.parent_revision.creation_comment.first()
+        # Current data
+        context['current_revision'] = annotation.current_revision
+        context['current_tags_data'] = annotation.current_revision.get_tags_json()
+        context['current_comment'] = annotation.current_revision.creation_comment.first()
+        
+        merge_form = AnnotationRevisionForm(instance=revision)
+        context['merge_form'] = merge_form
+        return render(request, 'iconolab/merge_revision.html', context)
+    
+    def post(self, request, *args, **kwargs):
+        # Handle merge form submit here
+        success, result = self.check_kwargs(kwargs)
+        if success:
+            (collection, image, annotation, revision) = result
+        else:
+            return result(request)
+        collection_name = kwargs['collection_name']
+        image_guid = kwargs['image_guid']
+        annotation_guid = kwargs['annotation_guid']
+        revision_guid = kwargs['revision_guid']
+        
+        merge_revision_form = AnnotationRevisionForm(request.POST)
+        if merge_revision_form.is_valid():
+            revision_title = merge_revision_form.cleaned_data['title']
+            revision_description = merge_revision_form.cleaned_data['description']
+            revision_fragment = merge_revision_form.cleaned_data['fragment']
+            revision_tags_json = merge_revision_form.cleaned_data['tags']
+            new_revision = annotation.merge_existing_revision(revision_title, revision_description, revision_fragment, revision_tags_json, revision)
+            revision_comment = merge_revision_form.cleaned_data['comment']
+            comment = IconolabComment.objects.create(
+                comment = revision_comment,
+                revision = new_revision,
+                content_type = ContentType.objects.get(app_label='iconolab', model='annotation'),
+                content_object = annotation,
+                site = Site.objects.get(id=settings.SITE_ID),
+                object_pk = annotation.id,
+                user = request.user,
+                user_name = request.user.username
+            )
+            return RedirectView.as_view(url=reverse('annotation_detail', kwargs={'collection_name': collection_name, 'image_guid': image_guid, 'annotation_guid': annotation_guid}))(request)
+        context = self.get_context_data(**kwargs)
+        context['image'] = image
+        context['merge_form'] = merge_revision_form
+        context['annotation'] = annotation
+        # Proposal data
+        context['proposal_revision'] = revision
+        context['proposal_tags_data'] = revision.get_tags_json()
+        context['proposal_comment'] = revision.creation_comment.first()
+        # Parent data
+        context['parent_revision'] = revision.parent_revision
+        context['parent_tags_data'] = revision.parent_revision.get_tags_json()
+        context['parent_comment'] = revision.parent_revision.creation_comment.first()
+        # Current data
+        context['current_revision'] = annotation.current_revision
+        context['current_tags_data'] = annotation.current_revision.get_tags_json()
+        context['current_comment'] = annotation.current_revision.creation_comment.first()
+        return render(request, 'iconolab/merge_revision.html', context)
+    
+    
+class NotFoundErrorView(View):
+    def get(self, request, *args, **kwargs):
+        # Handle image display here
+        pass
\ No newline at end of file