diff --git a/.gitignore b/.gitignore index b09f5a1..7442e75 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,8 @@ db.sqlite3 .disable_debug_toolbar # really -share/ \ No newline at end of file +share/ + +# other droppings +pip-selfcheck.json +selenium/ diff --git a/core/middleware.py b/core/middleware.py index 35f7e3d..e99dba1 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -1,6 +1,8 @@ import settings -class FinetoothEnvironmentMiddleware: +from django.utils import deprecation + +class FinetoothEnvironmentMiddleware(deprecation.MiddlewareMixin): def process_request(self, request): request.possible_environments = settings.Environment request.environment = settings.ENVIRONMENT diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py index 1c1129b..a41f333 100644 --- a/core/migrations/0001_initial.py +++ b/core/migrations/0001_initial.py @@ -1,112 +1,126 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 2.0.1 on 2018-01-22 21:01 -from django.db import models, migrations +import core.votable from django.conf import settings -import django.utils.timezone +import django.contrib.auth.models +import django.contrib.auth.validators import django.core.validators -import core.votable +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone class Migration(migrations.Migration): + initial = True + dependencies = [ - ('auth', '0001_initial'), + ('auth', '0009_alter_user_last_name_max_length'), ] operations = [ migrations.CreateModel( name='FinetoothUser', fields=[ - ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(verbose_name='last login', default=django.utils.timezone.now)), - ('is_superuser', models.BooleanField(verbose_name='superuser status', default=False, help_text='Designates that this user has all permissions without explicitly assigning them.')), - ('username', models.CharField(unique=True, max_length=30, verbose_name='username', validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username.', 'invalid')], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.')), - ('first_name', models.CharField(max_length=30, blank=True, verbose_name='first name')), - ('last_name', models.CharField(max_length=30, blank=True, verbose_name='last name')), - ('email', models.EmailField(max_length=75, blank=True, verbose_name='email address')), - ('is_staff', models.BooleanField(verbose_name='staff status', default=False, help_text='Designates whether the user can log into this admin site.')), - ('is_active', models.BooleanField(verbose_name='active', default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.')), - ('date_joined', models.DateTimeField(verbose_name='date joined', default=django.utils.timezone.now)), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), ('location', models.CharField(max_length=100, null=True)), ('url', models.URLField(null=True)), - ('groups', models.ManyToManyField(verbose_name='groups', to='auth.Group', related_name='user_set', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of his/her group.', related_query_name='user')), - ('user_permissions', models.ManyToManyField(verbose_name='user permissions', to='auth.Permission', related_name='user_set', blank=True, help_text='Specific permissions for this user.', related_query_name='user')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ - 'abstract': False, 'verbose_name': 'user', + 'abstract': False, 'verbose_name_plural': 'users', }, - bases=(models.Model,), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], ), migrations.CreateModel( name='Comment', fields=[ - ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('content', models.TextField()), - ('commenter', models.ForeignKey(to=settings.AUTH_USER_MODEL)), - ('parent', models.ForeignKey(to='core.Comment', null=True)), + ('published_at', models.DateTimeField(auto_now_add=True)), + ('commenter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Comment')), ], options={ + 'ordering': ('published_at',), }, bases=(models.Model, core.votable.VotableMixin), ), migrations.CreateModel( name='Post', fields=[ - ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=200)), - ('content', models.TextField()), - ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('content', models.TextField(validators=[django.core.validators.MinLengthValidator(5, 'Posts must contain at least five characters.')])), + ('published_at', models.DateTimeField()), + ('slug', models.SlugField(unique=True)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ + 'ordering': ('-published_at',), }, bases=(models.Model, core.votable.VotableMixin), ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.CharField(max_length=64, unique=True)), + ('posts', models.ManyToManyField(to='core.Post')), + ], + ), migrations.CreateModel( name='Vote', fields=[ - ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('value', models.IntegerField()), ('start_index', models.PositiveIntegerField()), ('end_index', models.PositiveIntegerField()), ], - options={ - }, - bases=(models.Model,), ), migrations.CreateModel( - name='PostVote', + name='CommentVote', fields=[ - ('vote_ptr', models.OneToOneField(auto_created=True, serialize=False, to='core.Vote', parent_link=True, primary_key=True)), - ('post', models.ForeignKey(to='core.Post')), + ('vote_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Vote')), ], - options={ - }, bases=('core.vote',), ), migrations.CreateModel( - name='CommentVote', + name='PostVote', fields=[ - ('vote_ptr', models.OneToOneField(auto_created=True, serialize=False, to='core.Vote', parent_link=True, primary_key=True)), - ('comment', models.ForeignKey(to='core.Comment')), + ('vote_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Vote')), + ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Post')), ], - options={ - }, bases=('core.vote',), ), migrations.AddField( model_name='vote', name='voter', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), - preserve_default=True, + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='comment', name='post', - field=models.ForeignKey(to='core.Post'), - preserve_default=True, + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Post'), + ), + migrations.AddField( + model_name='commentvote', + name='comment', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Comment'), ), ] diff --git a/core/migrations/0002_auto_20140903_0357.py b/core/migrations/0002_auto_20140903_0357.py deleted file mode 100644 index 46bb665..0000000 --- a/core/migrations/0002_auto_20140903_0357.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import datetime - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='comment', - name='published_at', - field=models.DateTimeField(default=datetime.datetime(2014, 9, 3, 3, 57, 44, 517051), auto_now_add=True), - preserve_default=False, - ), - migrations.AddField( - model_name='post', - name='published_at', - field=models.DateTimeField(default=datetime.datetime(2014, 9, 3, 3, 57, 54, 173017)), - preserve_default=False, - ), - ] diff --git a/core/migrations/0003_tag.py b/core/migrations/0003_tag.py deleted file mode 100644 index faa3de0..0000000 --- a/core/migrations/0003_tag.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0002_auto_20140903_0357'), - ] - - operations = [ - migrations.CreateModel( - name='Tag', - fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), - ('label', models.CharField(max_length=64, unique=True)), - ('posts', models.ManyToManyField(to='core.Post')), - ], - options={ - }, - bases=(models.Model,), - ), - ] diff --git a/core/migrations/0004_post_slug.py b/core/migrations/0004_post_slug.py deleted file mode 100644 index 7717e0e..0000000 --- a/core/migrations/0004_post_slug.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0003_tag'), - ] - - operations = [ - migrations.AddField( - model_name='post', - name='slug', - field=models.SlugField(null=True), - preserve_default=True, - ), - ] diff --git a/core/migrations/0005_slugifying_data_migration.py b/core/migrations/0005_slugifying_data_migration.py deleted file mode 100644 index f7e4f2b..0000000 --- a/core/migrations/0005_slugifying_data_migration.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.utils.text import slugify -from django.db import models, migrations - - -def slugify_migrate_forward(apps, schema_editor): - Post = apps.get_model('core', "Post") - for post in Post.objects.all(): - post.slug = slugify(post.title) - post.save() - -def unslugify_migrate_backward(apps, schema_editor): - Post = apps.get_model('core', "Post") - for post in Post.objects.all(): - post.slug = None - post.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0004_post_slug'), - ] - - operations = [ - migrations.RunPython(slugify_migrate_forward, unslugify_migrate_backward) - ] diff --git a/core/migrations/0006_auto_20141012_0251.py b/core/migrations/0006_auto_20141012_0251.py deleted file mode 100644 index aea5023..0000000 --- a/core/migrations/0006_auto_20141012_0251.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0005_slugifying_data_migration'), - ] - - operations = [ - migrations.AlterField( - model_name='post', - name='slug', - field=models.SlugField(unique=True), - ), - ] diff --git a/core/migrations/0007_auto_20150308_2143.py b/core/migrations/0007_auto_20150308_2143.py deleted file mode 100644 index b61a1e3..0000000 --- a/core/migrations/0007_auto_20150308_2143.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django.contrib.auth.models -import django.core.validators - - -class Migration(migrations.Migration): - - dependencies = [ - ('auth', '0006_require_contenttypes_0002'), - ('core', '0006_auto_20141012_0251'), - ] - - operations = [ - migrations.AlterModelManagers( - name='finetoothuser', - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), - migrations.AlterField( - model_name='finetoothuser', - name='email', - field=models.EmailField(blank=True, verbose_name='email address', max_length=254), - ), - migrations.RemoveField( - model_name='finetoothuser', - name='groups', - ), - migrations.AddField( - model_name='finetoothuser', - name='groups', - field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', to='auth.Group', verbose_name='groups', related_query_name='user'), - ), - migrations.AlterField( - model_name='finetoothuser', - name='last_login', - field=models.DateTimeField(null=True, verbose_name='last login', blank=True), - ), - migrations.AlterField( - model_name='finetoothuser', - name='username', - field=models.CharField(unique=True, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], error_messages={'unique': 'A user with that username already exists.'}, verbose_name='username', max_length=30), - ), - ] diff --git a/core/migrations/0008_auto_20150311_0549.py b/core/migrations/0008_auto_20150311_0549.py deleted file mode 100644 index c2f710c..0000000 --- a/core/migrations/0008_auto_20150311_0549.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django.core.validators - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0007_auto_20150308_2143'), - ] - - operations = [ - migrations.AlterField( - model_name='post', - name='content', - field=models.TextField(validators=[django.core.validators.MinLengthValidator(5, 'Posts must contain at least five characters.')]), - ), - ] diff --git a/core/migrations/0009_auto_20151020_0455.py b/core/migrations/0009_auto_20151020_0455.py deleted file mode 100644 index ab58a36..0000000 --- a/core/migrations/0009_auto_20151020_0455.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0008_auto_20150311_0549'), - ] - - operations = [ - migrations.AlterModelOptions( - name='post', - options={'ordering': ('-published_at',)}, - ), - ] diff --git a/core/migrations/0010_auto_20151020_0507.py b/core/migrations/0010_auto_20151020_0507.py deleted file mode 100644 index b9a914a..0000000 --- a/core/migrations/0010_auto_20151020_0507.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9b1 on 2015-10-20 05:07 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0009_auto_20151020_0455'), - ] - - operations = [ - migrations.AlterField( - model_name='finetoothuser', - name='username', - field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username'), - ), - ] diff --git a/core/migrations/0011_auto_20160107_0640.py b/core/migrations/0011_auto_20160107_0640.py deleted file mode 100644 index 5a70a47..0000000 --- a/core/migrations/0011_auto_20160107_0640.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.1 on 2016-01-07 06:40 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0010_auto_20151020_0507'), - ] - - operations = [ - migrations.AlterModelOptions( - name='comment', - options={'ordering': ('published_at',)}, - ), - ] diff --git a/core/models.py b/core/models.py index 15c6d21..f690980 100644 --- a/core/models.py +++ b/core/models.py @@ -1,5 +1,5 @@ from django.db import models -from django.core.urlresolvers import reverse +from django.urls import reverse from django.core.validators import MinLengthValidator from django.contrib.auth.models import AbstractUser diff --git a/core/tests/view_tests.py b/core/tests/view_tests.py index d628a39..fb8bd01 100644 --- a/core/tests/view_tests.py +++ b/core/tests/view_tests.py @@ -1,7 +1,7 @@ from datetime import datetime, timedelta from django.test import TestCase -from django.core.urlresolvers import reverse +from django.urls import reverse from django.utils.text import slugify from core.models import FinetoothUser, Post diff --git a/core/views/service.py b/core/views/service.py index c6d191f..371fc5e 100644 --- a/core/views/service.py +++ b/core/views/service.py @@ -39,7 +39,7 @@ def tag(request, post_pk): @require_POST def ballot_box(request, kind, pk): - if not request.user.is_authenticated(): + if not request.user.is_authenticated: return HttpResponse("You must be logged in to vote!", status=401) kinds = {"post": Post, "comment": Comment} value = request.POST.get('value') diff --git a/core/views/views.py b/core/views/views.py index 1f1b156..ef52fa9 100644 --- a/core/views/views.py +++ b/core/views/views.py @@ -11,7 +11,7 @@ from django.contrib.auth.decorators import login_required from django.contrib import messages from django.core.exceptions import ValidationError -from django.core.urlresolvers import reverse +from django.urls import reverse from django.template.response import TemplateResponse from django.utils.text import slugify from django.utils.translation import ugettext as _ diff --git a/dev_requirements.txt b/dev_requirements.txt index 710c297..5eae008 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,8 +1,8 @@ -bleach==1.4.1 -Django==1.10.2 -django-debug-toolbar==1.3 -django-extensions==1.6.1 -ipython==3.1.0 -Markdown==2.6.1 -jasmine==2.0.1 -factory_boy==2.5.1 +bleach==2.1.2 +Django==2.0.1 +django-debug-toolbar==1.9.1 +django-extensions==1.9.9 +ipython==6.2.1 +Markdown==2.6.11 +jasmine==2.9.0 +factory_boy==2.9.2 diff --git a/requirements.txt b/requirements.txt index 5666907..ee56a33 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +# TODO: update these (see dev_requirements for newer development versions) bleach==1.4 Django==1.10.2 Markdown==2.4.1 diff --git a/settings.py b/settings.py index 3e296c4..4c6b952 100644 --- a/settings.py +++ b/settings.py @@ -43,15 +43,15 @@ not os.path.exists(".disable_debug_toolbar")): INSTALLED_APPS += ('debug_toolbar',) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = ( 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'debug_toolbar.middleware.DebugToolbarMiddleware', 'core.middleware.FinetoothEnvironmentMiddleware' )