Django 2.0
authorRadek Czajka <rczajka@rczajka.pl>
Wed, 2 Oct 2019 10:37:28 +0000 (12:37 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Wed, 2 Oct 2019 10:37:28 +0000 (12:37 +0200)
25 files changed:
requirements/requirements.txt
src/apiclient/migrations/0001_initial.py
src/apiclient/models.py
src/apiclient/views.py
src/catalogue/migrations/0001_initial.py
src/catalogue/migrations/0004_auto_20191002_1224.py [new file with mode: 0644]
src/catalogue/models/book.py
src/catalogue/models/chunk.py
src/catalogue/models/image.py
src/catalogue/models/publish_log.py
src/catalogue/templatetags/catalogue.py
src/catalogue/templatetags/wall.py
src/catalogue/views.py
src/cover/migrations/0002_auto_20191002_1224.py [new file with mode: 0644]
src/cover/models.py
src/dvcs/models.py
src/redakcja/settings/__init__.py
src/redakcja/urls.py
src/toolbar/migrations/0001_initial.py
src/toolbar/migrations/0002_auto_20191002_1224.py [new file with mode: 0644]
src/toolbar/models.py
src/wiki/forms.py
src/wiki/helpers.py
src/wiki/views.py
src/wiki_img/views.py

index 08a8823..9e27efa 100644 (file)
@@ -11,7 +11,7 @@ python-slugify
 librarian==1.7.6
 
 ## Django
-Django==1.11.25
+Django==2.0.13
 fnpdjango==0.4.3
 django-pipeline==1.6.14
 django-cas-ng==3.6.0
@@ -21,4 +21,4 @@ fnp-django-pagination==2.2.4
 django-gravatar2==1.4.2
 django-extensions==2.1.6
 
-raven
+sentry-sdk==0.12.2
index 43f2d78..88f51b7 100644 (file)
@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
                 ('token', models.CharField(max_length=64, null=True, blank=True)),
                 ('token_secret', models.CharField(max_length=64, null=True, blank=True)),
                 ('beta', models.BooleanField(default=False)),
-                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
             options={
             },
index 64130bc..c750e6a 100644 (file)
@@ -3,7 +3,7 @@ from django.contrib.auth.models import User
 
 
 class OAuthConnection(models.Model):
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, models.CASCADE)
     access = models.BooleanField(default=False)
     token = models.CharField(max_length=64, null=True, blank=True)
     token_secret = models.CharField(max_length=64, null=True, blank=True)
index 239682a..8d0a798 100644 (file)
@@ -1,7 +1,7 @@
 import cgi
 
 from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.http import HttpResponseRedirect, HttpResponse
 import oauth2
 
index 2dd2336..794db48 100644 (file)
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.db import models, migrations
 import datetime
 import django.db.models.deletion
@@ -46,8 +43,8 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('timestamp', models.DateTimeField(auto_now_add=True, verbose_name='time')),
-                ('book', models.ForeignKey(related_name='publish_log', verbose_name='book', to='catalogue.Book')),
-                ('user', models.ForeignKey(verbose_name='user', to=settings.AUTH_USER_MODEL)),
+                ('book', models.ForeignKey(related_name='publish_log', verbose_name='book', to='catalogue.Book', on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(verbose_name='user', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ['-timestamp'],
@@ -67,8 +64,8 @@ class Migration(migrations.Migration):
                 ('_short_html', models.TextField(null=True, editable=False, blank=True)),
                 ('_hidden', models.NullBooleanField(editable=False)),
                 ('_changed', models.NullBooleanField(editable=False)),
-                ('book', models.ForeignKey(editable=False, to='catalogue.Book', verbose_name='book')),
-                ('creator', models.ForeignKey(related_name='created_chunk', blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='creator')),
+                ('book', models.ForeignKey(editable=False, to='catalogue.Book', verbose_name='book', on_delete=models.CASCADE)),
+                ('creator', models.ForeignKey(related_name='created_chunk', blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='creator', on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ['number'],
@@ -89,9 +86,9 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(default=datetime.datetime.now, editable=False, db_index=True)),
                 ('publishable', models.BooleanField(default=False, verbose_name='publishable')),
                 ('data', models.FileField(upload_to=dvcs.models.data_upload_to, storage=dvcs.storage.GzipFileSystemStorage(location=settings.CATALOGUE_REPO_PATH), verbose_name='data')),
-                ('author', models.ForeignKey(verbose_name='author', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
-                ('merge_parent', models.ForeignKey(related_name='merge_children', default=None, blank=True, to='catalogue.ChunkChange', null=True, verbose_name='merge parent')),
-                ('parent', models.ForeignKey(related_name='children', default=None, blank=True, to='catalogue.ChunkChange', null=True, verbose_name='parent')),
+                ('author', models.ForeignKey(verbose_name='author', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)),
+                ('merge_parent', models.ForeignKey(related_name='merge_children', default=None, blank=True, to='catalogue.ChunkChange', null=True, verbose_name='merge parent', on_delete=models.CASCADE)),
+                ('parent', models.ForeignKey(related_name='children', default=None, blank=True, to='catalogue.ChunkChange', null=True, verbose_name='parent', on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('created_at',),
@@ -105,8 +102,8 @@ class Migration(migrations.Migration):
             name='ChunkPublishRecord',
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('book_record', models.ForeignKey(verbose_name='book publish record', to='catalogue.BookPublishRecord')),
-                ('change', models.ForeignKey(related_name='publish_log', verbose_name='change', to='catalogue.ChunkChange')),
+                ('book_record', models.ForeignKey(verbose_name='book publish record', to='catalogue.BookPublishRecord', on_delete=models.CASCADE)),
+                ('change', models.ForeignKey(related_name='publish_log', verbose_name='change', to='catalogue.ChunkChange', on_delete=models.CASCADE)),
             ],
             options={
                 'verbose_name': 'chunk publish record',
@@ -142,7 +139,7 @@ class Migration(migrations.Migration):
                 ('_new_publishable', models.NullBooleanField(editable=False)),
                 ('_published', models.NullBooleanField(editable=False)),
                 ('_changed', models.NullBooleanField(editable=False)),
-                ('creator', models.ForeignKey(related_name='created_image', blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='creator')),
+                ('creator', models.ForeignKey(related_name='created_image', blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='creator', on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ['title'],
@@ -163,9 +160,9 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(default=datetime.datetime.now, editable=False, db_index=True)),
                 ('publishable', models.BooleanField(default=False, verbose_name='publishable')),
                 ('data', models.FileField(upload_to=dvcs.models.data_upload_to, storage=dvcs.storage.GzipFileSystemStorage(location=settings.CATALOGUE_IMAGE_REPO_PATH), verbose_name='data')),
-                ('author', models.ForeignKey(verbose_name='author', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
-                ('merge_parent', models.ForeignKey(related_name='merge_children', default=None, blank=True, to='catalogue.ImageChange', null=True, verbose_name='merge parent')),
-                ('parent', models.ForeignKey(related_name='children', default=None, blank=True, to='catalogue.ImageChange', null=True, verbose_name='parent')),
+                ('author', models.ForeignKey(verbose_name='author', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)),
+                ('merge_parent', models.ForeignKey(related_name='merge_children', default=None, blank=True, to='catalogue.ImageChange', null=True, verbose_name='merge parent', on_delete=models.CASCADE)),
+                ('parent', models.ForeignKey(related_name='children', default=None, blank=True, to='catalogue.ImageChange', null=True, verbose_name='parent', on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('created_at',),
@@ -180,9 +177,9 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('timestamp', models.DateTimeField(auto_now_add=True, verbose_name='time')),
-                ('change', models.ForeignKey(related_name='publish_log', verbose_name='change', to='catalogue.ImageChange')),
-                ('image', models.ForeignKey(related_name='publish_log', verbose_name='image', to='catalogue.Image')),
-                ('user', models.ForeignKey(verbose_name='user', to=settings.AUTH_USER_MODEL)),
+                ('change', models.ForeignKey(related_name='publish_log', verbose_name='change', to='catalogue.ImageChange', on_delete=models.CASCADE)),
+                ('image', models.ForeignKey(related_name='publish_log', verbose_name='image', to='catalogue.Image', on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(verbose_name='user', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ['-timestamp'],
@@ -230,7 +227,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='imagechange',
             name='tree',
-            field=models.ForeignKey(related_name='change_set', verbose_name='document', to='catalogue.Image'),
+            field=models.ForeignKey(related_name='change_set', verbose_name='document', to='catalogue.Image', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
@@ -240,25 +237,25 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='image',
             name='head',
-            field=models.ForeignKey(default=None, editable=False, to='catalogue.ImageChange', blank=True, help_text="This document's current head.", null=True, verbose_name='head'),
+            field=models.ForeignKey(default=None, editable=False, to='catalogue.ImageChange', blank=True, help_text="This document's current head.", null=True, verbose_name='head', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='image',
             name='project',
-            field=models.ForeignKey(blank=True, to='catalogue.Project', null=True),
+            field=models.ForeignKey(blank=True, to='catalogue.Project', null=True, on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='image',
             name='stage',
-            field=models.ForeignKey(verbose_name='stage', blank=True, to='catalogue.ImageTag', null=True),
+            field=models.ForeignKey(verbose_name='stage', blank=True, to='catalogue.ImageTag', null=True, on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='image',
             name='user',
-            field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text='Work assignment.', null=True, verbose_name='user'),
+            field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text='Work assignment.', null=True, verbose_name='user', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
@@ -270,7 +267,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='chunkchange',
             name='tree',
-            field=models.ForeignKey(related_name='change_set', verbose_name='document', to='catalogue.Chunk'),
+            field=models.ForeignKey(related_name='change_set', verbose_name='document', to='catalogue.Chunk', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
@@ -280,19 +277,19 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='chunk',
             name='head',
-            field=models.ForeignKey(default=None, editable=False, to='catalogue.ChunkChange', blank=True, help_text="This document's current head.", null=True, verbose_name='head'),
+            field=models.ForeignKey(default=None, editable=False, to='catalogue.ChunkChange', blank=True, help_text="This document's current head.", null=True, verbose_name='head', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='chunk',
             name='stage',
-            field=models.ForeignKey(verbose_name='stage', blank=True, to='catalogue.ChunkTag', null=True),
+            field=models.ForeignKey(verbose_name='stage', blank=True, to='catalogue.ChunkTag', null=True, on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='chunk',
             name='user',
-            field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text='Work assignment.', null=True, verbose_name='user'),
+            field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text='Work assignment.', null=True, verbose_name='user', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AlterUniqueTogether(
@@ -308,13 +305,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='book',
             name='parent',
-            field=models.ForeignKey(related_name='children', blank=True, editable=False, to='catalogue.Book', null=True, verbose_name='parent'),
+            field=models.ForeignKey(related_name='children', blank=True, editable=False, to='catalogue.Book', null=True, verbose_name='parent', on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.AddField(
             model_name='book',
             name='project',
-            field=models.ForeignKey(blank=True, to='catalogue.Project', null=True),
+            field=models.ForeignKey(blank=True, to='catalogue.Project', null=True, on_delete=models.CASCADE),
             preserve_default=True,
         ),
         migrations.CreateModel(
diff --git a/src/catalogue/migrations/0004_auto_20191002_1224.py b/src/catalogue/migrations/0004_auto_20191002_1224.py
new file mode 100644 (file)
index 0000000..443e777
--- /dev/null
@@ -0,0 +1,105 @@
+# Generated by Django 2.0.13 on 2019-10-02 12:24
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('catalogue', '0003_chunk__new_publishable'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='book',
+            name='parent',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='catalogue.Book', verbose_name='parent'),
+        ),
+        migrations.AlterField(
+            model_name='book',
+            name='project',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='catalogue.Project'),
+        ),
+        migrations.AlterField(
+            model_name='chunk',
+            name='creator',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_chunk', to=settings.AUTH_USER_MODEL, verbose_name='creator'),
+        ),
+        migrations.AlterField(
+            model_name='chunk',
+            name='head',
+            field=models.ForeignKey(blank=True, default=None, editable=False, help_text="This document's current head.", null=True, on_delete=django.db.models.deletion.SET_NULL, to='catalogue.ChunkChange', verbose_name='head'),
+        ),
+        migrations.AlterField(
+            model_name='chunk',
+            name='user',
+            field=models.ForeignKey(blank=True, help_text='Work assignment.', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user'),
+        ),
+        migrations.AlterField(
+            model_name='chunkchange',
+            name='author',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='author'),
+        ),
+        migrations.AlterField(
+            model_name='chunkchange',
+            name='description',
+            field=models.TextField(blank=True, default='', verbose_name='description'),
+        ),
+        migrations.AlterField(
+            model_name='chunkchange',
+            name='merge_parent',
+            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='merge_children', to='catalogue.ChunkChange', verbose_name='merge parent'),
+        ),
+        migrations.AlterField(
+            model_name='chunkchange',
+            name='parent',
+            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='catalogue.ChunkChange', verbose_name='parent'),
+        ),
+        migrations.AlterField(
+            model_name='image',
+            name='creator',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_image', to=settings.AUTH_USER_MODEL, verbose_name='creator'),
+        ),
+        migrations.AlterField(
+            model_name='image',
+            name='head',
+            field=models.ForeignKey(blank=True, default=None, editable=False, help_text="This document's current head.", null=True, on_delete=django.db.models.deletion.SET_NULL, to='catalogue.ImageChange', verbose_name='head'),
+        ),
+        migrations.AlterField(
+            model_name='image',
+            name='image',
+            field=models.FileField(upload_to='catalogue/images', verbose_name='image'),
+        ),
+        migrations.AlterField(
+            model_name='image',
+            name='project',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='catalogue.Project'),
+        ),
+        migrations.AlterField(
+            model_name='image',
+            name='user',
+            field=models.ForeignKey(blank=True, help_text='Work assignment.', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user'),
+        ),
+        migrations.AlterField(
+            model_name='imagechange',
+            name='author',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='author'),
+        ),
+        migrations.AlterField(
+            model_name='imagechange',
+            name='description',
+            field=models.TextField(blank=True, default='', verbose_name='description'),
+        ),
+        migrations.AlterField(
+            model_name='imagechange',
+            name='merge_parent',
+            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='merge_children', to='catalogue.ImageChange', verbose_name='merge parent'),
+        ),
+        migrations.AlterField(
+            model_name='imagechange',
+            name='parent',
+            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='catalogue.ImageChange', verbose_name='parent'),
+        ),
+    ]
index a846f6e..fc0e18f 100755 (executable)
@@ -4,6 +4,7 @@
 from django.contrib.sites.models import Site
 from django.db import models, transaction
 from django.template.loader import render_to_string
+from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
 from django.conf import settings
 from slugify import slugify
@@ -26,10 +27,10 @@ class Book(models.Model):
     slug = models.SlugField(_('slug'), max_length=128, unique=True, db_index=True)
     public = models.BooleanField(_('public'), default=True, db_index=True)
     gallery = models.CharField(_('scan gallery name'), max_length=255, blank=True)
-    project = models.ForeignKey(Project, null=True, blank=True)
+    project = models.ForeignKey(Project, models.SET_NULL, null=True, blank=True)
 
     #wl_slug = models.CharField(_('title'), max_length=255, null=True, db_index=True, editable=False)
-    parent = models.ForeignKey('self', null=True, blank=True, verbose_name=_('parent'), related_name="children", editable=False)
+    parent = models.ForeignKey('self', models.SET_NULL, null=True, blank=True, verbose_name=_('parent'), related_name="children", editable=False)
     parent_number = models.IntegerField(_('parent number'), null=True, blank=True, db_index=True, editable=False)
 
     # Cache
@@ -73,9 +74,8 @@ class Book(models.Model):
     def __str__(self):
         return self.title
 
-    @models.permalink
     def get_absolute_url(self):
-        return ("catalogue_book", [self.slug])
+        return reverse("catalogue_book", args=[self.slug])
 
     def correct_about(self):
         return "http://%s%s" % (
index 4182d08..b3e6aca 100755 (executable)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -7,6 +5,7 @@ from django.conf import settings
 from django.db import models
 from django.db.utils import IntegrityError
 from django.template.loader import render_to_string
+from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
 from catalogue.helpers import cached_in_field
 from catalogue.managers import VisibleManager
@@ -17,7 +16,7 @@ class Chunk(dvcs_models.Document):
     """ An editable chunk of text. Every Book text is divided into chunks. """
     REPO_PATH = settings.CATALOGUE_REPO_PATH
 
-    book = models.ForeignKey('Book', editable=False, verbose_name=_('book'))
+    book = models.ForeignKey('Book', models.CASCADE, editable=False, verbose_name=_('book'))
     number = models.IntegerField(_('number'))
     title = models.CharField(_('title'), max_length=255, blank=True)
     slug = models.SlugField(_('slug'))
@@ -46,9 +45,8 @@ class Chunk(dvcs_models.Document):
     def __str__(self):
         return "%d:%d: %s" % (self.book_id, self.number, self.title)
 
-    @models.permalink
     def get_absolute_url(self):
-        return "wiki_editor", [self.book.slug, self.slug]
+        return reverse("wiki_editor", args=[self.book.slug, self.slug])
 
     def pretty_name(self, book_length=None):
         title = self.book.title
index dbe1c04..becc308 100755 (executable)
@@ -5,6 +5,7 @@ from django.conf import settings
 from django.contrib.sites.models import Site
 from django.db import models
 from django.template.loader import render_to_string
+from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
 from catalogue.helpers import cached_in_field
 from catalogue.models import Project
@@ -19,7 +20,7 @@ class Image(dvcs_models.Document):
     title = models.CharField(_('title'), max_length=255, blank=True)
     slug = models.SlugField(_('slug'), unique=True)
     public = models.BooleanField(_('public'), default=True, db_index=True)
-    project = models.ForeignKey(Project, null=True, blank=True)
+    project = models.ForeignKey(Project, models.SET_NULL, null=True, blank=True)
 
     # cache
     _new_publishable = models.NullBooleanField(editable=False)
@@ -39,9 +40,8 @@ class Image(dvcs_models.Document):
     def __str__(self):
         return self.title
 
-    @models.permalink
     def get_absolute_url(self):
-        return ("catalogue_image", [self.slug])
+        return reverse("catalogue_image", args=[self.slug])
 
     def correct_about(self):
         return ["http://%s%s" % (
index 7a8e2f9..eeec055 100755 (executable)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -14,9 +12,9 @@ class BookPublishRecord(models.Model):
         A record left after publishing a Book.
     """
 
-    book = models.ForeignKey('Book', verbose_name=_('book'), related_name='publish_log')
+    book = models.ForeignKey('Book', models.CASCADE, verbose_name=_('book'), related_name='publish_log')
     timestamp = models.DateTimeField(_('time'), auto_now_add=True)
-    user = models.ForeignKey(User, verbose_name=_('user'))
+    user = models.ForeignKey(User, models.CASCADE, verbose_name=_('user'))
 
     class Meta:
         app_label = 'catalogue'
@@ -30,8 +28,8 @@ class ChunkPublishRecord(models.Model):
         BookPublishRecord details for each Chunk.
     """
 
-    book_record = models.ForeignKey(BookPublishRecord, verbose_name=_('book publish record'))
-    change = models.ForeignKey(Chunk.change_model, related_name='publish_log', verbose_name=_('change'))
+    book_record = models.ForeignKey(BookPublishRecord, models.CASCADE, verbose_name=_('book publish record'))
+    change = models.ForeignKey(Chunk.change_model, models.CASCADE, related_name='publish_log', verbose_name=_('change'))
 
     class Meta:
         app_label = 'catalogue'
@@ -42,10 +40,10 @@ class ChunkPublishRecord(models.Model):
 class ImagePublishRecord(models.Model):
     """A record left after publishing an Image."""
 
-    image = models.ForeignKey(Image, verbose_name=_('image'), related_name='publish_log')
+    image = models.ForeignKey(Image, models.CASCADE, verbose_name=_('image'), related_name='publish_log')
     timestamp = models.DateTimeField(_('time'), auto_now_add=True)
-    user = models.ForeignKey(User, verbose_name=_('user'))
-    change = models.ForeignKey(Image.change_model, related_name='publish_log', verbose_name=_('change'))
+    user = models.ForeignKey(User, models.CASCADE, verbose_name=_('user'))
+    change = models.ForeignKey(Image.change_model, models.CASCADE, related_name='publish_log', verbose_name=_('change'))
 
     class Meta:
         app_label = 'catalogue'
index 07c5cf9..9c876de 100644 (file)
@@ -1,6 +1,4 @@
-from __future__ import absolute_import
-
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django import template
 from django.utils.translation import ugettext as _
 
index 0c1628c..2dcf2ba 100755 (executable)
@@ -1,8 +1,6 @@
-from __future__ import absolute_import
-
 from datetime import timedelta
 from django.db.models import Q
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django import template
 from django.utils.translation import ugettext as _
 
index ab1f821..377bdbb 100644 (file)
@@ -8,7 +8,7 @@ from django.conf import settings
 from django.contrib import auth
 from django.contrib.auth.models import User
 from django.contrib.auth.decorators import login_required, permission_required
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.db.models import Count, Q
 from django.db import transaction
 from django import http
diff --git a/src/cover/migrations/0002_auto_20191002_1224.py b/src/cover/migrations/0002_auto_20191002_1224.py
new file mode 100644 (file)
index 0000000..3f5864e
--- /dev/null
@@ -0,0 +1,19 @@
+# Generated by Django 2.0.13 on 2019-10-02 12:24
+
+import cover.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('cover', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='image',
+            name='file',
+            field=models.ImageField(storage=cover.models.OverwriteStorage(), upload_to='cover/image', verbose_name='file'),
+        ),
+    ]
index ea69f65..c60efe1 100644 (file)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -8,6 +6,7 @@ from django.core.files.storage import FileSystemStorage
 from django.db import models
 from django.db.models.signals import post_save
 from django.dispatch import receiver
+from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
 from django.contrib.sites.models import Site
 from cover.utils import URLOpener
@@ -37,9 +36,8 @@ class Image(models.Model):
     def __str__(self):
         return u"%s - %s" % (self.author, self.title)
 
-    @models.permalink
     def get_absolute_url(self):
-        return 'cover_image', [self.id]
+        return reverse('cover_image', args=[self.id])
 
     def get_full_url(self):
         return "http://%s%s" % (Site.objects.get_current().domain, self.get_absolute_url())
index d6b0cc6..adaf795 100644 (file)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -10,7 +8,8 @@ from django.contrib.auth.models import User
 from django.core.files.base import ContentFile
 from django.db import models, transaction
 from django.db.models.base import ModelBase
-from django.utils.translation import string_concat, ugettext_lazy as _
+from django.utils.text import format_lazy
+from django.utils.translation import ugettext_lazy as _
 import merge3
 
 from django.conf import settings
@@ -71,7 +70,7 @@ class Change(models.Model):
         
         Data file contains a gzipped text of the document.
     """
-    author = models.ForeignKey(User, null=True, blank=True, verbose_name=_('author'))
+    author = models.ForeignKey(User, models.SET_NULL, null=True, blank=True, verbose_name=_('author'))
     author_name = models.CharField(
         _('author name'), max_length=128, null=True, blank=True, help_text=_("Used if author is not set."))
     author_email = models.CharField(
@@ -79,10 +78,10 @@ class Change(models.Model):
     revision = models.IntegerField(_('revision'), db_index=True)
 
     parent = models.ForeignKey(
-        'self', null=True, blank=True, default=None, verbose_name=_('parent'), related_name="children")
+        'self', models.SET_NULL, null=True, blank=True, default=None, verbose_name=_('parent'), related_name="children")
 
     merge_parent = models.ForeignKey(
-        'self', null=True, blank=True, default=None, verbose_name=_('merge parent'), related_name="merge_children")
+        'self', models.SET_NULL, null=True, blank=True, default=None, verbose_name=_('merge parent'), related_name="merge_children")
 
     description = models.TextField(_('description'), blank=True, default='')
     created_at = models.DateTimeField(editable=False, db_index=True, default=datetime.now)
@@ -165,10 +164,10 @@ def create_tag_model(model):
 
     class Meta(Tag.Meta):
         app_label = model._meta.app_label
-        verbose_name = string_concat(
-            _("tag"), " ", _("for:"), " ", model._meta.verbose_name)
-        verbose_name_plural = string_concat(
-            _("tags"), " ", _("for:"), " ", model._meta.verbose_name)
+        verbose_name = format_lazy(
+            '{} {} {}', _('tag'), _('for:'), model._meta.verbose_name)
+        verbose_name_plural = format_lazy(
+            '{} {} {}', _("tags"), _("for:"), model._meta.verbose_name)
 
     attrs = {
         '__module__': model.__module__,
@@ -183,14 +182,14 @@ def create_change_model(model):
 
     class Meta(Change.Meta):
         app_label = model._meta.app_label
-        verbose_name = string_concat(
-            _("change"), " ", _("for:"), " ", model._meta.verbose_name)
-        verbose_name_plural = string_concat(
-            _("changes"), " ", _("for:"), " ", model._meta.verbose_name)
+        verbose_name = format_lazy(
+            '{} {} {}', _("change"), _("for:"), model._meta.verbose_name)
+        verbose_name_plural = format_lazy(
+            '{} {} {}', _("changes"), _("for:"), model._meta.verbose_name)
 
     attrs = {
         '__module__': model.__module__,
-        'tree': models.ForeignKey(model, related_name='change_set', verbose_name=_('document')),
+        'tree': models.ForeignKey(model, models.CASCADE, related_name='change_set', verbose_name=_('document')),
         'tags': models.ManyToManyField(model.tag_model, verbose_name=_('tags'), related_name='change_set'),
         'data': models.FileField(_('data'), upload_to=data_upload_to, storage=repo),
         'Meta': Meta,
@@ -206,19 +205,19 @@ class DocumentMeta(ModelBase):
         if not model._meta.abstract:
             # create a real Tag object and `stage' fk
             model.tag_model = create_tag_model(model)
-            models.ForeignKey(model.tag_model, verbose_name=_('stage'),
+            models.ForeignKey(model.tag_model, models.CASCADE, verbose_name=_('stage'),
                 null=True, blank=True).contribute_to_class(model, 'stage')
 
             # create real Change model and `head' fk
             model.change_model = create_change_model(model)
 
             models.ForeignKey(
-                model.change_model, null=True, blank=True, default=None,
+                model.change_model, models.SET_NULL, null=True, blank=True, default=None,
                 verbose_name=_('head'), help_text=_("This document's current head."),
                 editable=False).contribute_to_class(model, 'head')
 
             models.ForeignKey(
-                User, null=True, blank=True, editable=False,
+                User, models.SET_NULL, null=True, blank=True, editable=False,
                 verbose_name=_('creator'), related_name="created_%s" % name.lower()
                 ).contribute_to_class(model, 'creator')
 
@@ -231,7 +230,7 @@ class Document(models.Model, metaclass=DocumentMeta):
     # default repository path
     REPO_PATH = os.path.join(settings.MEDIA_ROOT, 'dvcs')
 
-    user = models.ForeignKey(User, null=True, blank=True, verbose_name=_('user'), help_text=_('Work assignment.'))
+    user = models.ForeignKey(User, models.SET_NULL, null=True, blank=True, verbose_name=_('user'), help_text=_('Work assignment.'))
 
     class Meta:
         abstract = True
@@ -280,7 +279,7 @@ class Document(models.Model, metaclass=DocumentMeta):
             author=author, author_name=author_name, author_email=author_email,
             description=kwargs.get('description', ''), publishable=publishable, parent=parent)
 
-        change.tags = tags
+        change.tags.set(tags)
         change.data.save('', ContentFile(text.encode('utf-8')))
         change.save()
 
index 571a9ed..71bc998 100644 (file)
@@ -1,9 +1,8 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import
 import os.path
+import sentry_sdk
+from sentry_sdk.integrations.django import DjangoIntegration
 from .defaults import *
 from ..localsettings import *
-import os
 
 PROJECT_ROOT = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
 
@@ -66,7 +65,6 @@ INSTALLED_APPS = (
     'django.contrib.sites',
     'django.contrib.admin',
     'django.contrib.admindocs',
-    'raven.contrib.django.raven_compat',
 
     'sorl.thumbnail',
     'fnp_django_pagination',
@@ -237,3 +235,15 @@ PIPELINE = {
         }
     }
 }
+
+
+try:
+    SENTRY_DSN
+except NameError:
+    pass
+else:
+    sentry_sdk.init(
+        dsn=SENTRY_DSN,
+        integrations=[DjangoIntegration()]
+    )
+
index 54ed920..2ecb7ed 100644 (file)
@@ -9,8 +9,6 @@ from django.views.generic import RedirectView
 import django_cas_ng.views
 
 
-admin.autodiscover()
-
 urlpatterns = [
     # Auth
     url(r'^accounts/login/$', django_cas_ng.views.LoginView.as_view(), name='cas_ng_login'),
@@ -20,7 +18,7 @@ urlpatterns = [
 
     # Admin panel
     url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
-    url(r'^admin/', include(admin.site.urls)),
+    url(r'^admin/', admin.site.urls),
 
     url(r'^$', RedirectView.as_view(url= '/documents/', permanent=False)),
     url(r'^documents/', include('catalogue.urls')),
index e3a2404..e396fac 100644 (file)
@@ -62,7 +62,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='button',
             name='scriptlet',
-            field=models.ForeignKey(blank=True, to='toolbar.Scriptlet', null=True),
+            field=models.ForeignKey(blank=True, to='toolbar.Scriptlet', null=True, on_delete=models.CASCADE),
             preserve_default=True,
         ),
     ]
diff --git a/src/toolbar/migrations/0002_auto_20191002_1224.py b/src/toolbar/migrations/0002_auto_20191002_1224.py
new file mode 100644 (file)
index 0000000..b2f134b
--- /dev/null
@@ -0,0 +1,29 @@
+# Generated by Django 2.0.13 on 2019-10-02 12:24
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('toolbar', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='button',
+            name='link',
+            field=models.CharField(blank=True, default='', max_length=256),
+        ),
+        migrations.AlterField(
+            model_name='button',
+            name='params',
+            field=models.TextField(default='[]'),
+        ),
+        migrations.AlterField(
+            model_name='button',
+            name='scriptlet',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='toolbar.Scriptlet'),
+        ),
+    ]
index fbaa396..02567fa 100644 (file)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -34,7 +32,7 @@ class Button(models.Model):
 
     # behaviour
     params = models.TextField(default='[]')  # TODO: should be a JSON field
-    scriptlet = models.ForeignKey('Scriptlet', null=True, blank=True)
+    scriptlet = models.ForeignKey('Scriptlet', models.SET_NULL, null=True, blank=True)
     link = models.CharField(max_length=256, blank=True, default='')
 
     # ui related stuff
index 3ef3ed1..6f6defc 100644 (file)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -67,7 +65,7 @@ class DocumentTextSaveForm(forms.Form):
     def __init__(self, *args, **kwargs):
         user = kwargs.pop('user')
         r = super(DocumentTextSaveForm, self).__init__(*args, **kwargs)
-        if user and user.is_authenticated():
+        if user and user.is_authenticated:
             self.fields['author_name'].required = False
             self.fields['author_email'].required = False
         return r
index d62c545..6ad6bb6 100644 (file)
@@ -44,7 +44,7 @@ class JSONServerError(JSONResponse):
 def ajax_login_required(view):
     @wraps(view)
     def authenticated_view(request, *args, **kwargs):
-        if not request.user.is_authenticated():
+        if not request.user.is_authenticated:
             return http.HttpResponse("Login required.", status=401, content_type="text/plain")
         return view(request, *args, **kwargs)
     return authenticated_view
index 332f28f..6b3586c 100644 (file)
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 from datetime import datetime
 import os
 import logging
@@ -6,7 +5,7 @@ from time import mktime
 from urllib.parse import quote
 
 from django.conf import settings
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django import http
 from django.http import Http404, HttpResponseForbidden
 from django.middleware.gzip import GZipMiddleware
@@ -115,7 +114,7 @@ def text(request, chunk_id):
     if request.method == 'POST':
         form = forms.DocumentTextSaveForm(request.POST, user=request.user, prefix="textsave")
         if form.is_valid():
-            if request.user.is_authenticated():
+            if request.user.is_authenticated:
                 author = request.user
             else:
                 author = None
@@ -180,7 +179,7 @@ def revert(request, chunk_id):
         comment = form.cleaned_data['comment']
         comment += "\n#revert to %s" % revision
 
-        if request.user.is_authenticated():
+        if request.user.is_authenticated:
             author = request.user
         else:
             author = None
@@ -222,7 +221,7 @@ def gallery(request, directory):
 
         books = Book.objects.filter(gallery=directory)
 
-        if not all(book.public for book in books) and not request.user.is_authenticated():
+        if not all(book.public for book in books) and not request.user.is_authenticated:
             return HttpResponseForbidden("Not authorized.")
 
         return JSONResponse(images)
index e5bbf41..adbad5c 100644 (file)
@@ -3,7 +3,7 @@ import functools
 import logging
 logger = logging.getLogger("fnp.wiki_img")
 
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
                 ajax_require_permission)
 
@@ -63,7 +63,7 @@ def text(request, image_id):
     if request.method == 'POST':
         form = ImageSaveForm(request.POST, user=request.user, prefix="textsave")
         if form.is_valid():
-            if request.user.is_authenticated():
+            if request.user.is_authenticated:
                 author = request.user
             else:
                 author = None
@@ -148,7 +148,7 @@ def revert(request, object_id):
         comment = form.cleaned_data['comment']
         comment += "\n#revert to %s" % revision
 
-        if request.user.is_authenticated():
+        if request.user.is_authenticated:
             author = request.user
         else:
             author = None