refresh dependencies version, and make it work for Django 2.0
authorymh <ymh.work@gmail.com>
Mon, 14 May 2018 14:45:22 +0200
changeset 532 a301e0bc677b
parent 531 fa14d77ec13a
child 533 e829a7cb5cb7
refresh dependencies version, and make it work for Django 2.0
.hgignore
src/iconolab/auth/urls.py
src/iconolab/auth/views.py
src/iconolab/forms/bookmarks.py
src/iconolab/mails.py
src/iconolab/models.py
src/iconolab/search_indexes/urls.py
src/iconolab/search_indexes/views.py
src/iconolab/settings/__init__.py
src/iconolab/templates/iconolab/detail_image.html
src/iconolab/templatetags/iconolab_tags.py
src/iconolab/urls.py
src/iconolab/views/comments.py
src/iconolab/views/objects.py
src/iconolab/views/userpages.py
src/requirements/base.txt
src/requirements/dev.txt
src/requirements/prod.txt
src/setup.py
--- a/.hgignore	Thu Oct 12 17:33:22 2017 +0200
+++ b/.hgignore	Mon May 14 14:45:22 2018 +0200
@@ -34,5 +34,7 @@
 ^src/.vscode
 ^src/requirements/custom.txt$
 ^src/iconolab/db.sqlite3
+^src/.direnv
+^src/.envrc$
 
 ^data/
--- a/src/iconolab/auth/urls.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/auth/urls.py	Mon May 14 14:45:22 2018 +0200
@@ -4,6 +4,7 @@
 from django.contrib.auth.views import login, logout, password_change
 from . import views
 
+app_name="iconolab-auth"
 urlpatterns = [
     url(r'^register/$', views.RegisterView.as_view(), name='register'),
     url(r'^register/created/$', views.UserCreatedView.as_view(), name='user_created'),
--- a/src/iconolab/auth/views.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/auth/views.py	Mon May 14 14:45:22 2018 +0200
@@ -2,7 +2,7 @@
 from django.contrib.auth import authenticate, login, logout, get_user_model
 from iconolab.auth.forms import UserCreationForm
 from django.shortcuts import redirect, render, HttpResponseRedirect
-from django.core.urlresolvers import reverse_lazy
+from django.urls import reverse_lazy
 from django.contrib.auth.forms import AuthenticationForm
 from django.views.generic import FormView
 from django.views.generic.base import RedirectView, TemplateView
@@ -32,7 +32,7 @@
 		return context
 
 	def get(self, request, *args, **kwargs):
-		if request.user.is_authenticated():
+		if request.user.is_authenticated:
 			return HttpResponseRedirect(self.get_success_url())
 		return super(LoginView, self).get(request, *args, **kwargs)
 
--- a/src/iconolab/forms/bookmarks.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/forms/bookmarks.py	Mon May 14 14:45:22 2018 +0200
@@ -18,7 +18,7 @@
         user = kwargs.pop('user', None)
         super(BookmarkForm, self).__init__(*args, **kwargs)
 
-        if user.is_authenticated():
+        if user.is_authenticated:
 
             self.user = user
 
--- a/src/iconolab/mails.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/mails.py	Mon May 14 14:45:22 2018 +0200
@@ -1,9 +1,7 @@
 from django.conf import settings
 from django.contrib.sites.models import Site
 from django.core.mail import send_mail
-from django.core.urlresolvers import reverse
-
-current_site = Site.objects.get_current()
+from django.urls import reverse
 
 class EmailManager():
 
@@ -15,6 +13,7 @@
     VERB_REQUEST_FOR_EXPERTISE = 'a fait un appel à expertise'
 
     def __message_content(self, verb):
+        current_site = Site.objects.get_current()
         notifications_url = 'http://' + current_site.domain + reverse('user_notifications')
 
         message  = 'Un utilisateur ' + verb + '\n'
--- a/src/iconolab/models.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/models.py	Mon May 14 14:45:22 2018 +0200
@@ -75,7 +75,7 @@
         Some items may belong to a "folder". This is actually a physical folder
     """
     folder_guid = models.UUIDField(default=uuid.uuid4, editable=False)
-    collection = models.ForeignKey(Collection, related_name="folders")
+    collection = models.ForeignKey(Collection, related_name="folders", on_delete=models.PROTECT)
     name = models.TextField(null=False, blank=False)
     description = models.TextField(null=True, blank=True)
     original_id = models.CharField(max_length=256, null=True, blank=True)
@@ -109,7 +109,7 @@
         Item objects belong to a collection, are linked to a metadata item, and
         to one or more images
     """
-    collection = models.ForeignKey(Collection, related_name="items")
+    collection = models.ForeignKey(Collection, related_name="items", on_delete=models.PROTECT)
     item_guid = models.UUIDField(default=uuid.uuid4, editable=False)
     folders = models.ManyToManyField('Folder')
 
@@ -128,7 +128,7 @@
         Metadata object for the item class. Each field represents what we can
         import from the provided .csv files
     """
-    item = models.OneToOneField('Item', related_name='metadatas')
+    item = models.OneToOneField('Item', related_name='metadatas', on_delete=models.PROTECT)
     authors = models.CharField(max_length=255, default="")
     school = models.CharField(max_length=255, default="")
     field = models.CharField(max_length=255, default="")
@@ -161,7 +161,7 @@
     media = models.ImageField(upload_to='uploads/',
                               height_field='height', width_field='width')
     item = models.ForeignKey(
-        'Item', related_name='images', null=True, blank=True)
+        'Item', related_name='images', null=True, blank=True, on_delete=models.PROTECT)
     height = models.IntegerField(null=False, blank=False)
     width = models.IntegerField(null=False, blank=False)
     created = models.DateTimeField(auto_now_add=True, null=True)
@@ -229,7 +229,7 @@
         displayed in image and item pages
     """
     image = models.OneToOneField(
-        'Image', related_name='stats', blank=False, null=False)
+        'Image', related_name='stats', blank=False, null=False, on_delete=models.PROTECT)
     views_count = models.IntegerField(blank=True, null=True, default=0)
     annotations_count = models.IntegerField(blank=True, null=True, default=0)
     submitted_revisions_count = models.IntegerField(
@@ -430,10 +430,10 @@
     image = models.ForeignKey(
         'Image', related_name='annotations', on_delete=models.CASCADE)
     source_revision = models.ForeignKey(
-        'AnnotationRevision', related_name='source_related_annotation', blank=True, null=True)
+        'AnnotationRevision', related_name='source_related_annotation', blank=True, null=True, on_delete=models.PROTECT)
     current_revision = models.OneToOneField(
-        'AnnotationRevision', related_name='current_for_annotation', blank=True, null=True)
-    author = models.ForeignKey(User, null=True)
+        'AnnotationRevision', related_name='current_for_annotation', blank=True, null=True, on_delete=models.PROTECT)
+    author = models.ForeignKey(User, null=True, on_delete=models.PROTECT)
     created = models.DateTimeField(auto_now_add=True, null=True)
     comments = GenericRelation(
         'IconolabComment', content_type_field='content_type_id', object_id_field='object_pk')
@@ -561,7 +561,7 @@
         displayed in annotation pages
     """
     annotation = models.OneToOneField(
-        'Annotation', related_name='stats', blank=False, null=False)
+        'Annotation', related_name='stats', blank=False, null=False, on_delete=models.PROTECT)
     submitted_revisions_count = models.IntegerField(
         blank=True, null=True, default=1)
     awaiting_revisions_count = models.IntegerField(
@@ -705,12 +705,12 @@
 
     revision_guid = models.UUIDField(default=uuid.uuid4)
     annotation = models.ForeignKey(
-        'Annotation', related_name='revisions', null=False, blank=False)
+        'Annotation', related_name='revisions', null=False, blank=False, on_delete=models.PROTECT)
     parent_revision = models.ForeignKey(
-        'AnnotationRevision', related_name='child_revisions', blank=True, null=True)
+        'AnnotationRevision', related_name='child_revisions', blank=True, null=True, on_delete=models.PROTECT)
     merge_parent_revision = models.ForeignKey(
-        'AnnotationRevision', related_name='child_revisions_merge', blank=True, null=True)
-    author = models.ForeignKey(User, null=True)
+        'AnnotationRevision', related_name='child_revisions_merge', blank=True, null=True, on_delete=models.PROTECT)
+    author = models.ForeignKey(User, null=True, on_delete=models.PROTECT)
     title = models.CharField(max_length=255)
     description = models.TextField(null=True)
     fragment = models.TextField()
@@ -879,7 +879,7 @@
     label_slug = models.SlugField(blank=True, null=True)
     link = models.URLField(unique=True)
     description = models.CharField(max_length=255, blank=True, null=True)
-    collection = models.ForeignKey('Collection', blank=True, null=True)
+    collection = models.ForeignKey('Collection', blank=True, null=True, on_delete=models.PROTECT)
 
     def is_internal(self):
         return self.link.startswith(settings.INTERNAL_TAGS_URL)
@@ -912,7 +912,7 @@
         Each comment can have a set of metacategories
     """
     revision = models.ForeignKey(
-        'AnnotationRevision', related_name='creation_comment', null=True, blank=True)
+        'AnnotationRevision', related_name='creation_comment', null=True, blank=True, on_delete=models.PROTECT)
     metacategories = models.ManyToManyField(
         'MetaCategory', through='MetaCategoryInfo', through_fields=('comment', 'metacategory'))
 
@@ -983,7 +983,7 @@
         (DISAGREEMENT, 'disagreement'),
     )
 
-    collection = models.ForeignKey(Collection, related_name="metacategories")
+    collection = models.ForeignKey(Collection, related_name="metacategories", on_delete=models.PROTECT)
     label = models.CharField(max_length=255)
     triggers_notifications = models.IntegerField(
         choices=NOTIFIED_USERS, default=NONE)
@@ -1042,11 +1042,11 @@
 
 
 class BookmarkCategory(models.Model):
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.PROTECT)
     name = models.CharField(max_length=255)
     created = models.DateTimeField(auto_now_add=True)
 
 class Bookmark(models.Model):
-    category = models.ForeignKey(BookmarkCategory)
-    image = models.ForeignKey(Image)
+    category = models.ForeignKey(BookmarkCategory, on_delete=models.PROTECT)
+    image = models.ForeignKey(Image, on_delete=models.PROTECT)
     created = models.DateTimeField(auto_now_add=True)
--- a/src/iconolab/search_indexes/urls.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/search_indexes/urls.py	Mon May 14 14:45:22 2018 +0200
@@ -3,6 +3,7 @@
 from django.conf.urls import url
 from . import views
 
+app_name = "iconolab-search_indexes"
 urlpatterns = [
     url(r'collection/(?P<collection_name>[a-z0-9\-]+)/model/(?P<model_type>[a-z0-9\-]+)', views.IconolabSearchView.as_view(), name="collection_with_model_search"),
     url(r'collection/(?P<collection_name>[a-z0-9\-]+)', views.IconolabSearchView.as_view(), name="collection_haystack_search"),
--- a/src/iconolab/search_indexes/views.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/search_indexes/views.py	Mon May 14 14:45:22 2018 +0200
@@ -2,7 +2,7 @@
 from haystack.query import RelatedSearchQuerySet
 from iconolab.search_indexes.forms import IconolabSearchForm
 from django.shortcuts import HttpResponse, redirect
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.views.generic import RedirectView
 from iconolab.models import Collection
 
--- a/src/iconolab/settings/__init__.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/settings/__init__.py	Mon May 14 14:45:22 2018 +0200
@@ -67,13 +67,12 @@
 
 SITE_ID = 1
 
-MIDDLEWARE_CLASSES = [
+MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 ]
--- a/src/iconolab/templates/iconolab/detail_image.html	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/templates/iconolab/detail_image.html	Mon May 14 14:45:22 2018 +0200
@@ -131,7 +131,7 @@
   var annotations = [];
   {% if image.annotations.exists %}
     {% for annotation in image.latest_annotations %}
-  annotations.push({{ annotation.current_revision|json|safe }});
+  annotations.push(JSON.parse("{{ annotation.current_revision|json|addslashes|safe }}"));
     {% endfor %}
   {% endif %}
 
--- a/src/iconolab/templatetags/iconolab_tags.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/templatetags/iconolab_tags.py	Mon May 14 14:45:22 2018 +0200
@@ -11,43 +11,43 @@
 # {% transform_matrix 230 200 100 100 %}
 @register.simple_tag
 def transform_matrix(im_width=0, im_height=0, max_x=0, max_y=0):
-	try :
-		x_ratio = im_width / max_x
-		y_ratio = im_height / max_y
-		value_list = [x_ratio, 0, 0, y_ratio, 0, 0]
-		matrix = ",".join([str(v) for v in value_list])
-	except:
-		matrix = ""
+    try :
+        x_ratio = im_width / max_x
+        y_ratio = im_height / max_y
+        value_list = [x_ratio, 0, 0, y_ratio, 0, 0]
+        matrix = ",".join([str(v) for v in value_list])
+    except:
+        matrix = ""
 
-	return matrix
+    return matrix
 
 @register.filter
 def clean_path(path):
-	result = ""
-	if not len(path):
-		return result
-	else:
-		path_infos = path.split(";")
-		if len(path_infos) > 0 :
-			result = path_infos[0]
-	return result
+    result = ""
+    if not len(path):
+        return result
+    else:
+        path_infos = path.split(";")
+        if len(path_infos) > 0 :
+            result = path_infos[0]
+    return result
 
 
 @register.filter
 def path_type(path):
-	result = ""
-	if not len(path):
-		return result
-	else:
-		path_infos = path.split(";")
-		if len(path_infos) > 1 :
-			result = path_infos[1]
+    result = ""
+    if not len(path):
+        return result
+    else:
+        path_infos = path.split(";")
+        if len(path_infos) > 1 :
+            result = path_infos[1]
 
-	return result
+    return result
 
 @register.simple_tag
 def version():
-	return __version__
+    return __version__
 
 @register.filter
 def get_item(dictionary, key):
@@ -63,7 +63,7 @@
 def json_dumps(data):
     if isinstance(data, AnnotationRevision) :
         serializer = AnnotationRevisionSerializer(data)
-        return JSONRenderer().render(serializer.data)
+        return JSONRenderer().render(serializer.data).decode('utf-8')
     return serialize('json', [data])
 
 @register.simple_tag(takes_context=True)
@@ -74,9 +74,9 @@
         return 'container-fluid'
     return 'container'
 
-@register.assignment_tag(takes_context=True)
+@register.simple_tag(takes_context=True)
 def is_bookmarked(context, image):
     request = context['request']
-    if not request.user.is_authenticated():
+    if not request.user.is_authenticated:
         return False
     return image.is_bookmarked_by(request.user)
--- a/src/iconolab/urls.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/urls.py	Mon May 14 14:45:22 2018 +0200
@@ -13,7 +13,7 @@
     1. Import the include() function: from django.conf.urls import url, include
     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
 """
-from django.core.urlresolvers import reverse_lazy
+from django.urls import reverse_lazy
 from django.conf.urls import url, include
 
 from django.contrib import admin
--- a/src/iconolab/views/comments.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/views/comments.py	Mon May 14 14:45:22 2018 +0200
@@ -21,7 +21,7 @@
     '''
     # Fill out some initial data fields from an authenticated user, if present
     data = request.POST.copy()
-    if request.user.is_authenticated():
+    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', ''):
@@ -78,7 +78,7 @@
     # Otherwise create the comment
     comment = form.get_comment_object()
     comment.ip_address = request.META.get('REMOTE_ADDR', None)
-    if request.user.is_authenticated():
+    if request.user.is_authenticated:
         comment.user = request.user
 
     # Signal that the comment is about to be saved
--- a/src/iconolab/views/objects.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/views/objects.py	Mon May 14 14:45:22 2018 +0200
@@ -8,7 +8,7 @@
 from django.contrib.sites.models import Site
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.db.models import Count, Prefetch
 from django.http import Http404
 from django.shortcuts import HttpResponse, get_object_or_404, redirect, render
@@ -617,7 +617,7 @@
             comments_list = paginator.page(paginator.num_pages)
         context['comments'] = comments_list
 
-        if request.user.is_authenticated():
+        if request.user.is_authenticated:
             user_comment_notifications = Notification.objects.filter(
                 recipient=request.user,
                 action_object_content_type__app_label='iconolab',
@@ -794,7 +794,7 @@
         context['revision'] = revision
         context['tags_data'] = revision.get_tags_json()
         context['comment'] = revision.creation_comment.first()
-        if request.user.is_authenticated() and annotation.author == request.user:
+        if request.user.is_authenticated and annotation.author == request.user:
             ann_author_notified = Notification.objects.filter(
                     recipient=request.user,
                     action_object_content_type__app_label='iconolab',
@@ -807,7 +807,7 @@
             if ann_author_notified:
                 ann_author_notified.first().mark_as_read()
                 context['notified_revision'] = True
-        if request.user.is_authenticated() and revision.author == request.user:
+        if request.user.is_authenticated and revision.author == request.user:
             rev_author_notified = Notification.objects.filter(
                     recipient=request.user,
                     action_object_content_type__app_label='iconolab',
--- a/src/iconolab/views/userpages.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/iconolab/views/userpages.py	Mon May 14 14:45:22 2018 +0200
@@ -1,6 +1,6 @@
 from django.shortcuts import HttpResponse, get_object_or_404, render, redirect
 from django.views.generic import View, DetailView
-from django.core.urlresolvers import reverse_lazy
+from django.urls import reverse_lazy
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
 from django.contrib.auth.models import User
@@ -63,7 +63,7 @@
         context = {}
         notifications = Notification.objects.filter(recipient=request.user)
 
-        if request.user.is_authenticated() and 'clear_notifications' in request.GET:
+        if request.user.is_authenticated and 'clear_notifications' in request.GET:
             Notification.objects.filter(recipient=request.user).mark_all_as_read()
 
         context['notifications_unread_ids'] = notifications.unread().values_list('id', flat=True)
@@ -149,7 +149,7 @@
 
     def post(self, request, *args, **kwargs):
 
-        if request.user.is_authenticated():
+        if request.user.is_authenticated:
             bookmark_id = kwargs.get('bookmark')
             bookmark = Bookmark.objects.get(id=bookmark_id)
             if bookmark.category.user == request.user:
@@ -165,7 +165,7 @@
 
     def post(self, request, *args, **kwargs):
 
-        if request.user.is_authenticated():
+        if request.user.is_authenticated:
             bookmark_id = kwargs.get('bookmark')
             bookmark = Bookmark.objects.get(id=bookmark_id)
             if bookmark.category.user == request.user:
--- a/src/requirements/base.txt	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/requirements/base.txt	Mon May 14 14:45:22 2018 +0200
@@ -1,19 +1,11 @@
-appdirs==1.4.3
-Django==1.10.5
-django-comments-xtd==1.6.3
-django-contrib-comments==1.7.3
-django-haystack==2.6.0
-django-model-utils==2.6.1
-django-notifications-hq==1.2
-djangorestframework==3.5.4
-elasticsearch==5.1.0
-jsonfield==1.0.3
-olefile==0.44
-packaging==16.8
-Pillow==4.0.0
-pyparsing==2.1.10
-pytz==2016.10
-requests==2.13.0
-six==1.10.0
-sorl-thumbnail==12.4a1
-urllib3==1.20
+Django==2.0.5
+django-comments-xtd==2.1.0
+django-contrib-comments==1.8.0
+django-haystack==2.8.1
+#django-notifications-hq==1.4.0a0
+git+https://github.com/django-notifications/django-notifications.git#egg=django-notifications-hq
+djangorestframework==3.8.2
+elasticsearch==6.2.0
+Pillow==5.1.0
+requests==2.18.4
+sorl-thumbnail==12.4.1
--- a/src/requirements/dev.txt	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/requirements/dev.txt	Mon May 14 14:45:22 2018 +0200
@@ -1,1 +1,2 @@
 -r base.txt
+setuptools_scm
--- a/src/requirements/prod.txt	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/requirements/prod.txt	Mon May 14 14:45:22 2018 +0200
@@ -1,4 +1,4 @@
 -r base.txt
 pylibmc
 uWSGI
-psycopg2
+psycopg2 --no-binary psycopg2
--- a/src/setup.py	Thu Oct 12 17:33:22 2017 +0200
+++ b/src/setup.py	Mon May 14 14:45:22 2018 +0200
@@ -120,8 +120,9 @@
             'Programming Language :: Python',
             'Topic :: Utilities'
         ],
+        setup_requires=['setuptools_scm'],
         install_requires=[
-            "Django >= 1.9",
+            "Django >= 2.0",
             "django-comments-xtd",
             "django-contrib-comments",
             "django-haystack",
@@ -132,8 +133,8 @@
             "pytz",
             "requests",
             "six",
-            "sorl-thumbnail >= 12.4a1",
-            "djangorestframework >= 3.5"
+            "sorl-thumbnail >= 12.4.1",
+            "djangorestframework >= 3.8"
         ],
     )