signals refactoring followup: fixed circular import + added a profile view and template and link in header + refactored views into a views module
--- a/src/iconolab/signals/handlers.py Mon Aug 01 11:51:50 2016 +0200
+++ b/src/iconolab/signals/handlers.py Mon Aug 01 12:59:18 2016 +0200
@@ -2,7 +2,6 @@
from django.db.models.signals import post_save
from django.dispatch import Signal, receiver
-from iconolab.models import Annotation, AnnotationRevision, IconolabComment
# Signal sent during method Annotation.validate_existing_revision to update stats
revision_accepted = Signal(providing_args=["instance"])
@@ -10,22 +9,25 @@
def increment_stats_on_new_revision(sender, instance, **kwargs):
- # Annotation stats
- annotation = instance.annotation
- annotation.stats.submitted_revisions_count += 1
- if instance.state in [AnnotationRevision.ACCEPTED, AnnotationRevision.STUDIED]:
- annotation.stats.accepted_revisions_count += 1
- annotation.stats.set_tags_stats()
- annotation.stats.save()
- # Image stats
- image = instance.annotation.image
- image.stats.submitted_revisions_count += 1
- image.stats.set_tags_stats()
- image.stats.save()
+ from iconolab.models import AnnotationRevision
+ if sender == AnnotationRevision:
+ # Annotation stats
+ annotation = instance.annotation
+ annotation.stats.submitted_revisions_count += 1
+ if instance.state in [AnnotationRevision.ACCEPTED, AnnotationRevision.STUDIED]:
+ annotation.stats.accepted_revisions_count += 1
+ annotation.stats.set_tags_stats()
+ annotation.stats.save()
+ # Image stats
+ image = instance.annotation.image
+ image.stats.submitted_revisions_count += 1
+ image.stats.set_tags_stats()
+ image.stats.save()
def increment_stats_on_new_comments(sender, instance, created, **kwargs):
- if created:
+ from iconolab.models import IconolabComment
+ if created and sender == IconolabComment:
model = apps.get_model(instance.content_type.app_label,instance.content_type.model)
object_pk = instance.object_pk
annotation = model._default_manager.get(pk=object_pk)
@@ -36,20 +38,23 @@
def increment_accepted_revisions(sender, instance, **kwargs):
- annotation = instance.annotation
- annotation.stats.accepted_revisions_count += 1
- annotation.stats.save()
+ from iconolab.models import AnnotationRevision
+ if sender == AnnotationRevision:
+ annotation = instance.annotation
+ annotation.stats.accepted_revisions_count += 1
+ annotation.stats.save()
def increment_annotations_count(sender, instance, created, **kwargs):
- if created:
+ from iconolab.models import Annotation
+ if created and sender == Annotation:
image = instance.image
image.stats.annotations_count += 1
image.stats.submitted_revisions_count += 1
image.stats.set_tags_stats()
image.stats.save()
-post_save.connect(increment_annotations_count, sender=Annotation)
-post_save.connect(increment_stats_on_new_comments, sender=IconolabComment)
-revision_created.connect(increment_stats_on_new_revision, sender=AnnotationRevision)
-revision_accepted.connect(increment_accepted_revisions, sender=AnnotationRevision)
+post_save.connect(increment_annotations_count)
+post_save.connect(increment_stats_on_new_comments)
+revision_created.connect(increment_stats_on_new_revision)
+revision_accepted.connect(increment_accepted_revisions)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/templates/iconolab/user_page.html Mon Aug 01 12:59:18 2016 +0200
@@ -0,0 +1,11 @@
+{% extends 'iconolab_base.html' %}
+
+{% load staticfiles %}
+
+{% load thumbnail %}
+
+{% load iconolab_tags %}
+
+{% block content %}
+ <div id="user-profile-block" class="row" style="border: 1px solid gray;padding-top: 10px;"></div>
+{% endblock %}
\ No newline at end of file
--- a/src/iconolab/templates/partials/header.html Mon Aug 01 11:51:50 2016 +0200
+++ b/src/iconolab/templates/partials/header.html Mon Aug 01 12:59:18 2016 +0200
@@ -25,7 +25,7 @@
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
- <li><a href="#">{{user.username}}: Mon espace</a></li>
+ <li><a href="{% url 'user_profile' %}">{{user.username}}: Mon espace</a></li>
<li><a href="{% url 'account:logout' %}">Se déconnecter</a></li>
{% else %}
<li><a href="{% url 'account:register' %}">Créer un compte</a></li>
--- a/src/iconolab/urls.py Mon Aug 01 11:51:50 2016 +0200
+++ b/src/iconolab/urls.py Mon Aug 01 12:59:18 2016 +0200
@@ -16,7 +16,7 @@
from django.core.urlresolvers import reverse_lazy
from django.conf.urls import url, include
from django.contrib import admin
-from . import views
+from iconolab import views
from . import settings
from django.conf.urls.static import static
@@ -24,22 +24,23 @@
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
- url(r'^$', views.RedirectView.as_view(url=reverse_lazy("home"))),
+ url(r'^$', views.iconolab.RedirectView.as_view(url=reverse_lazy("home"))),
url(r'^admin/', admin.site.urls),
- url(r'^home$', views.GlobalHomepageView.as_view(), name="home"),
- url(r'^collections/(?P<collection_name>[a-z]+)$', views.CollectionHomepageView.as_view(), name='collection_home'), # Home fond
- url(r'^collections/(?P<collection_name>[a-z]+)/items/(?P<item_guid>[^/]+)$', views.ShowItemView.as_view(), name='item_detail'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)$', views.ShowImageView.as_view(), name='image_detail'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/create$', login_required(views.CreateAnnotationView.as_view()), name='annotation_create'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/detail$', views.ShowAnnotationView.as_view(), name='annotation_detail'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/edit$', login_required(views.EditAnnotationView.as_view()), name='annotation_edit'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/revisions/(?P<revision_guid>[^/]+)/detail', views.ShowRevisionView.as_view(), name='revision_detail'),
- url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/revisions/(?P<revision_guid>[^/]+)/merge$', login_required(views.MergeProposalView.as_view()), name='annotation_merge'),
- url(r'errors/404', views.NotFoundErrorView.as_view(), name="404error"),
+ url(r'^home$', views.iconolab.GlobalHomepageView.as_view(), name="home"),
+ url(r'^collections/(?P<collection_name>[a-z]+)$', views.iconolab.CollectionHomepageView.as_view(), name='collection_home'), # Home fond
+ url(r'^collections/(?P<collection_name>[a-z]+)/items/(?P<item_guid>[^/]+)$', views.iconolab.ShowItemView.as_view(), name='item_detail'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)$', views.iconolab.ShowImageView.as_view(), name='image_detail'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/create$', login_required(views.iconolab.CreateAnnotationView.as_view()), name='annotation_create'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/detail$', views.iconolab.ShowAnnotationView.as_view(), name='annotation_detail'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/edit$', login_required(views.iconolab.EditAnnotationView.as_view()), name='annotation_edit'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/revisions/(?P<revision_guid>[^/]+)/detail', views.iconolab.ShowRevisionView.as_view(), name='revision_detail'),
+ url(r'^collections/(?P<collection_name>[a-z]+)/images/(?P<image_guid>[^/]+)/annotations/(?P<annotation_guid>[^/]+)/revisions/(?P<revision_guid>[^/]+)/merge$', login_required(views.iconolab.MergeProposalView.as_view()), name='annotation_merge'),
+ url(r'^user/profile', login_required(views.iconolab.UserProfileView), name="user_profile"),
+ url(r'^errors/404', views.iconolab.NotFoundErrorView.as_view(), name="404error"),
url(r'^rest', include('restapi.urls')),
url(r'^account/', include('iconolab.auth.urls', namespace='account')),
url(r'^comments/', include('django_comments_xtd.urls')),
- url(r'^comments/annotation/post', views.post_comment_iconolab, name="post_comment")
+ url(r'^comments/annotation/post', views.comments.post_comment_iconolab, name="post_comment")
]
urlpatterns += staticfiles_urlpatterns()
--- a/src/iconolab/views.py Mon Aug 01 11:51:50 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,596 +0,0 @@
-from django.apps import apps
-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.views.decorators.csrf import csrf_protect
-from django.views.decorators.http import require_POST
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
-from django.core.urlresolvers import reverse
-from django.core.exceptions import ObjectDoesNotExist, ValidationError
-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
-import datetime
-import django_comments
-from django_comments import signals
-from django_comments.views.utils import next_redirect, confirmation_view
-
-
-class GlobalHomepageView(View):
- def get(self, request, *args, **kwargs):
- context = {}
- context["collections"] = Collection.objects
- return render(request, 'iconolab/home.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
-
-
-@csrf_protect
-@require_POST
-def post_comment_iconolab(request, next=None, using=None):
- '''
- Post a comment.
- HTTP POST is required. If ``POST['submit'] == 'preview'`` or if there are
- errors a preview template, ``comments/preview.html``, will be rendered.
- '''
- # Fill out some initial data fields from an authenticated user, if present
- data = request.POST.copy()
- if request.user.is_authenticated():
- if not data.get('name', ''):
- data['name'] = request.user.get_full_name() or request.user.get_username()
- if not data.get('email', ''):
- data['email'] = request.user.email
-
- # Look up the object we're trying to comment about
- ctype = data.get('content_type')
- object_pk = data.get('object_pk')
- if ctype is None or object_pk is None:
- return CommentPostBadRequest('Missing content_type or object_pk field.')
- try:
- model = apps.get_model(*ctype.split('.', 1))
- target = model._default_manager.using(using).get(pk=object_pk)
- except TypeError:
- return CommentPostBadRequest(
- 'Invalid content_type value: %r' % escape(ctype))
- except AttributeError:
- return CommentPostBadRequest(
- 'The given content-type %r does not resolve to a valid model.' % escape(ctype))
- except ObjectDoesNotExist:
- return CommentPostBadRequest(
- 'No object matching content-type %r and object PK %r exists.' % (
- escape(ctype), escape(object_pk)))
- except (ValueError, ValidationError) as e:
- return CommentPostBadRequest(
- 'Attempting go get content-type %r and object PK %r exists raised %s' % (
- escape(ctype), escape(object_pk), e.__class__.__name__))
-
- # Do we want to preview the comment?
- preview = 'preview' in data
-
- # Construct the comment form
- form = django_comments.get_form()(target, data=data)
-
- # Check security information
- if form.security_errors():
- return CommentPostBadRequest(
- 'The comment form failed security verification: %s' % escape(str(form.security_errors())))
-
- # If there are errors or if we requested a preview show the comment
- if form.errors:
- return render(request, 'iconolab/detail_annotation.html', {
- 'comment_form': form,
- 'next': data.get('next', next),
- 'annotation': target,
- 'annotation_guid': target.annotation_guid,
- 'image_guid': target.image.image_guid,
- 'collection_name': target.image.item.collection.name,
- 'tags_data': target.current_revision.get_tags_json()
- },
- )
-
- # Otherwise create the comment
- comment = form.get_comment_object()
- comment.ip_address = request.META.get('REMOTE_ADDR', None)
- if request.user.is_authenticated():
- comment.user = request.user
-
- # Signal that the comment is about to be saved
- responses = signals.comment_will_be_posted.send(
- sender=comment.__class__,
- comment=comment,
- request=request
- )
-
- for (receiver, response) in responses:
- if response is False:
- return CommentPostBadRequest(
- 'comment_will_be_posted receiver %r killed the comment' % receiver.__name__)
-
- # Save the comment and signal that it was saved
- comment.save()
-
- signals.comment_was_posted.send(
- sender=comment.__class__,
- comment=comment,
- request=request
- )
-
- # Creating metacategories here as apparently there is no way to make it work easily woth django_comments_xtd
- for metacategory in form.cleaned_data.get("metacategories", []):
- if 'xtd_comment' in comment:
- metacategory_info = MetaCategoryInfo.objects.create(
- comment = comment['xtd_comment'],
- metacategory = metacategory
- )
-
- return next_redirect(request, fallback=next or 'comments-comment-done',
- c=comment._get_pk_val())
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/views/__init__.py Mon Aug 01 12:59:18 2016 +0200
@@ -0,0 +1,2 @@
+from . import comments
+from . import iconolab
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/views/comments.py Mon Aug 01 12:59:18 2016 +0200
@@ -0,0 +1,110 @@
+from django.apps import apps
+from django.views.decorators.csrf import csrf_protect
+from django.views.decorators.http import require_POST
+from django.core.exceptions import ObjectDoesNotExist, ValidationError
+import datetime
+import django_comments
+from django_comments import signals
+from django_comments.views.utils import next_redirect, confirmation_view
+from django_comments.views.comments import CommentPostBadRequest
+
+@csrf_protect
+@require_POST
+def post_comment_iconolab(request, next=None, using=None):
+ '''
+ Post a comment.
+ HTTP POST is required. If ``POST['submit'] == 'preview'`` or if there are
+ errors a preview template, ``comments/preview.html``, will be rendered.
+ '''
+ # Fill out some initial data fields from an authenticated user, if present
+ data = request.POST.copy()
+ if request.user.is_authenticated():
+ if not data.get('name', ''):
+ data['name'] = request.user.get_full_name() or request.user.get_username()
+ if not data.get('email', ''):
+ data['email'] = request.user.email
+
+ # Look up the object we're trying to comment about
+ ctype = data.get('content_type')
+ object_pk = data.get('object_pk')
+ if ctype is None or object_pk is None:
+ return CommentPostBadRequest('Missing content_type or object_pk field.')
+ try:
+ model = apps.get_model(*ctype.split('.', 1))
+ target = model._default_manager.using(using).get(pk=object_pk)
+ except TypeError:
+ return CommentPostBadRequest(
+ 'Invalid content_type value: %r' % escape(ctype))
+ except AttributeError:
+ return CommentPostBadRequest(
+ 'The given content-type %r does not resolve to a valid model.' % escape(ctype))
+ except ObjectDoesNotExist:
+ return CommentPostBadRequest(
+ 'No object matching content-type %r and object PK %r exists.' % (
+ escape(ctype), escape(object_pk)))
+ except (ValueError, ValidationError) as e:
+ return CommentPostBadRequest(
+ 'Attempting go get content-type %r and object PK %r exists raised %s' % (
+ escape(ctype), escape(object_pk), e.__class__.__name__))
+
+ # Do we want to preview the comment?
+ preview = 'preview' in data
+
+ # Construct the comment form
+ form = django_comments.get_form()(target, data=data)
+
+ # Check security information
+ if form.security_errors():
+ return CommentPostBadRequest(
+ 'The comment form failed security verification: %s' % escape(str(form.security_errors())))
+
+ # If there are errors or if we requested a preview show the comment
+ if form.errors:
+ return render(request, 'iconolab/detail_annotation.html', {
+ 'comment_form': form,
+ 'next': data.get('next', next),
+ 'annotation': target,
+ 'annotation_guid': target.annotation_guid,
+ 'image_guid': target.image.image_guid,
+ 'collection_name': target.image.item.collection.name,
+ 'tags_data': target.current_revision.get_tags_json()
+ },
+ )
+
+ # Otherwise create the comment
+ comment = form.get_comment_object()
+ comment.ip_address = request.META.get('REMOTE_ADDR', None)
+ if request.user.is_authenticated():
+ comment.user = request.user
+
+ # Signal that the comment is about to be saved
+ responses = signals.comment_will_be_posted.send(
+ sender=comment.__class__,
+ comment=comment,
+ request=request
+ )
+
+ for (receiver, response) in responses:
+ if response is False:
+ return CommentPostBadRequest(
+ 'comment_will_be_posted receiver %r killed the comment' % receiver.__name__)
+
+ # Save the comment and signal that it was saved
+ comment.save()
+
+ signals.comment_was_posted.send(
+ sender=comment.__class__,
+ comment=comment,
+ request=request
+ )
+
+ # Creating metacategories here as apparently there is no way to make it work easily woth django_comments_xtd
+ for metacategory in form.cleaned_data.get("metacategories", []):
+ if 'xtd_comment' in comment:
+ metacategory_info = MetaCategoryInfo.objects.create(
+ comment = comment['xtd_comment'],
+ metacategory = metacategory
+ )
+
+ return next_redirect(request, fallback=next or 'comments-comment-done',
+ c=comment._get_pk_val())
\ No newline at end of file
--- /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