From 252697b842c0b91d6bdb0c6e6211539a7e1bd2c5 2020-11-22 13:58:14 From: Joel Addison Date: 2020-11-22 13:58:14 Subject: [PATCH] Update to Django 2.2 Upgrade site and modules to Django 2.2. Remove and replace obsolete functionality with current equivalents. Update requirements to latest versions where possible. Remove unused dependencies. --- diff --git a/constraints.txt b/constraints.txt index 73dc240ce80b5d9ee9c77e04c0ebf93ac3dab6e0..5820023e0c4679892c8b6acf1e0da1a05c58c1c7 100644 --- a/constraints.txt +++ b/constraints.txt @@ -1,2 +1,2 @@ -django<1.12,>=1.11 -pysaml2==4.8.0 +django<3.0,>=2.2 +pysaml2>=5.3.0 diff --git a/docker/Dockerfile b/docker/Dockerfile index 54d1c2109a3390aa7690b1f71a19dd9ea2cc1192..2353264eb79cb260163242130789447664d6a2fb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.6-stretch as symposion_base +FROM python:3.8-buster as symposion_base RUN set -ex \ && apt-get update @@ -25,6 +25,7 @@ RUN set -ex \ COPY constraints.txt requirements.txt /reqs/ RUN set -ex \ + && pip install -U pip \ && pip install --no-cache-dir -r /reqs/requirements.txt -c /reqs/constraints.txt \ && apt-get purge -y --auto-remove $buildDeps \ && rm -rf /usr/src/python ~/.cache diff --git a/docker/laptop-mode-env b/docker/laptop-mode-env index 8d391eff2770fb3a722a49838e3f712946ba2f82..b790c16bbe599fcc1267fc28675b023d6a5a4642 100644 --- a/docker/laptop-mode-env +++ b/docker/laptop-mode-env @@ -5,4 +5,4 @@ GCS_BUCKET=5CEA51A5-A613-4AEF-A9FB-D0A57D77C13B GOOGLE_APPLICATION_CREDENTIALS=/dev/null DATABASE_URL=sqlite:////tmp/symposion.sqlite SYMPOSION_DEV_MODE=LAPTOP -SYMPOSION_APP_DEBUG=1 \ No newline at end of file +SYMPOSION_APP_DEBUG=1 diff --git a/pinaxcon/devmode_settings.py b/pinaxcon/devmode_settings.py index 4c569d7ecb9d7171ba508cc6d800b00613a6f5e6..e417897311e95279cb3d89a76ea04146abbcda54 100644 --- a/pinaxcon/devmode_settings.py +++ b/pinaxcon/devmode_settings.py @@ -8,3 +8,5 @@ LOGIN_URL='/accounts/login' ROOT_URLCONF = "pinaxcon.devmode_urls" DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' + +INTERNAL_IPS = ['*'] diff --git a/pinaxcon/devmode_urls.py b/pinaxcon/devmode_urls.py index 0525dbff0f71e2d7008b2ba93a4509c0de78e6c8..c86a92dd555ad92b7d9105f137e4087c85aef525 100644 --- a/pinaxcon/devmode_urls.py +++ b/pinaxcon/devmode_urls.py @@ -1,11 +1,11 @@ -from django.conf.urls import include, url -from django.contrib.auth.views import login, logout - +from django.contrib.auth.views import LoginView, LogoutView +from django.urls import include, path + from pinaxcon import urls urlpatterns = [ - url(r'^accounts/logout', logout, {'template_name': 'admin/logout.html'}), - url(r'^accounts/login', login, {'template_name': 'admin/login.html'}), + path('accounts/logout', LogoutView.as_view(template_name='admin/logout.html')), + path('accounts/login', LoginView.as_view(template_name='admin/login.html')), ] urlpatterns += urls.urlpatterns diff --git a/pinaxcon/monkey_patch.py b/pinaxcon/monkey_patch.py index c010251231aef994e360a905330bfda54a42f70b..207fcd129e710f1950c74208f96f1e04d8efe25e 100644 --- a/pinaxcon/monkey_patch.py +++ b/pinaxcon/monkey_patch.py @@ -4,8 +4,13 @@ from functools import wraps class MonkeyPatchMiddleware(object): ''' Ensures that our monkey patching only gets called after it is safe to do so.''' - def process_request(self, request): + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): do_monkey_patch() + response = self.get_response(request) + return response def do_monkey_patch(): @@ -53,7 +58,7 @@ def patch_stripe_payment_form(): # noqa: C901 if not isinstance(value, HttpRequest): continue user = value.user - if not user.is_authenticated(): + if not user.is_authenticated: break try: attendee_profile = models.AttendeeProfile.objects.get( diff --git a/pinaxcon/raffle/models.py b/pinaxcon/raffle/models.py index 899b59737a4e081d709934360455211eca4aebc1..975f3b2bed385fb5761058c5eb56eb202912b7b6 100644 --- a/pinaxcon/raffle/models.py +++ b/pinaxcon/raffle/models.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.db import models from pinaxcon.raffle.mixins import PrizeMixin, RaffleMixin @@ -26,11 +27,18 @@ class Prize(PrizeMixin, models.Model): unlocked. """ description = models.CharField(max_length=255) - raffle = models.ForeignKey('pinaxcon_raffle.Raffle', related_name='prizes') + raffle = models.ForeignKey( + 'pinaxcon_raffle.Raffle', + related_name='prizes', + on_delete=models.CASCADE, + ) order = models.PositiveIntegerField() winning_ticket = models.OneToOneField( - 'pinaxcon_raffle.DrawnTicket', null=True, - blank=True, related_name='+', on_delete=models.PROTECT + 'pinaxcon_raffle.DrawnTicket', + null=True, + blank=True, + related_name='+', + on_delete=models.PROTECT, ) class Meta: @@ -45,9 +53,16 @@ class PrizeAudit(models.Model): Stores an audit event for changes to a particular :model:`pinaxcon_raffle.Prize`. """ reason = models.CharField(max_length=255) - prize = models.ForeignKey('pinaxcon_raffle.Prize', related_name='audit_events') + prize = models.ForeignKey( + 'pinaxcon_raffle.Prize', + related_name='audit_events', + on_delete=models.CASCADE, + ) - user = models.ForeignKey('auth.User') + user = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + ) timestamp = models.DateTimeField(auto_now_add=True) class Meta: @@ -62,8 +77,15 @@ class Draw(models.Model): Stores a draw for a given :model:`pinaxcon_raffle.Raffle`, along with audit fields for the creating :model:`auth.User` and the creation timestamp. """ - raffle = models.ForeignKey('pinaxcon_raffle.Raffle', related_name='draws') - drawn_by = models.ForeignKey('auth.User') + raffle = models.ForeignKey( + 'pinaxcon_raffle.Raffle', + related_name='draws', + on_delete=models.CASCADE, + ) + drawn_by = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + ) drawn_time = models.DateTimeField(auto_now_add=True) def __str__(self): @@ -78,9 +100,18 @@ class DrawnTicket(models.Model): """ ticket = models.CharField(max_length=255) - draw = models.ForeignKey('pinaxcon_raffle.Draw') - prize = models.ForeignKey('pinaxcon_raffle.Prize') - lineitem = models.ForeignKey('registrasion.LineItem') + draw = models.ForeignKey( + 'pinaxcon_raffle.Draw', + on_delete=models.CASCADE, + ) + prize = models.ForeignKey( + 'pinaxcon_raffle.Prize', + on_delete=models.CASCADE, + ) + lineitem = models.ForeignKey( + 'registrasion.LineItem', + on_delete=models.CASCADE, + ) def __str__(self): - return f"{self.ticket}: {self.draw.raffle}" \ No newline at end of file + return f"{self.ticket}: {self.draw.raffle}" diff --git a/pinaxcon/registrasion/management/commands/dummy_presentations.py b/pinaxcon/registrasion/management/commands/dummy_presentations.py index 93edabe600c88ee178222fb26bb08627dbc51d71..b19693e797801861d9ccf5795bc7dfb36fded473 100644 --- a/pinaxcon/registrasion/management/commands/dummy_presentations.py +++ b/pinaxcon/registrasion/management/commands/dummy_presentations.py @@ -1,4 +1,4 @@ -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from django.core.management.base import BaseCommand from symposion.conference.models import Section, current_conference @@ -8,6 +8,8 @@ from symposion.schedule.models import Presentation from symposion.proposals.models import ProposalKind from pinaxcon.proposals.models import TalkProposal +User = get_user_model() + class Command(BaseCommand): diff --git a/pinaxcon/settings.py b/pinaxcon/settings.py index e4dc7510b1d4c6036753304ccc5323d8e47b4e68..d4a6deb265ca1f339420e69ee9af810e7f7b15a2 100644 --- a/pinaxcon/settings.py +++ b/pinaxcon/settings.py @@ -8,6 +8,7 @@ import saml2 import saml2.saml from datetime import date, datetime, timedelta +import pytz from dataclasses import dataclass @@ -124,7 +125,7 @@ else: ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '*'] -TIME_ZONE = "Australia/Brisbane" +TIME_ZONE = "Australia/Melbourne" DATE_FORMAT = "j F Y" LANGUAGE_CODE = "en-au" @@ -176,12 +177,12 @@ TEMPLATES = [ }, ] -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ + "whitenoise.middleware.WhiteNoiseMiddleware", "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", "debug_toolbar.middleware.DebugToolbarMiddleware", "reversion.middleware.RevisionMiddleware", @@ -200,6 +201,7 @@ else: WSGI_APPLICATION = "pinaxcon.wsgi.application" INSTALLED_APPS = [ + "whitenoise.runserver_nostatic", "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -224,6 +226,7 @@ INSTALLED_APPS = [ "taggit", "reversion", "sitetree", + "django_jsonfield_backport", "pinax.eventlog", # symposion @@ -283,9 +286,12 @@ DEBUG_TOOLBAR_PANELS = [ DEBUG_TOOLBAR_CONFIG = { 'INTERCEPT_REDIRECTS': False, - 'SHOW_TOOLBAR_CALLBACK': lambda x: DEBUG, } +INTERNAL_IPS = [ + '127.0.0.1', +] + from debug_toolbar.panels.logging import collector LOGGING = { 'version': 1, @@ -502,9 +508,10 @@ class PenguinDinnerCat(Category): return t -LCA_START = datetime(2021, 1, 23) -LCA_END = datetime(2021, 1, 25) -EARLY_BIRD_DEADLINE = datetime(2020, 12, 1) +_TZINFO = pytz.timezone(TIME_ZONE) +LCA_START = datetime(2021, 1, 23, tzinfo=_TZINFO) +LCA_END = datetime(2021, 1, 25, tzinfo=_TZINFO) +EARLY_BIRD_DEADLINE = datetime(2020, 12, 1, tzinfo=_TZINFO) PENGUIN_DINNER_TICKET_DATE = date(2021, 1, 23) SPEAKER_DINNER_TICKET_DATE = date(2021, 1, 25) PDNS_TICKET_DATE = date(2021, 1, 24) diff --git a/pinaxcon/templates/403_csrf.html b/pinaxcon/templates/403_csrf.html index 5a5a89684ce9f262847c250f10384f29b1924eb7..e54b869563d299d45466b3f811c944e3bbc427d6 100644 --- a/pinaxcon/templates/403_csrf.html +++ b/pinaxcon/templates/403_csrf.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load i18n %} diff --git a/pinaxcon/templates/404.html b/pinaxcon/templates/404.html index f5f87b7bbdb0b20be15a24714aa11183297aaea1..9b26c7442a5b36edee58f399000e577233825f39 100644 --- a/pinaxcon/templates/404.html +++ b/pinaxcon/templates/404.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load i18n %} diff --git a/pinaxcon/templates/dashboard.html b/pinaxcon/templates/dashboard.html index e94b7d73a235648174258826fcb01c78b1593674..ae336c11cd9e40b0ad17694e444dba4c3fc870c6 100644 --- a/pinaxcon/templates/dashboard.html +++ b/pinaxcon/templates/dashboard.html @@ -1,12 +1,11 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load i18n %} {% load review_tags %} {% load teams_tags %} {% load registrasion_tags %} {% load lca2018_tags %} -{% load staticfiles %} {% block head_title %}Dashboard{% endblock %} diff --git a/pinaxcon/templates/raffle.html b/pinaxcon/templates/raffle.html index 34a7d2031f343682c015228d13b8b2f4836e2209..8934b3625be55cc5a57e57f8b5dd74459e5e51d5 100644 --- a/pinaxcon/templates/raffle.html +++ b/pinaxcon/templates/raffle.html @@ -1,7 +1,7 @@ {% extends "site_base.html" %} {% load registrasion_tags %} {% load lca2018_tags %} -{% load staticfiles %} +{% load static %} {% block head_title %}Raffle Tickets{% endblock %} {% block page_title %}Raffle Tickets{% endblock %} diff --git a/pinaxcon/templates/raffle_draw.html b/pinaxcon/templates/raffle_draw.html index f7540479c4d0c97317a2c51e6670da726cdadb0f..6fcc77fc94625916420717f80cc8fa0e0456b11e 100644 --- a/pinaxcon/templates/raffle_draw.html +++ b/pinaxcon/templates/raffle_draw.html @@ -1,7 +1,7 @@ {% extends "site_base.html" %} {% load registrasion_tags %} {% load lca2018_tags %} -{% load staticfiles %} +{% load static %} {% block head_title %}Raffle Winners{% endblock %} {% block page_title %}Raffle Winners{% endblock %} diff --git a/pinaxcon/templates/registrasion/base.html b/pinaxcon/templates/registrasion/base.html index a83e70e76a09bbc1aa606c7477a492fde2f46447..a8fb61d331db29708f01bd16532405d4491bff67 100644 --- a/pinaxcon/templates/registrasion/base.html +++ b/pinaxcon/templates/registrasion/base.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load lca2018_tags %} {% load i18n %} diff --git a/pinaxcon/templates/registrasion/invoice.html b/pinaxcon/templates/registrasion/invoice.html index 717d7f28a23a47bcf37b5cb1cb8e283175350f7f..09014a210779b1e6966d7d2fcb380d9020a82a6c 100644 --- a/pinaxcon/templates/registrasion/invoice.html +++ b/pinaxcon/templates/registrasion/invoice.html @@ -1,7 +1,7 @@ {% extends "registrasion/base.html" %} {% load registrasion_tags %} {% load lca2018_tags %} -{% load staticfiles %} +{% load static %} {% block head_title %}Tax Invoice/Statement #{{ invoice.id }}{% endblock %} {% block page_title %}{% conference_name %}{% endblock %} diff --git a/pinaxcon/templates/site_base.html b/pinaxcon/templates/site_base.html index c24a26067c5b363c62e8ca7b916d1e8614fb08eb..d39ab252bd437aba0c5b2802d9e6058b67d8ec27 100644 --- a/pinaxcon/templates/site_base.html +++ b/pinaxcon/templates/site_base.html @@ -1,4 +1,4 @@ -{% load staticfiles %} +{% load static %} {% load i18n %} {% load sitetree %} {% load sass_tags %} diff --git a/pinaxcon/templates/symposion/dashboard/_categories.html b/pinaxcon/templates/symposion/dashboard/_categories.html index 56fcc8207494b758e4633d59c80bbc7915eaa787..e90e639f4f069099db1e545c02a9291b38cd0a5d 100644 --- a/pinaxcon/templates/symposion/dashboard/_categories.html +++ b/pinaxcon/templates/symposion/dashboard/_categories.html @@ -5,7 +5,7 @@ {% load registrasion_tags %} {% load lca2018_tags %} {% load lca2019_tags %} -{% load staticfiles %} +{% load static %} {% load waffle_tags %} {% if user.is_staff %} diff --git a/pinaxcon/templates/symposion/proposals/base.html b/pinaxcon/templates/symposion/proposals/base.html index e994c4cc1b7ccbacc47dcc8da5b823e4769378c7..3d61509024f5a4b7593fa885be280336d4e73d61 100644 --- a/pinaxcon/templates/symposion/proposals/base.html +++ b/pinaxcon/templates/symposion/proposals/base.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% block body_outer %} diff --git a/pinaxcon/templates/symposion/reviews/base.html b/pinaxcon/templates/symposion/reviews/base.html index b3a4a7680439f98d141ce154c75d84c5a58d1731..62ef72774dcde184fb62c1744ac6edf04af6cf7e 100644 --- a/pinaxcon/templates/symposion/reviews/base.html +++ b/pinaxcon/templates/symposion/reviews/base.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load i18n %} diff --git a/pinaxcon/templates/symposion/reviews/review_list.html b/pinaxcon/templates/symposion/reviews/review_list.html index 10c0b590248902d57d313c054fb865a85297360d..f6983c4d17faa5f52d538b74d3304a0525cdfa8c 100644 --- a/pinaxcon/templates/symposion/reviews/review_list.html +++ b/pinaxcon/templates/symposion/reviews/review_list.html @@ -13,9 +13,11 @@ {% if reviewed == 'all_reviews' %}

All proposals

{% elif reviewed == 'user_reviewed' %} -

Proposals you have reviewed

+

Proposals you have reviewed

+ {% elif reviewed == 'user_not_reviewed' %} +

Proposals you have not reviewed

{% else %} -

Proposals you have not yet reviewed

+

Proposals reviewed by selected reviewer

{% endif %} {% include "symposion/reviews/_review_table.html" %} diff --git a/pinaxcon/templates/symposion/reviews/review_review.html b/pinaxcon/templates/symposion/reviews/review_review.html index 80e1a4bab9e13327acc2f230ee9f0a688688e050..93096a10ba1a53cf2df599a90831e30c386e0e4a 100644 --- a/pinaxcon/templates/symposion/reviews/review_review.html +++ b/pinaxcon/templates/symposion/reviews/review_review.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load bootstrap %} diff --git a/pinaxcon/templates/symposion/schedule/presentation_detail.html b/pinaxcon/templates/symposion/schedule/presentation_detail.html index e6ecf940b8ebfc69b9ff3cd7e57e4612bb28df16..faccffb07534d99c9fbf50aa727de6cdababd644 100644 --- a/pinaxcon/templates/symposion/schedule/presentation_detail.html +++ b/pinaxcon/templates/symposion/schedule/presentation_detail.html @@ -3,7 +3,7 @@ {% load lca2018_tags %} {% load lca2019_tags %} {% load sitetree %} -{% load staticfiles %} +{% load static %} {% load thumbnail %} {% block head_title %}Presentation: {{ presentation.title }}{% endblock %} diff --git a/pinaxcon/templates/symposion/schedule/session_detail.html b/pinaxcon/templates/symposion/schedule/session_detail.html index cf088326dddaf4b4110dcc9944004ec348a9f05b..070d130038396e392b9f05ff41f032bc6a2cfd73 100644 --- a/pinaxcon/templates/symposion/schedule/session_detail.html +++ b/pinaxcon/templates/symposion/schedule/session_detail.html @@ -2,7 +2,7 @@ {% load lca2018_tags %} {% load sitetree %} -{% load staticfiles %} +{% load static %} {% load thumbnail %} {% load i18n %} diff --git a/pinaxcon/templates/symposion/schedule/session_list.html b/pinaxcon/templates/symposion/schedule/session_list.html index 4fdd15cc15b5d2b660f0406dd52329ca3926321d..9cb78c2c4a1586c7fe53558c307ccbcba15bbfc6 100644 --- a/pinaxcon/templates/symposion/schedule/session_list.html +++ b/pinaxcon/templates/symposion/schedule/session_list.html @@ -2,7 +2,7 @@ {% load lca2018_tags %} {% load sitetree %} -{% load staticfiles %} +{% load static %} {% load thumbnail %} {% load i18n %} diff --git a/pinaxcon/templatetags/lca2018_tags.py b/pinaxcon/templatetags/lca2018_tags.py index 98d1bc1ca26cc736fb63e1d453f652ce58c43ea0..b6cc7a689d9d5dcfb75ba261adaf20b2f0bc09c2 100644 --- a/pinaxcon/templatetags/lca2018_tags.py +++ b/pinaxcon/templatetags/lca2018_tags.py @@ -15,7 +15,7 @@ GST_RATE = settings.GST_RATE register = template.Library() -@register.assignment_tag() +@register.simple_tag() def classname(ob): return ob.__class__.__name__ diff --git a/pinaxcon/urls.py b/pinaxcon/urls.py index 034a1dfb8a968ed2640cd5782f37413c657d66c8..4818128bda012ed37b15cf9cd44b88ec8beeb24f 100644 --- a/pinaxcon/urls.py +++ b/pinaxcon/urls.py @@ -1,8 +1,9 @@ +import debug_toolbar from django.conf import settings -from django.conf.urls import include, url from django.conf.urls.static import static from django.views.generic import RedirectView from django.views.generic import TemplateView +from django.urls import include, path from django.contrib.flatpages.views import flatpage from django.contrib import admin @@ -11,31 +12,30 @@ import symposion.views urlpatterns = [ - url(r'^saml2/', include('djangosaml2.urls')), - url(r"^admin/", include(admin.site.urls)), + path('saml2/', include('djangosaml2.urls')), + path('admin/', admin.site.urls), - url(r"^speaker/", include("symposion.speakers.urls")), - url(r"^proposals/", include("symposion.proposals.urls")), - url(r"^reviews/", include("symposion.reviews.urls")), - url(r"^schedule/", include("symposion.schedule.urls")), - url(r"^conference/", include("symposion.conference.urls")), + path("speaker/", include("symposion.speakers.urls")), + path("proposals/", include("symposion.proposals.urls")), + path("reviews/", include("symposion.reviews.urls")), + path("schedule/", include("symposion.schedule.urls")), + path("conference/", include("symposion.conference.urls")), - url(r"^teams/", include("symposion.teams.urls")), - url(r'^raffle/', include("pinaxcon.raffle.urls")), + path("teams/", include("symposion.teams.urls")), + path('raffle/', include("pinaxcon.raffle.urls")), # Required by registrasion - url(r'^tickets/payments/', include('registripe.urls')), - url(r'^tickets/', include('registrasion.urls')), - url(r'^nested_admin/', include('nested_admin.urls')), - url(r'^checkin/', include('regidesk.urls')), - url(r'^pages/', include('django.contrib.flatpages.urls')), - - url(r'^dashboard/', symposion.views.dashboard, name="dashboard"), - url(r'^boardingpass', RedirectView.as_view(pattern_name="regidesk:boardingpass")), -] + path('tickets/payments/', include('registripe.urls')), + path('tickets/', include('registrasion.urls')), + path('nested_admin/', include('nested_admin.urls')), + path('checkin/', include('regidesk.urls')), + path('pages/', include('django.contrib.flatpages.urls')), + + path('dashboard/', symposion.views.dashboard, name="dashboard"), + path('boardingpass', RedirectView.as_view(pattern_name="regidesk:boardingpass")), -if settings.DEBUG: - import debug_toolbar - urlpatterns.insert(0, url(r'^__debug__/', include(debug_toolbar.urls))) + # Debug Toolbar. Always include to ensure tests work. + path('__debug__/', include(debug_toolbar.urls)), +] -urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)# \ No newline at end of file +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/pinaxcon/wsgi.py b/pinaxcon/wsgi.py index 2cf8d83c69fba7f93241c68598c50979ae201e3d..854ac99f97d58eb1b8b661d741c57780388238c5 100644 --- a/pinaxcon/wsgi.py +++ b/pinaxcon/wsgi.py @@ -5,6 +5,4 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pinaxcon.settings") from django.core.wsgi import get_wsgi_application # noqa -from dj_static import Cling, MediaCling # noqa - -application = Cling(MediaCling(get_wsgi_application())) +application = get_wsgi_application() diff --git a/requirements.txt b/requirements.txt index 6fb68a8d0882b79b969aea18ca4b2554ca737db5..db250ac054b8cc27b3ff1ef9d486fa5f18f88178 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,86 +1,51 @@ -asn1crypto==0.24.0 -bleach==2.1.3 -cachetools==2.1.0 -cairocffi==0.8.1 -CairoSVG==2.1.2 -certifi==2018.4.16 -cffi==1.11.5 -chardet==3.0.4 -coverage==4.0.3 -cryptography==2.3 -cssselect2==0.2.1 -dataclasses==0.6 -decorator==4.3.0 -defusedxml==0.5.0 -dj-database-url==0.4.2 -dj-static==0.0.6 -Django==1.11.25 -django-appconf==1.0.1 +Django>=2.2 +pinax-theme-bootstrap==8.0.1 +pinax-eventlog[django-lts]==5.1.0 +django-formset-js==0.5.0 +whitenoise==5.2.0 +dj-database-url==0.5.0 +pylibmc==1.6.1 +django-debug-toolbar==3.1.1 django-bootstrap-form==3.4 +django-settings-export~=1.2.1 django-capture-tag==1.0 -django-compressor==2.3 -django-countries==5.3.1 -django-crispy-forms==1.7.2 -django-debug-toolbar==1.9.1 -django-formset-js==0.5.0 -django-gapc-storage==0.5.1 -django-ical==1.4 -django-jquery-js==3.1.1 -django-model-utils==3.1.2 -django-nested-admin==2.2.6 -django-nose==1.4.5 -django-reversion==1.10.1 -django-sass-processor==0.7.3 -django-settings-export==1.2.1 -django-sitetree==1.10.0 -django-taggit==0.18.0 -django-timezone-field==2.1 -django-waffle==0.14.0 -djangosaml2==0.17.2 -easy-thumbnails==2.5 -future==0.16.0 -google-api-python-client==1.7.0 -google-auth==1.5.1 -google-auth-httplib2==0.0.3 -html5lib==1.0.1 -httplib2==0.11.3 -icalendar==4.0.2 -idna==2.7 -jsonfield==2.0.2 -libsass==0.19.3 -lxml==4.0.0 -mysqlclient==1.3.13 -nose==1.3.7 -oauth2client==4.1.2 -Paste==2.0.3 -Pillow==5.2.0 -pinax-eventlog==1.1.1 -pinax-stripe==3.2.1 -pinax-theme-bootstrap==7.10.2 -pyasn1==0.4.4 -pyasn1-modules==0.2.2 -pycparser==2.18 -pycryptodomex==3.6.4 -pylibmc==1.5.1 -pyOpenSSL==18.0.0 -pypng==0.0.18 -PyQRCode==1.2.1 -pysaml2==4.8.0 -python-dateutil==2.7.3 -pytz==2018.4 -rcssmin==1.0.6 -repoze.who==2.3 -requests==2.19.1 -rjsmin==1.1.0 -rsa==3.4.2 -six==1.11.0 -sqlparse==0.2.4 -static3==0.7.0 -stripe==1.38.0 -tinycss2==0.6.1 -uritemplate==3.0.0 -urllib3==1.23 -uWSGI==2.0.17.1 -webencodings==0.5.1 -WebOb==1.8.2 -zope.interface==4.5.0 +djangosaml2==0.50.0 +django-gapc-storage==0.5.2 +django-waffle==2.0.0 + +# database +mysqlclient==2.0.1 + +# For testing +django-nose==1.4.7 +coverage==5.3 +factory_boy==3.1.0 + +# Symposion reqs +django-appconf==1.0.4 +django-model-utils==4.0.0 +django-reversion==3.0.8 +django-sitetree==1.16.0 +django-taggit==1.3.0 +django-timezone-field==4.0 +easy-thumbnails==2.7.0 +bleach==3.2.1 +pytz>=2020.1 +django-ical==1.7.1 + +# Registrasion reqs +django-nested-admin==3.3.2 +CairoSVG==2.4.2 + +# Registripe +django-countries>=6.1.3 +pinax-stripe==4.4.0 +requests==2.24.0 +stripe==2.55.0 + +# SASS Compiler and template tags +libsass==0.20.1 +django-sass-processor==0.8.2 +django-compressor==2.4 + +django-crispy-forms==1.9.2 diff --git a/vendor/regidesk/regidesk/forms.py b/vendor/regidesk/regidesk/forms.py index 816160d6c5fdf9bf309c9419ffb957814d619fc7..09047ac50519c73e2fd3a7efa78e67d4a4e25ec0 100644 --- a/vendor/regidesk/regidesk/forms.py +++ b/vendor/regidesk/regidesk/forms.py @@ -1,15 +1,13 @@ import copy from regidesk import models -from django import forms -from django.core.urlresolvers import reverse import functools from django import forms -from django.core.urlresolvers import reverse from django.core.exceptions import ValidationError from django.db.models import F, Q from django.forms import widgets +from django.urls import reverse from django.utils import timezone from django_countries import countries diff --git a/vendor/regidesk/regidesk/management/commands/print_badges.py b/vendor/regidesk/regidesk/management/commands/print_badges.py index 16960f27008e3bc39ca81b2dfa885842e6fe33ea..5111cb5c019f3c4c7d54eeec55a7ed0dd31dfa09 100644 --- a/vendor/regidesk/regidesk/management/commands/print_badges.py +++ b/vendor/regidesk/regidesk/management/commands/print_badges.py @@ -2,10 +2,13 @@ from django.core.management.base import BaseCommand, CommandError -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from registrasion.views import _convert_img as convert_img from registrasion.views import render_badge_svg +User = get_user_model() + + class Command(BaseCommand): def handle(self, *args, **options): diff --git a/vendor/regidesk/regidesk/models.py b/vendor/regidesk/regidesk/models.py index 0bb590f6e6d4a67d21490c2db3ab866e2f41f679..b8417ef2ef50ad9a0732184a101c0bae60fee402 100644 --- a/vendor/regidesk/regidesk/models.py +++ b/vendor/regidesk/regidesk/models.py @@ -12,7 +12,7 @@ from django.db.models import Q, F from django.db.models import Case, When, Value from django.db.models import Count from django.db.models.signals import post_save -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model import pyqrcode from symposion import constants @@ -20,6 +20,8 @@ from symposion.text_parser import parse from registrasion.models import commerce from registrasion.util import generate_access_code as generate_code +User = get_user_model() + class BoardingPassTemplate(models.Model): @@ -60,7 +62,7 @@ class BoardingPass(models.Model): class CheckIn(models.Model): - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) boardingpass = models.OneToOneField(BoardingPass, null=True, blank=True, on_delete=models.SET_NULL) seen = models.DateTimeField(null=True,blank=True) diff --git a/vendor/regidesk/regidesk/templates/regidesk/base.html b/vendor/regidesk/regidesk/templates/regidesk/base.html index 1b60395670d69ee60a4a85ae20843d6ba782dc5e..71b003980b25d82f84d0cc5024ddd070031c3921 100644 --- a/vendor/regidesk/regidesk/templates/regidesk/base.html +++ b/vendor/regidesk/regidesk/templates/regidesk/base.html @@ -1,5 +1,5 @@ {% extends "site_base.html" %} -{% load staticfiles %} +{% load static %} {% load i18n %} @@ -39,4 +39,4 @@ }] }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/vendor/regidesk/regidesk/views.py b/vendor/regidesk/regidesk/views.py index 86cdbd6a4cae7a5b67866adf7c99aebcc598ccfb..008e4e5575df1e81200095adf7b465d13b63bddc 100644 --- a/vendor/regidesk/regidesk/views.py +++ b/vendor/regidesk/regidesk/views.py @@ -9,7 +9,8 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import permission_required, user_passes_test, login_required from django.contrib.auth.mixins import PermissionRequiredMixin -from django.contrib.auth.models import User, Group +from django.contrib.auth.models import Group +from django.contrib.auth import get_user_model from django.contrib.sites.models import Site from django.db import transaction from django.db.models import F, Q @@ -32,10 +33,10 @@ from symposion.conference.models import Conference from regidesk import forms from regidesk.models import BoardingPass, BoardingPassTemplate, CheckIn - - +User = get_user_model() AttendeeProfile = util.get_object_from_name(settings.ATTENDEE_PROFILE_MODEL) + def _staff_only(user): ''' Returns true if the user is staff. ''' return user.is_staff diff --git a/vendor/regidesk/requirements.txt b/vendor/regidesk/requirements.txt index fb4e31e0d7e19a90656569216e2fff857f9eb6ee..a4af7f311dee6d5c8964594ec39b9d4582f61541 100644 --- a/vendor/regidesk/requirements.txt +++ b/vendor/regidesk/requirements.txt @@ -1,4 +1,4 @@ -django-countries>=4.0 -requests>=2.11.1 +django-countries>=6.1.3 +requests>=2.24.0 pypng pyqrcode diff --git a/vendor/registrasion/registrasion/admin.py b/vendor/registrasion/registrasion/admin.py index 082046904b6b1a14611c07a0e6f358c64fbd06dc..83c3679c1ea3c50ed936117ddf38e2db4fb046fa 100644 --- a/vendor/registrasion/registrasion/admin.py +++ b/vendor/registrasion/registrasion/admin.py @@ -44,12 +44,14 @@ class DiscountForProductInline(admin.TabularInline): model = conditions.DiscountForProduct verbose_name = _("Product included in discount") verbose_name_plural = _("Products included in discount") + sortable_options = [] class DiscountForCategoryInline(admin.TabularInline): model = conditions.DiscountForCategory verbose_name = _("Category included in discount") verbose_name_plural = _("Categories included in discount") + sortable_options = [] @admin.register(conditions.TimeOrStockLimitDiscount) @@ -137,7 +139,7 @@ class VoucherFlagInline(nested_admin.NestedStackedInline): @admin.register(inventory.Voucher) -class VoucherAdmin(nested_admin.NestedAdmin): +class VoucherAdmin(nested_admin.NestedModelAdmin): def effects(self, obj): ''' List the effects of the voucher in the admin. ''' @@ -178,7 +180,7 @@ class VoucherAdmin(nested_admin.NestedAdmin): # Enabling conditions @admin.register(conditions.ProductFlag) class ProductFlagAdmin( - nested_admin.NestedAdmin, + nested_admin.NestedModelAdmin, EffectsDisplayMixin): def enablers(self, obj): @@ -194,7 +196,7 @@ class ProductFlagAdmin( # Enabling conditions @admin.register(conditions.CategoryFlag) class CategoryFlagAdmin( - nested_admin.NestedAdmin, + nested_admin.NestedModelAdmin, EffectsDisplayMixin): model = conditions.CategoryFlag @@ -206,7 +208,7 @@ class CategoryFlagAdmin( @admin.register(conditions.SpeakerFlag) -class SpeakerFlagAdmin(nested_admin.NestedAdmin, EffectsDisplayMixin): +class SpeakerFlagAdmin(nested_admin.NestedModelAdmin, EffectsDisplayMixin): model = conditions.SpeakerFlag fields = ("description", "is_presenter", "is_copresenter", "proposal_kind", diff --git a/vendor/registrasion/registrasion/contrib/badger.py b/vendor/registrasion/registrasion/contrib/badger.py index 15f9bf6dc8ce3ac68b821182c8f7ba342f455c66..2d0a15a9ed5a65a976cf1a85ee9d928a0eab1c21 100644 --- a/vendor/registrasion/registrasion/contrib/badger.py +++ b/vendor/registrasion/registrasion/contrib/badger.py @@ -24,7 +24,8 @@ import pdb from django.core.management.base import BaseCommand -from django.contrib.auth.models import User, Group +from django.contrib.auth.models import Group +from django.contrib.auth import get_user_model from django.db.utils import OperationalError, ProgrammingError from pinaxcon.registrasion.models import AttendeeProfile from registrasion.controllers.cart import CartController @@ -35,6 +36,8 @@ from registrasion.models import Product from registrasion.models import Invoice from symposion.speakers.models import Speaker +User = get_user_model() + # A few unicode encodings ... GLYPH_PLUS = '+' GLYPH_GLASS = u'\ue001' diff --git a/vendor/registrasion/registrasion/controllers/batch.py b/vendor/registrasion/registrasion/controllers/batch.py index 579d89703516512040cb2bb8157701cdc27c74d4..d21f646349e517acf66fe6f1baf0a116812b5809 100644 --- a/vendor/registrasion/registrasion/controllers/batch.py +++ b/vendor/registrasion/registrasion/controllers/batch.py @@ -1,7 +1,9 @@ import contextlib import functools -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model + +User = get_user_model() class BatchController(object): diff --git a/vendor/registrasion/registrasion/controllers/item.py b/vendor/registrasion/registrasion/controllers/item.py index 29345831c3e9df99829ec753b97749745807c7e9..0f44d31610ce6bda14438664a4ffeb577178a0d2 100644 --- a/vendor/registrasion/registrasion/controllers/item.py +++ b/vendor/registrasion/registrasion/controllers/item.py @@ -6,7 +6,7 @@ from functools import reduce from registrasion.models import commerce from registrasion.models import inventory -from collections import Iterable +from collections.abc import Iterable from collections import namedtuple from django.db.models import Case from django.db.models import Q diff --git a/vendor/registrasion/registrasion/models/commerce.py b/vendor/registrasion/registrasion/models/commerce.py index 4791ec3d6742e00d6ab602a07e20c01591ae581f..3e213c99f6bc998e00fff862b691c0d9260bcb60 100644 --- a/vendor/registrasion/registrasion/models/commerce.py +++ b/vendor/registrasion/registrasion/models/commerce.py @@ -1,7 +1,7 @@ from . import conditions from . import inventory -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.db import models from django.db.models import F, Q, Sum @@ -10,6 +10,8 @@ from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from model_utils.managers import InheritanceManager +User = get_user_model() + # Commerce Models @@ -38,7 +40,7 @@ class Cart(models.Model): (STATUS_RELEASED, _("Released")), ] - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) # ProductItems (foreign key) vouchers = models.ManyToManyField(inventory.Voucher, blank=True) time_last_updated = models.DateTimeField( @@ -76,8 +78,8 @@ class ProductItem(models.Model): return "product: %s * %d in Cart: %s" % ( self.product, self.quantity, self.cart) - cart = models.ForeignKey(Cart) - product = models.ForeignKey(inventory.Product) + cart = models.ForeignKey(Cart, on_delete=models.CASCADE) + product = models.ForeignKey(inventory.Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField(db_index=True) @@ -93,9 +95,10 @@ class DiscountItem(models.Model): return "%s: %s * %d in Cart: %s" % ( self.discount, self.product, self.quantity, self.cart) - cart = models.ForeignKey(Cart) - product = models.ForeignKey(inventory.Product) - discount = models.ForeignKey(conditions.DiscountBase) + cart = models.ForeignKey(Cart, on_delete=models.CASCADE) + product = models.ForeignKey(inventory.Product, on_delete=models.CASCADE) + discount = models.ForeignKey(conditions.DiscountBase, + on_delete=models.CASCADE) quantity = models.PositiveIntegerField() @@ -189,8 +192,8 @@ class Invoice(models.Model): return self.value - self.total_payments() # Invoice Number - user = models.ForeignKey(User) - cart = models.ForeignKey(Cart, null=True) + user = models.ForeignKey(User, on_delete=models.CASCADE) + cart = models.ForeignKey(Cart, null=True, on_delete=models.CASCADE) cart_revision = models.IntegerField( null=True, db_index=True, @@ -242,11 +245,12 @@ class LineItem(models.Model): ''' price * quantity ''' return self.price * self.quantity - invoice = models.ForeignKey(Invoice) + invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE) description = models.CharField(max_length=255) quantity = models.PositiveIntegerField() price = models.DecimalField(max_digits=8, decimal_places=2) - product = models.ForeignKey(inventory.Product, null=True, blank=True) + product = models.ForeignKey(inventory.Product, null=True, blank=True, + on_delete=models.CASCADE) @python_2_unicode_compatible @@ -275,7 +279,7 @@ class PaymentBase(models.Model): def __str__(self): return "Payment: ref=%s amount=%s" % (self.reference, self.amount) - invoice = models.ForeignKey(Invoice) + invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE) time = models.DateTimeField(default=timezone.now) reference = models.CharField(max_length=255) amount = models.DecimalField(max_digits=8, decimal_places=2) @@ -287,7 +291,7 @@ class ManualPayment(PaymentBase): class Meta: app_label = "registrasion" - entered_by = models.ForeignKey(User) + entered_by = models.ForeignKey(User, on_delete=models.CASCADE) class CreditNote(PaymentBase): @@ -364,7 +368,7 @@ class CreditNoteApplication(CleanOnSave, PaymentBase): "Cannot apply a refunded credit note to an invoice" ) - parent = models.OneToOneField(CreditNote) + parent = models.OneToOneField(CreditNote, on_delete=models.CASCADE) class CreditNoteRefund(CleanOnSave, models.Model): @@ -391,7 +395,7 @@ class CreditNoteRefund(CleanOnSave, models.Model): "Cannot refund a credit note that has been paid to an invoice" ) - parent = models.OneToOneField(CreditNote) + parent = models.OneToOneField(CreditNote, on_delete=models.CASCADE) time = models.DateTimeField(default=timezone.now) reference = models.CharField(max_length=255) @@ -402,4 +406,4 @@ class ManualCreditNoteRefund(CreditNoteRefund): class Meta: app_label = "registrasion" - entered_by = models.ForeignKey(User) + entered_by = models.ForeignKey(User, on_delete=models.CASCADE) diff --git a/vendor/registrasion/registrasion/models/conditions.py b/vendor/registrasion/registrasion/models/conditions.py index ca2f7d2f743737c40a405005f447d8ca04b1bebe..3652aa830f5d7944521772f6000c262ee22f18f3 100644 --- a/vendor/registrasion/registrasion/models/conditions.py +++ b/vendor/registrasion/registrasion/models/conditions.py @@ -10,8 +10,6 @@ from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from model_utils.managers import InheritanceManager -from symposion import proposals - # Condition Types @@ -99,7 +97,7 @@ class SpeakerCondition(models.Model): "presentation."), ) proposal_kind = models.ManyToManyField( - proposals.models.ProposalKind, + "symposion_proposals.ProposalKind", help_text=_("The types of proposals that these users may be " "presenters of."), ) @@ -520,6 +518,7 @@ class CategoryFlag(FlagBase): inventory.Category, help_text=_("If a product from this category is purchased, this " "condition is met."), + on_delete=models.CASCADE, ) diff --git a/vendor/registrasion/registrasion/models/inventory.py b/vendor/registrasion/registrasion/models/inventory.py index 6dfc6cd4081fa78f8dacea98c9f6874e6fcd8498..40201c64cb8e2ebfb28be20f8b102b9553b46f7c 100644 --- a/vendor/registrasion/registrasion/models/inventory.py +++ b/vendor/registrasion/registrasion/models/inventory.py @@ -156,7 +156,8 @@ class Product(models.Model): ) category = models.ForeignKey( Category, - verbose_name=_("Product category") + verbose_name=_("Product category"), + on_delete=models.CASCADE, ) price = models.DecimalField( max_digits=8, diff --git a/vendor/registrasion/registrasion/models/people.py b/vendor/registrasion/registrasion/models/people.py index e36f2688dead4fea8ae2ba1ecca7048be2456bb5..09561451fd24bd3c8281f3496be7b2cb7a41f805 100644 --- a/vendor/registrasion/registrasion/models/people.py +++ b/vendor/registrasion/registrasion/models/people.py @@ -1,7 +1,7 @@ from registrasion import util from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.utils.encoding import python_2_unicode_compatible @@ -9,6 +9,9 @@ from model_utils.managers import InheritanceManager from registrasion.models.commerce import Invoice, ProductItem +User = get_user_model() + + # User models @python_2_unicode_compatible diff --git a/vendor/registrasion/registrasion/reporting/reports.py b/vendor/registrasion/registrasion/reporting/reports.py index 5795a59921a5af4d3426401a1474a5cb9ce56c8e..9c76d4df7de820f3a215d41c4b9de6a106985702 100644 --- a/vendor/registrasion/registrasion/reporting/reports.py +++ b/vendor/registrasion/registrasion/reporting/reports.py @@ -2,8 +2,8 @@ import csv from django.contrib.auth.decorators import user_passes_test from django.shortcuts import render -from django.core.urlresolvers import reverse from django.http import HttpResponse +from django.urls import reverse from functools import wraps from registrasion import views diff --git a/vendor/registrasion/registrasion/reporting/views.py b/vendor/registrasion/registrasion/reporting/views.py index 54a2e26838208e9044b6980ae74a119dea32af13..7a502252fefb3af362ba531b558f7fcbc434c9a4 100644 --- a/vendor/registrasion/registrasion/reporting/views.py +++ b/vendor/registrasion/registrasion/reporting/views.py @@ -6,8 +6,7 @@ import itertools from django.conf import settings from django.contrib.auth.decorators import user_passes_test -from django.contrib.auth.models import User -from django.core.urlresolvers import reverse +from django.contrib.auth import get_user_model from django.db import models from django.db.models import F, Q, Subquery, OuterRef from django.db.models import Count, Max, Sum @@ -15,6 +14,7 @@ from django.db.models import Case, When, Value from django.db.models.fields.related import RelatedField from django.db.models.fields import CharField from django.shortcuts import render +from django.urls import reverse from registrasion.controllers.cart import CartController from registrasion.controllers.item import ItemController @@ -39,6 +39,7 @@ def CURRENCY(): return models.DecimalField(decimal_places=2) +User = get_user_model() AttendeeProfile = util.get_object_from_name(settings.ATTENDEE_PROFILE_MODEL) diff --git a/vendor/registrasion/registrasion/templatetags/registrasion_tags.py b/vendor/registrasion/registrasion/templatetags/registrasion_tags.py index ccebe20bedc46859978b142f1e2ff6f817ac235b..4c4a324ee2dccb2bebc9d51e42bd36e82c6d694c 100644 --- a/vendor/registrasion/registrasion/templatetags/registrasion_tags.py +++ b/vendor/registrasion/registrasion/templatetags/registrasion_tags.py @@ -5,10 +5,7 @@ from registrasion.controllers.item import ItemController from django import template from django.conf import settings from django.db.models import Sum -try: - from urllib import urlencode -except ImportError: - from urllib.parse import urlencode +from urllib.parse import urlencode from operator import attrgetter @@ -24,7 +21,7 @@ def user_for_context(context): return context.request.user -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def available_categories(context): ''' Gets all of the currently available products. @@ -36,7 +33,7 @@ def available_categories(context): return CategoryController.available_categories(user_for_context(context)) -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def missing_categories(context): ''' Adds the categories that the user does not currently have. ''' user = user_for_context(context) @@ -52,7 +49,7 @@ def missing_categories(context): return sorted(set(i for i in missing), key=attrgetter("order")) -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def available_credit(context): ''' Calculates the sum of unclaimed credit from this user's credit notes. @@ -69,7 +66,7 @@ def available_credit(context): return 0 - ret -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def invoices(context): ''' @@ -78,7 +75,7 @@ def invoices(context): return commerce.Invoice.objects.filter(user=user_for_context(context)) -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def items_pending(context): ''' Gets all of the items that the user from this context has reserved. @@ -89,7 +86,7 @@ def items_pending(context): return ItemController(user_for_context(context)).items_pending() -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def items_purchased(context, category=None): ''' Returns the items purchased for this user. @@ -102,7 +99,7 @@ def items_purchased(context, category=None): ) -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def total_items_purchased(context, category=None): ''' Returns the number of items purchased for this user (sum of quantities). @@ -113,7 +110,7 @@ def total_items_purchased(context, category=None): return sum(i.quantity for i in items_purchased(context, category)) -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def report_as_csv(context, section): old_query = context.request.META["QUERY_STRING"] @@ -126,7 +123,7 @@ def report_as_csv(context, section): return context.request.path + "?" + querystring -@register.assignment_tag(takes_context=True) +@register.simple_tag(takes_context=True) def sold_out_and_unregistered(context): ''' If the current user is unregistered, returns True if there are no products in the TICKET_PRODUCT_CATEGORY that are available to that user. @@ -186,7 +183,7 @@ def include_if_exists(parser, token): try: tag_name, template_name = token.split_contents() except ValueError: - raise (template.TemplateSyntaxError, + raise template.TemplateSyntaxError( "%r tag requires a single argument" % token.contents.split()[0]) return IncludeNode(template_name) diff --git a/vendor/registrasion/registrasion/tests/test_batch.py b/vendor/registrasion/registrasion/tests/test_batch.py index 331f8838f06a42c647bf0ccb06971a002fdbf1a8..3153c42c63d51d35875575ef1d2409936cf1a23a 100644 --- a/vendor/registrasion/registrasion/tests/test_batch.py +++ b/vendor/registrasion/registrasion/tests/test_batch.py @@ -127,11 +127,11 @@ class BatchTestCase(RegistrationCartTestCase): # end_batch should get called once on exiting the batch with BatchController.batch(self.USER_1): ender = get_ender(self.USER_1) - self.assertEquals(1, ender.end_count) + self.assertEqual(1, ender.end_count) # end_batch should get called once on exiting the batch # no matter how deep the object gets cached with BatchController.batch(self.USER_1): with BatchController.batch(self.USER_1): ender = get_ender(self.USER_1) - self.assertEquals(1, ender.end_count) + self.assertEqual(1, ender.end_count) diff --git a/vendor/registrasion/registrasion/tests/test_cart.py b/vendor/registrasion/registrasion/tests/test_cart.py index 825ff675358875dcf56dc10dc9744eff18c659e2..9b274762624d9d36c5b9ed25031ac2192cf304a1 100644 --- a/vendor/registrasion/registrasion/tests/test_cart.py +++ b/vendor/registrasion/registrasion/tests/test_cart.py @@ -2,7 +2,7 @@ import datetime import pytz from decimal import Decimal -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ValidationError from django.core.management import call_command @@ -19,6 +19,7 @@ from registrasion.tests.controller_helpers import TestingCartController from registrasion.tests.patches import MixInPatches UTC = pytz.timezone('UTC') +User = get_user_model() class RegistrationCartTestCase(MixInPatches, TestCase): @@ -85,7 +86,7 @@ class RegistrationCartTestCase(MixInPatches, TestCase): prod = inventory.Product.objects.create( name="Product " + str(i + 1), description="This is a test product.", - category=cls.categories[i / 2], # 2 products per category + category=cls.categories[i // 2], # 2 products per category price=Decimal("10.00"), reservation_duration=cls.RESERVATION, limit_per_user=10, @@ -192,7 +193,7 @@ class BasicCartTests(RegistrationCartTestCase): product=self.PROD_1) self.assertEqual(1, len(items)) item = items[0] - self.assertEquals(2, item.quantity) + self.assertEqual(2, item.quantity) def test_set_quantity(self): current_cart = TestingCartController.for_user(self.USER_1) diff --git a/vendor/registrasion/registrasion/tests/test_credit_note.py b/vendor/registrasion/registrasion/tests/test_credit_note.py index 76d0fc3860491341a4263980385304de6e96d6e7..208f6bba718d5b071126758f676cbedfe488e29c 100644 --- a/vendor/registrasion/registrasion/tests/test_credit_note.py +++ b/vendor/registrasion/registrasion/tests/test_credit_note.py @@ -114,7 +114,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): cn = self._credit_note_for_invoice(invoice.invoice) # That credit note should be in the unclaimed pile - self.assertEquals(1, commerce.CreditNote.unclaimed().count()) + self.assertEqual(1, commerce.CreditNote.unclaimed().count()) # Create a new (identical) cart with invoice cart = TestingCartController.for_user(self.USER_1) @@ -126,7 +126,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): self.assertTrue(invoice2.invoice.is_paid) # That invoice should not show up as unclaimed any more - self.assertEquals(0, commerce.CreditNote.unclaimed().count()) + self.assertEqual(0, commerce.CreditNote.unclaimed().count()) def test_apply_credit_note_generates_new_credit_note_if_overpaying(self): @@ -141,7 +141,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): # There should be one credit note generated out of the invoice. cn = self._credit_note_for_invoice(invoice.invoice) # noqa - self.assertEquals(1, commerce.CreditNote.unclaimed().count()) + self.assertEqual(1, commerce.CreditNote.unclaimed().count()) # Create a new invoice for a cart of half value of inv 1 invoice2 = self._invoice_containing_prod_1(1) @@ -150,7 +150,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): # We generated a new credit note, and spent the old one, # unclaimed should still be 1. - self.assertEquals(1, commerce.CreditNote.unclaimed().count()) + self.assertEqual(1, commerce.CreditNote.unclaimed().count()) credit_note2 = commerce.CreditNote.objects.get( invoice=invoice2.invoice, @@ -158,7 +158,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): # The new credit note should be the residual of the cost of cart 1 # minus the cost of cart 2. - self.assertEquals( + self.assertEqual( invoice.invoice.value - invoice2.invoice.value, credit_note2.value, ) @@ -210,14 +210,14 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): invoice.refund() - self.assertEquals(1, commerce.CreditNote.unclaimed().count()) + self.assertEqual(1, commerce.CreditNote.unclaimed().count()) cn = self._credit_note_for_invoice(invoice.invoice) cn.refund() # Refunding a credit note should mark it as claimed - self.assertEquals(0, commerce.CreditNote.unclaimed().count()) + self.assertEqual(0, commerce.CreditNote.unclaimed().count()) # Create a new cart with invoice cart = TestingCartController.for_user(self.USER_1) @@ -238,7 +238,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): invoice.refund() - self.assertEquals(1, commerce.CreditNote.unclaimed().count()) + self.assertEqual(1, commerce.CreditNote.unclaimed().count()) cn = self._credit_note_for_invoice(invoice.invoice) @@ -251,7 +251,7 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): # Creating `invoice_2` will automatically apply `cn`. cn.apply_to_invoice(invoice_2.invoice) - self.assertEquals(0, commerce.CreditNote.unclaimed().count()) + self.assertEqual(0, commerce.CreditNote.unclaimed().count()) # Cannot refund this credit note as it is already applied. with self.assertRaises(ValidationError): @@ -327,13 +327,13 @@ class CreditNoteTestCase(TestHelperMixin, RegistrationCartTestCase): invoice._refresh() # The first invoice should be refunded - self.assertEquals( + self.assertEqual( commerce.Invoice.STATUS_VOID, invoice.invoice.status, ) # Both credit notes should be for the same amount - self.assertEquals( + self.assertEqual( cn.credit_note.value, cn2.credit_note.value, ) diff --git a/vendor/registrasion/registrasion/tests/test_invoice.py b/vendor/registrasion/registrasion/tests/test_invoice.py index b77fa22352ecedf06e1401ce2f063cdbe3813a0e..f4d511a9397aaa40013825b443540a171c1a701d 100644 --- a/vendor/registrasion/registrasion/tests/test_invoice.py +++ b/vendor/registrasion/registrasion/tests/test_invoice.py @@ -98,7 +98,8 @@ class InvoiceTestCase(TestHelperMixin, RegistrationCartTestCase): def test_total_payments_balance_due(self): invoice = self._invoice_containing_prod_1(2) - for i in xrange(0, invoice.invoice.value): + invoice_value = int(invoice.invoice.value) + for i in range(0, invoice_value): self.assertTrue( i + 1, invoice.invoice.total_payments() ) @@ -175,7 +176,7 @@ class InvoiceTestCase(TestHelperMixin, RegistrationCartTestCase): invoice_1.refund() cart.refresh_from_db() - self.assertEquals(commerce.Cart.STATUS_RELEASED, cart.status) + self.assertEqual(commerce.Cart.STATUS_RELEASED, cart.status) def test_invoice_voids_self_if_cart_changes(self): current_cart = TestingCartController.for_user(self.USER_1) @@ -322,12 +323,12 @@ class InvoiceTestCase(TestHelperMixin, RegistrationCartTestCase): ) inv = TestingInvoiceController(_invoice) - self.assertEquals( + self.assertEqual( inv.invoice.value, sum(i[1] for i in description_price_pairs) ) - self.assertEquals( + self.assertEqual( len(inv.invoice.lineitem_set.all()), len(description_price_pairs) ) @@ -336,37 +337,37 @@ class InvoiceTestCase(TestHelperMixin, RegistrationCartTestCase): def test_sends_email_on_invoice_creation(self): invoice = self._invoice_containing_prod_1(1) - self.assertEquals(1, len(self.emails)) + self.assertEqual(1, len(self.emails)) email = self.emails[0] - self.assertEquals([self.USER_1.email], email["to"]) - self.assertEquals("invoice_created", email["kind"]) - self.assertEquals(invoice.invoice, email["context"]["invoice"]) + self.assertEqual([self.USER_1.email], email["to"]) + self.assertEqual("invoice_created", email["kind"]) + self.assertEqual(invoice.invoice, email["context"]["invoice"]) def test_sends_first_change_email_on_invoice_fully_paid(self): invoice = self._invoice_containing_prod_1(1) - self.assertEquals(1, len(self.emails)) + self.assertEqual(1, len(self.emails)) invoice.pay("Partial", invoice.invoice.value - 1) # Should have an "invoice_created" email and nothing else. - self.assertEquals(1, len(self.emails)) + self.assertEqual(1, len(self.emails)) invoice.pay("Remainder", 1) - self.assertEquals(2, len(self.emails)) + self.assertEqual(2, len(self.emails)) email = self.emails[1] - self.assertEquals([self.USER_1.email], email["to"]) - self.assertEquals("invoice_updated", email["kind"]) - self.assertEquals(invoice.invoice, email["context"]["invoice"]) + self.assertEqual([self.USER_1.email], email["to"]) + self.assertEqual("invoice_updated", email["kind"]) + self.assertEqual(invoice.invoice, email["context"]["invoice"]) def test_sends_email_when_invoice_refunded(self): invoice = self._invoice_containing_prod_1(1) - self.assertEquals(1, len(self.emails)) + self.assertEqual(1, len(self.emails)) invoice.pay("Payment", invoice.invoice.value) - self.assertEquals(2, len(self.emails)) + self.assertEqual(2, len(self.emails)) invoice.refund() - self.assertEquals(3, len(self.emails)) + self.assertEqual(3, len(self.emails)) email = self.emails[2] - self.assertEquals([self.USER_1.email], email["to"]) - self.assertEquals("invoice_updated", email["kind"]) - self.assertEquals(invoice.invoice, email["context"]["invoice"]) + self.assertEqual([self.USER_1.email], email["to"]) + self.assertEqual("invoice_updated", email["kind"]) + self.assertEqual(invoice.invoice, email["context"]["invoice"]) diff --git a/vendor/registrasion/registrasion/tests/test_speaker.py b/vendor/registrasion/registrasion/tests/test_speaker.py index cf64074e1e68ae4445ff5f1072dfd1e13a864fc9..f22a8ad8175023b565e292e5cef4e33cf8020214 100644 --- a/vendor/registrasion/registrasion/tests/test_speaker.py +++ b/vendor/registrasion/registrasion/tests/test_speaker.py @@ -67,7 +67,7 @@ class SpeakerTestCase(RegistrationCartTestCase): kind=kind_1, title="Proposal 1", abstract="Abstract", - description="Description", + #description="Description", speaker=speaker_1, ) proposal_models.AdditionalSpeaker.objects.create( @@ -80,7 +80,7 @@ class SpeakerTestCase(RegistrationCartTestCase): kind=kind_2, title="Proposal 2", abstract="Abstract", - description="Description", + #description="Description", speaker=speaker_1, ) proposal_models.AdditionalSpeaker.objects.create( diff --git a/vendor/registrasion/registrasion/views.py b/vendor/registrasion/registrasion/views.py index f270ef8d1349dd4fdcf19f4f1a29cb8d39bd7658..d740d5ae9a2561d8769d0107ab9719731bf2836f 100644 --- a/vendor/registrasion/registrasion/views.py +++ b/vendor/registrasion/registrasion/views.py @@ -28,7 +28,7 @@ from django import forms as django_forms from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import user_passes_test -from django.contrib.auth.models import User +from django.contrib.auth import get_user_model from django.contrib import messages from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ValidationError @@ -50,6 +50,8 @@ from registrasion.contrib.badger import ( InvalidTicketChoiceError ) +User = get_user_model() + _GuidedRegistrationSection = namedtuple( "GuidedRegistrationSection", ( diff --git a/vendor/registrasion/requirements/base.txt b/vendor/registrasion/requirements/base.txt index c45a3a46730be13cbf7af07884025f339b6b6bab..e84dd1c666488cf95ff7bd4b8e04ab48dad47c4a 100644 --- a/vendor/registrasion/requirements/base.txt +++ b/vendor/registrasion/requirements/base.txt @@ -1,3 +1,3 @@ -django-nested-admin==2.2.6 +django-nested-admin==3.3.2 #symposion==1.0b2.dev3 -lxml==4.0.0 +lxml==4.6.1 diff --git a/vendor/registripe/registripe/forms.py b/vendor/registripe/registripe/forms.py index 6438618a55124493e5d51e3755e5af274a213fad..3d6e0304da672abf93f81cf3144aab80307addf4 100644 --- a/vendor/registripe/registripe/forms.py +++ b/vendor/registripe/registripe/forms.py @@ -1,15 +1,13 @@ import copy from registripe import models -from django import forms -from django.core.urlresolvers import reverse import functools from django import forms -from django.core.urlresolvers import reverse from django.core.exceptions import ValidationError from django.db.models import F, Q from django.forms import widgets +from django.urls import reverse from django.utils import timezone from django_countries import countries @@ -21,7 +19,7 @@ from pinax.stripe import models as pinax_stripe_models class StripeCardElement(forms.widgets.TextInput): - def render(self, name, value, attrs=None): + def render(self, name, value, attrs=None, renderer=None): element = '''
Please wait.
''' % (name, ) @@ -36,7 +34,7 @@ class StripeCardElement(forms.widgets.TextInput): class StripeTokenWidget(forms.widgets.HiddenInput): - def render(self, name, value, attrs=None): + def render(self, name, value, attrs=None, renderer=None): return '''