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.
This commit is contained in:
parent
ac57053ecf
commit
252697b842
78 changed files with 646 additions and 364 deletions
|
@ -1,2 +1,2 @@
|
|||
django<1.12,>=1.11
|
||||
pysaml2==4.8.0
|
||||
django<3.0,>=2.2
|
||||
pysaml2>=5.3.0
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,3 +8,5 @@ LOGIN_URL='/accounts/login'
|
|||
ROOT_URLCONF = "pinaxcon.devmode_urls"
|
||||
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
|
||||
INTERNAL_IPS = ['*']
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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}"
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load lca2018_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load sitetree %}
|
||||
{% load sass_tags %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% load registrasion_tags %}
|
||||
{% load lca2018_tags %}
|
||||
{% load lca2019_tags %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load waffle_tags %}
|
||||
|
||||
{% if user.is_staff %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% block body_outer %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
<h4>All proposals</h4>
|
||||
{% elif reviewed == 'user_reviewed' %}
|
||||
<h4>Proposals you have reviewed</h4>
|
||||
{% elif reviewed == 'user_not_reviewed' %}
|
||||
<h4>Proposals you have not reviewed</h4>
|
||||
{% else %}
|
||||
<h4>Proposals you have not yet reviewed</h4>
|
||||
<h4>Proposals reviewed by selected reviewer</h4>
|
||||
{% endif %}
|
||||
|
||||
{% include "symposion/reviews/_review_table.html" %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% load lca2018_tags %}
|
||||
{% load sitetree %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load thumbnail %}
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% load lca2018_tags %}
|
||||
{% load sitetree %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
{% load thumbnail %}
|
||||
{% load i18n %}
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
|
@ -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')),
|
||||
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')),
|
||||
|
||||
url(r'^dashboard/', symposion.views.dashboard, name="dashboard"),
|
||||
url(r'^boardingpass', RedirectView.as_view(pattern_name="regidesk:boardingpass")),
|
||||
path('dashboard/', symposion.views.dashboard, name="dashboard"),
|
||||
path('boardingpass', RedirectView.as_view(pattern_name="regidesk:boardingpass")),
|
||||
|
||||
# Debug Toolbar. Always include to ensure tests work.
|
||||
path('__debug__/', include(debug_toolbar.urls)),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
import debug_toolbar
|
||||
urlpatterns.insert(0, url(r'^__debug__/', include(debug_toolbar.urls)))
|
||||
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)#
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -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()
|
||||
|
|
135
requirements.txt
135
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-bootstrap-form==3.4
|
||||
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>=2.2
|
||||
pinax-theme-bootstrap==8.0.1
|
||||
pinax-eventlog[django-lts]==5.1.0
|
||||
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
|
||||
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
|
||||
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
|
||||
|
|
4
vendor/regidesk/regidesk/forms.py
vendored
4
vendor/regidesk/regidesk/forms.py
vendored
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
6
vendor/regidesk/regidesk/models.py
vendored
6
vendor/regidesk/regidesk/models.py
vendored
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "site_base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load static %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
|
|
7
vendor/regidesk/regidesk/views.py
vendored
7
vendor/regidesk/regidesk/views.py
vendored
|
@ -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
|
||||
|
|
4
vendor/regidesk/requirements.txt
vendored
4
vendor/regidesk/requirements.txt
vendored
|
@ -1,4 +1,4 @@
|
|||
django-countries>=4.0
|
||||
requests>=2.11.1
|
||||
django-countries>=6.1.3
|
||||
requests>=2.24.0
|
||||
pypng
|
||||
pyqrcode
|
||||
|
|
10
vendor/registrasion/registrasion/admin.py
vendored
10
vendor/registrasion/registrasion/admin.py
vendored
|
@ -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",
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,6 @@ 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 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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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(
|
||||
|
|
4
vendor/registrasion/registrasion/views.py
vendored
4
vendor/registrasion/registrasion/views.py
vendored
|
@ -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",
|
||||
(
|
||||
|
|
4
vendor/registrasion/requirements/base.txt
vendored
4
vendor/registrasion/requirements/base.txt
vendored
|
@ -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
|
||||
|
|
8
vendor/registripe/registripe/forms.py
vendored
8
vendor/registripe/registripe/forms.py
vendored
|
@ -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 = '''
|
||||
<div class="registrasion-stripe-element" id='%s' style='"-moz-appearance: textfield; -webkit-appearance: textfield; appearance: field;"'>Please wait.</div>''' % (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 '''
|
||||
<div class='registrasion-stripe-token' style='display:none;'
|
||||
|
|
4
vendor/registripe/registripe/models.py
vendored
4
vendor/registripe/registripe/models.py
vendored
|
@ -7,8 +7,8 @@ from pinax.stripe.models import Charge
|
|||
|
||||
class StripePayment(commerce.PaymentBase):
|
||||
|
||||
charge = models.ForeignKey(Charge)
|
||||
charge = models.ForeignKey(Charge, on_delete=models.CASCADE)
|
||||
|
||||
class StripeCreditNoteRefund(commerce.CreditNoteRefund):
|
||||
|
||||
charge = models.ForeignKey(Charge)
|
||||
charge = models.ForeignKey(Charge, on_delete=models.CASCADE)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% comment %}
|
||||
This is used in the default invoice.html file to display Stripe funcationality if the app is loaded.
|
||||
This is used in the default invoice.html file to display Stripe functionality if the app is loaded.
|
||||
{% endcomment %}
|
||||
|
||||
{% block content %}
|
||||
|
|
8
vendor/registripe/requirements.txt
vendored
8
vendor/registripe/requirements.txt
vendored
|
@ -1,4 +1,4 @@
|
|||
django-countries>=4.0
|
||||
pinax-stripe==3.2.1
|
||||
requests>=2.11.1
|
||||
stripe==1.38.0
|
||||
django-countries>=6.1.3
|
||||
pinax-stripe==4.4.0
|
||||
requests>=2.24.0
|
||||
stripe==2.55.0
|
||||
|
|
6
vendor/symposion/conference/models.py
vendored
6
vendor/symposion/conference/models.py
vendored
|
@ -49,7 +49,11 @@ class Section(models.Model):
|
|||
scheduling process.
|
||||
"""
|
||||
|
||||
conference = models.ForeignKey(Conference, verbose_name=_("Conference"))
|
||||
conference = models.ForeignKey(
|
||||
Conference,
|
||||
verbose_name=_("Conference"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
name = models.CharField(_("Name"), max_length=100)
|
||||
slug = models.SlugField(verbose_name=_("Slug"))
|
||||
|
|
4
vendor/symposion/conference/views.py
vendored
4
vendor/symposion/conference/views.py
vendored
|
@ -2,7 +2,9 @@ from django.http import Http404
|
|||
from django.shortcuts import render
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
57
vendor/symposion/proposals/models.py
vendored
57
vendor/symposion/proposals/models.py
vendored
|
@ -1,13 +1,13 @@
|
|||
import os
|
||||
import uuid
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.timezone import now
|
||||
|
||||
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
|
||||
|
||||
|
@ -19,6 +19,8 @@ from symposion.text_parser import parse
|
|||
from symposion.conference.models import Section
|
||||
from symposion.speakers.models import Speaker
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class ProposalSection(models.Model):
|
||||
"""
|
||||
|
@ -30,7 +32,11 @@ class ProposalSection(models.Model):
|
|||
* closed is NULL or False
|
||||
"""
|
||||
|
||||
section = models.OneToOneField(Section, verbose_name=_("Section"))
|
||||
section = models.OneToOneField(
|
||||
Section,
|
||||
verbose_name=_("Section"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
start = models.DateTimeField(null=True, blank=True, verbose_name=_("Start"))
|
||||
end = models.DateTimeField(null=True, blank=True, verbose_name=_("End"))
|
||||
|
@ -66,7 +72,12 @@ class ProposalKind(models.Model):
|
|||
to distinguish the section as well as the kind.
|
||||
"""
|
||||
|
||||
section = models.ForeignKey(Section, related_name="proposal_kinds", verbose_name=_("Section"))
|
||||
section = models.ForeignKey(
|
||||
Section,
|
||||
related_name="proposal_kinds",
|
||||
verbose_name=_("Section"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
name = models.CharField(_("Name"), max_length=100)
|
||||
slug = models.SlugField(verbose_name=_("Slug"))
|
||||
|
@ -79,7 +90,11 @@ class ProposalBase(models.Model):
|
|||
|
||||
objects = InheritanceManager()
|
||||
|
||||
kind = models.ForeignKey(ProposalKind, verbose_name=_("Kind"))
|
||||
kind = models.ForeignKey(
|
||||
ProposalKind,
|
||||
verbose_name=_("Kind"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
title = models.CharField(max_length=100, verbose_name=_("Title"))
|
||||
abstract = models.TextField(
|
||||
|
@ -134,7 +149,12 @@ class ProposalBase(models.Model):
|
|||
editable=False,
|
||||
verbose_name=_("Submitted")
|
||||
)
|
||||
speaker = models.ForeignKey(Speaker, related_name="proposals", verbose_name=_("Speaker"))
|
||||
speaker = models.ForeignKey(
|
||||
Speaker,
|
||||
related_name="proposals",
|
||||
verbose_name=_("Speaker"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
# @@@ this validation used to exist as a validators keyword on additional_speakers
|
||||
# M2M field but that is no longer supported by Django. Should be moved to
|
||||
|
@ -213,8 +233,16 @@ class AdditionalSpeaker(models.Model):
|
|||
(SPEAKING_STATUS_DECLINED, _("Declined")),
|
||||
]
|
||||
|
||||
speaker = models.ForeignKey(Speaker, verbose_name=_("Speaker"))
|
||||
proposalbase = models.ForeignKey(ProposalBase, verbose_name=_("Proposalbase"))
|
||||
speaker = models.ForeignKey(
|
||||
Speaker,
|
||||
verbose_name=_("Speaker"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
proposalbase = models.ForeignKey(
|
||||
ProposalBase,
|
||||
verbose_name=_("Proposalbase"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
status = models.IntegerField(choices=SPEAKING_STATUS, default=SPEAKING_STATUS_PENDING, verbose_name=_("Status"))
|
||||
|
||||
class Meta:
|
||||
|
@ -239,9 +267,18 @@ def uuid_filename(instance, filename):
|
|||
|
||||
class SupportingDocument(models.Model):
|
||||
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="supporting_documents", verbose_name=_("Proposal"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="supporting_documents",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
uploaded_by = models.ForeignKey(User, verbose_name=_("Uploaded by"))
|
||||
uploaded_by = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("Uploaded by"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
created_at = models.DateTimeField(default=now, verbose_name=_("Created at"))
|
||||
|
||||
|
|
8
vendor/symposion/proposals/views.py
vendored
8
vendor/symposion/proposals/views.py
vendored
|
@ -5,14 +5,14 @@ import sys
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db.models import Q
|
||||
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.views import static
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -27,6 +27,8 @@ from symposion.proposals.forms import (
|
|||
AddSpeakerForm, SupportingDocumentCreateForm
|
||||
)
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def get_form(name):
|
||||
dot = name.rindex(".")
|
||||
|
@ -36,7 +38,7 @@ def get_form(name):
|
|||
|
||||
|
||||
def proposal_submit(request):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
messages.info(request, _("To submit a proposal, please "
|
||||
"<a href='{0}'>log in</a> and create a speaker profile "
|
||||
"via the dashboard.".format(settings.LOGIN_URL)))
|
||||
|
|
91
vendor/symposion/reviews/models.py
vendored
91
vendor/symposion/reviews/models.py
vendored
|
@ -10,7 +10,7 @@ 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
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from symposion import constants
|
||||
|
@ -18,6 +18,8 @@ from symposion.text_parser import parse
|
|||
from symposion.proposals.models import ProposalBase
|
||||
from symposion.schedule.models import Presentation
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Votes(object):
|
||||
ABSTAIN = "0"
|
||||
|
@ -51,8 +53,16 @@ class ReviewAssignment(models.Model):
|
|||
(AUTO_ASSIGNED_LATER, _("auto-assigned, later")),
|
||||
]
|
||||
|
||||
proposal = models.ForeignKey(ProposalBase, verbose_name=_("Proposal"))
|
||||
user = models.ForeignKey(User, verbose_name=_("User"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
origin = models.IntegerField(choices=ORIGIN_CHOICES, verbose_name=_("Origin"))
|
||||
|
||||
|
@ -91,8 +101,17 @@ class ReviewAssignment(models.Model):
|
|||
|
||||
|
||||
class ProposalMessage(models.Model):
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="messages", verbose_name=_("Proposal"))
|
||||
user = models.ForeignKey(User, verbose_name=_("User"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="messages",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
message = models.TextField(verbose_name=_("Message"))
|
||||
message_html = models.TextField(blank=True)
|
||||
|
@ -111,8 +130,17 @@ class ProposalMessage(models.Model):
|
|||
class Review(models.Model):
|
||||
VOTES = VOTES
|
||||
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="reviews", verbose_name=_("Proposal"))
|
||||
user = models.ForeignKey(User, verbose_name=_("User"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="reviews",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
# No way to encode "-0" vs. "+0" into an IntegerField, and I don't feel
|
||||
# like some complicated encoding system.
|
||||
|
@ -208,8 +236,17 @@ class Review(models.Model):
|
|||
class LatestVote(models.Model):
|
||||
VOTES = VOTES
|
||||
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="votes", verbose_name=_("Proposal"))
|
||||
user = models.ForeignKey(User, verbose_name=_("User"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="votes",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
# No way to encode "-0" vs. "+0" into an IntegerField, and I don't feel
|
||||
# like some complicated encoding system.
|
||||
|
@ -232,7 +269,12 @@ class LatestVote(models.Model):
|
|||
|
||||
|
||||
class ProposalResult(models.Model):
|
||||
proposal = models.OneToOneField(ProposalBase, related_name="result", verbose_name=_("Proposal"))
|
||||
proposal = models.OneToOneField(
|
||||
ProposalBase,
|
||||
related_name="result",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
score = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"), verbose_name=_("Score"))
|
||||
comment_count = models.PositiveIntegerField(default=0, verbose_name=_("Comment count"))
|
||||
# vote_count only counts non-abstain votes.
|
||||
|
@ -297,8 +339,17 @@ class ProposalResult(models.Model):
|
|||
|
||||
|
||||
class Comment(models.Model):
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="comments", verbose_name=_("Proposal"))
|
||||
commenter = models.ForeignKey(User, verbose_name=_("Commenter"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="comments",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
commenter = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("Commenter"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
text = models.TextField(verbose_name=_("Text"))
|
||||
text_html = models.TextField(blank=True)
|
||||
|
||||
|
@ -329,9 +380,19 @@ class NotificationTemplate(models.Model):
|
|||
|
||||
class ResultNotification(models.Model):
|
||||
|
||||
proposal = models.ForeignKey(ProposalBase, related_name="notifications", verbose_name=_("Proposal"))
|
||||
template = models.ForeignKey(NotificationTemplate, null=True, blank=True,
|
||||
on_delete=models.SET_NULL, verbose_name=_("Template"))
|
||||
proposal = models.ForeignKey(
|
||||
ProposalBase,
|
||||
related_name="notifications",
|
||||
verbose_name=_("Proposal"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
template = models.ForeignKey(
|
||||
NotificationTemplate,
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name=_("Template")
|
||||
)
|
||||
timestamp = models.DateTimeField(default=datetime.now, verbose_name=_("Timestamp"))
|
||||
to_address = models.EmailField(verbose_name=_("To address"))
|
||||
from_address = models.EmailField(verbose_name=_("From address"))
|
||||
|
|
|
@ -6,7 +6,7 @@ from symposion.reviews.models import ReviewAssignment
|
|||
register = template.Library()
|
||||
|
||||
|
||||
@register.assignment_tag(takes_context=True)
|
||||
@register.simple_tag(takes_context=True)
|
||||
def review_assignments(context):
|
||||
request = context["request"]
|
||||
assignments = ReviewAssignment.objects.filter(user=request.user)
|
||||
|
|
3
vendor/symposion/reviews/views.py
vendored
3
vendor/symposion/reviews/views.py
vendored
|
@ -268,6 +268,8 @@ def review_list(request, section_slug, user_pk):
|
|||
if not request.user.pk == user_pk:
|
||||
return access_not_permitted(request)
|
||||
|
||||
section = get_object_or_404(ProposalSection, section__slug=section_slug)
|
||||
|
||||
queryset = ProposalBase.objects.select_related("speaker__user", "result")
|
||||
reviewed = LatestVote.objects.filter(user__pk=user_pk).values_list("proposal", flat=True)
|
||||
queryset = queryset.filter(kind__section__slug=section_slug)
|
||||
|
@ -280,6 +282,7 @@ def review_list(request, section_slug, user_pk):
|
|||
|
||||
ctx = {
|
||||
"proposals": proposals,
|
||||
"section": section,
|
||||
}
|
||||
return render(request, "symposion/reviews/review_list.html", ctx)
|
||||
|
||||
|
|
2
vendor/symposion/schedule/forms.py
vendored
2
vendor/symposion/schedule/forms.py
vendored
|
@ -73,6 +73,8 @@ class ScheduleSectionForm(forms.Form):
|
|||
if 'encoding' in kwargs:
|
||||
self.encoding = kwargs['encoding']
|
||||
kwargs.pop('encoding')
|
||||
else:
|
||||
self.encoding = "utf-8"
|
||||
super(ScheduleSectionForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean_filename(self):
|
||||
|
|
105
vendor/symposion/schedule/models.py
vendored
105
vendor/symposion/schedule/models.py
vendored
|
@ -1,7 +1,7 @@
|
|||
import datetime
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -11,11 +11,17 @@ from symposion.proposals.models import ProposalBase
|
|||
from symposion.conference.models import Section
|
||||
from symposion.speakers.models import Speaker
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Schedule(models.Model):
|
||||
objects = DefaultSelectRelatedManager()
|
||||
|
||||
section = models.OneToOneField(Section, verbose_name=_("Section"))
|
||||
section = models.OneToOneField(
|
||||
Section,
|
||||
verbose_name=_("Section"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
published = models.BooleanField(default=True, verbose_name=_("Published"))
|
||||
hidden = models.BooleanField(_("Hide schedule from overall conference view"), default=False)
|
||||
|
||||
|
@ -35,7 +41,11 @@ class Day(models.Model):
|
|||
objects = DefaultSelectRelatedManager()
|
||||
|
||||
|
||||
schedule = models.ForeignKey(Schedule, verbose_name=_("Schedule"))
|
||||
schedule = models.ForeignKey(
|
||||
Schedule,
|
||||
verbose_name=_("Schedule"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
date = models.DateField(verbose_name=_("Date"))
|
||||
|
||||
def __str__(self):
|
||||
|
@ -53,7 +63,11 @@ class Day(models.Model):
|
|||
|
||||
class Room(models.Model):
|
||||
|
||||
schedule = models.ForeignKey(Schedule, verbose_name=_("Schedule"))
|
||||
schedule = models.ForeignKey(
|
||||
Schedule,
|
||||
verbose_name=_("Schedule"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
name = models.CharField(max_length=65, verbose_name=_("Name"))
|
||||
order = models.PositiveIntegerField(verbose_name=_("Order"))
|
||||
|
||||
|
@ -70,8 +84,8 @@ class Room(models.Model):
|
|||
|
||||
class Track(models.Model):
|
||||
name = models.CharField(max_length=80, verbose_name=_("Track"))
|
||||
room = models.ForeignKey(Room)
|
||||
day = models.ForeignKey(Day)
|
||||
room = models.ForeignKey(Room, on_delete=models.CASCADE)
|
||||
day = models.ForeignKey(Day, on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -88,7 +102,11 @@ class SlotKind(models.Model):
|
|||
break, lunch, or X-minute talk.
|
||||
"""
|
||||
|
||||
schedule = models.ForeignKey(Schedule, verbose_name=_("schedule"))
|
||||
schedule = models.ForeignKey(
|
||||
Schedule,
|
||||
verbose_name=_("schedule"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
label = models.CharField(max_length=50, verbose_name=_("Label"))
|
||||
|
||||
def __str__(self):
|
||||
|
@ -103,8 +121,16 @@ class Slot(models.Model):
|
|||
objects = DefaultSelectRelatedManager()
|
||||
|
||||
name = models.CharField(max_length=512, editable=False)
|
||||
day = models.ForeignKey(Day, verbose_name=_("Day"))
|
||||
kind = models.ForeignKey(SlotKind, verbose_name=_("Kind"))
|
||||
day = models.ForeignKey(
|
||||
Day,
|
||||
verbose_name=_("Day"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
kind = models.ForeignKey(
|
||||
SlotKind,
|
||||
verbose_name=_("Kind"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
start = models.TimeField(verbose_name=_("Start"))
|
||||
end = models.TimeField(verbose_name=_("End"))
|
||||
exclusive = models.BooleanField(
|
||||
|
@ -194,8 +220,16 @@ class SlotRoom(models.Model):
|
|||
Links a slot with a room.
|
||||
"""
|
||||
|
||||
slot = models.ForeignKey(Slot, verbose_name=_("Slot"))
|
||||
room = models.ForeignKey(Room, verbose_name=_("Room"))
|
||||
slot = models.ForeignKey(
|
||||
Slot,
|
||||
verbose_name=_("Slot"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
room = models.ForeignKey(
|
||||
Room,
|
||||
verbose_name=_("Room"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.room, self.slot)
|
||||
|
@ -210,11 +244,23 @@ class SlotRoom(models.Model):
|
|||
class Presentation(models.Model):
|
||||
objects = DefaultSelectRelatedManager()
|
||||
|
||||
slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr", verbose_name=_("Slot"))
|
||||
slot = models.OneToOneField(
|
||||
Slot,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="content_ptr",
|
||||
verbose_name=_("Slot"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
title = models.CharField(max_length=100, verbose_name=_("Title"))
|
||||
abstract = models.TextField(verbose_name=_("Abstract"))
|
||||
abstract_html = models.TextField(blank=True)
|
||||
speaker = models.ForeignKey(Speaker, related_name="presentations", verbose_name=_("Speaker"))
|
||||
speaker = models.ForeignKey(
|
||||
Speaker,
|
||||
related_name="presentations",
|
||||
verbose_name=_("Speaker"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
additional_speakers = models.ManyToManyField(Speaker, related_name="copresentations",
|
||||
blank=True, verbose_name=_("Additional speakers"))
|
||||
unpublish = models.BooleanField(
|
||||
|
@ -222,8 +268,18 @@ class Presentation(models.Model):
|
|||
verbose_name=_("Do not publish"),
|
||||
)
|
||||
cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled"))
|
||||
proposal_base = models.OneToOneField(ProposalBase, related_name="presentation", verbose_name=_("Proposal base"))
|
||||
section = models.ForeignKey(Section, related_name="presentations", verbose_name=_("Section"))
|
||||
proposal_base = models.OneToOneField(
|
||||
ProposalBase,
|
||||
related_name="presentation",
|
||||
verbose_name=_("Proposal base"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
section = models.ForeignKey(
|
||||
Section,
|
||||
related_name="presentations",
|
||||
verbose_name=_("Section"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.abstract_html = parse(self.abstract)
|
||||
|
@ -256,7 +312,12 @@ class Presentation(models.Model):
|
|||
|
||||
class Session(models.Model):
|
||||
|
||||
day = models.ForeignKey(Day, related_name="sessions", verbose_name=_("Day"))
|
||||
day = models.ForeignKey(
|
||||
Day,
|
||||
related_name="sessions",
|
||||
verbose_name=_("Day"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
slots = models.ManyToManyField(Slot, related_name="sessions", verbose_name=_("Slots"))
|
||||
|
||||
def sorted_slots(self):
|
||||
|
@ -318,8 +379,16 @@ class SessionRole(models.Model):
|
|||
(SESSION_ROLE_RUNNER, _("Session Runner")),
|
||||
]
|
||||
|
||||
session = models.ForeignKey(Session, verbose_name=_("Session"))
|
||||
user = models.ForeignKey(User, verbose_name=_("User"))
|
||||
session = models.ForeignKey(
|
||||
Session,
|
||||
verbose_name=_("Session"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
role = models.IntegerField(choices=SESSION_ROLE_TYPES, verbose_name=_("Role"))
|
||||
status = models.NullBooleanField(verbose_name=_("Status"))
|
||||
|
||||
|
|
12
vendor/symposion/schedule/tests/factories.py
vendored
12
vendor/symposion/schedule/tests/factories.py
vendored
|
@ -9,7 +9,7 @@ from symposion.schedule.models import Schedule, Day, Slot, SlotKind
|
|||
from symposion.conference.models import Section, Conference
|
||||
|
||||
|
||||
class ConferenceFactory(factory.DjangoModelFactory):
|
||||
class ConferenceFactory(factory.django.DjangoModelFactory):
|
||||
title = fuzzy.FuzzyText()
|
||||
start_date = fuzzy.FuzzyDate(datetime.date(2014, 1, 1))
|
||||
end_date = fuzzy.FuzzyDate(
|
||||
|
@ -21,7 +21,7 @@ class ConferenceFactory(factory.DjangoModelFactory):
|
|||
model = Conference
|
||||
|
||||
|
||||
class SectionFactory(factory.DjangoModelFactory):
|
||||
class SectionFactory(factory.django.DjangoModelFactory):
|
||||
conference = factory.SubFactory(ConferenceFactory)
|
||||
name = fuzzy.FuzzyText()
|
||||
slug = fuzzy.FuzzyText()
|
||||
|
@ -30,7 +30,7 @@ class SectionFactory(factory.DjangoModelFactory):
|
|||
model = Section
|
||||
|
||||
|
||||
class ScheduleFactory(factory.DjangoModelFactory):
|
||||
class ScheduleFactory(factory.django.DjangoModelFactory):
|
||||
section = factory.SubFactory(SectionFactory)
|
||||
published = True
|
||||
hidden = False
|
||||
|
@ -39,7 +39,7 @@ class ScheduleFactory(factory.DjangoModelFactory):
|
|||
model = Schedule
|
||||
|
||||
|
||||
class SlotKindFactory(factory.DjangoModelFactory):
|
||||
class SlotKindFactory(factory.django.DjangoModelFactory):
|
||||
schedule = factory.SubFactory(ScheduleFactory)
|
||||
label = fuzzy.FuzzyText()
|
||||
|
||||
|
@ -47,7 +47,7 @@ class SlotKindFactory(factory.DjangoModelFactory):
|
|||
model = SlotKind
|
||||
|
||||
|
||||
class DayFactory(factory.DjangoModelFactory):
|
||||
class DayFactory(factory.django.DjangoModelFactory):
|
||||
schedule = factory.SubFactory(ScheduleFactory)
|
||||
date = fuzzy.FuzzyDate(datetime.date(2014, 1, 1))
|
||||
|
||||
|
@ -55,7 +55,7 @@ class DayFactory(factory.DjangoModelFactory):
|
|||
model = Day
|
||||
|
||||
|
||||
class SlotFactory(factory.DjangoModelFactory):
|
||||
class SlotFactory(factory.django.DjangoModelFactory):
|
||||
day = factory.SubFactory(DayFactory)
|
||||
kind = factory.SubFactory(SlotKindFactory)
|
||||
start = datetime.time(random.randint(0, 23), random.randint(0, 59))
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
from datetime import date
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.urls import reverse
|
||||
from django.test import TestCase
|
||||
|
||||
from symposion.conference.models import Section, current_conference, Conference
|
||||
from symposion.schedule.models import Day, Schedule, Session
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class TestScheduleViews(TestCase):
|
||||
username = "user@example.com"
|
||||
|
|
12
vendor/symposion/schedule/views.py
vendored
12
vendor/symposion/schedule/views.py
vendored
|
@ -1,13 +1,13 @@
|
|||
import json
|
||||
import pytz
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.template import loader, Context
|
||||
from django.conf import settings
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib import messages
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
|
@ -21,6 +21,8 @@ from symposion.schedule.timetable import TimeTable
|
|||
from symposion.conference.models import Conference
|
||||
from pinaxcon.templatetags.lca2018_tags import speaker_photo
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def fetch_schedule(slug):
|
||||
qs = Schedule.objects.all()
|
||||
|
@ -369,7 +371,7 @@ def session_detail(request, session_id):
|
|||
if chairs:
|
||||
chair = chairs[0].user
|
||||
else:
|
||||
if request.user.is_authenticated():
|
||||
if request.user.is_authenticated:
|
||||
# did the current user previously try to apply and got rejected?
|
||||
if SessionRole.objects.filter(session=session, user=request.user, role=SessionRole.SESSION_ROLE_CHAIR, status=False):
|
||||
chair_denied = True
|
||||
|
@ -380,12 +382,12 @@ def session_detail(request, session_id):
|
|||
if runners:
|
||||
runner = runners[0].user
|
||||
else:
|
||||
if request.user.is_authenticated():
|
||||
if request.user.is_authenticated:
|
||||
# did the current user previously try to apply and got rejected?
|
||||
if SessionRole.objects.filter(session=session, user=request.user, role=SessionRole.SESSION_ROLE_RUNNER, status=False):
|
||||
runner_denied = True
|
||||
|
||||
if request.method == "POST" and request.user.is_authenticated():
|
||||
if request.method == "POST" and request.user.is_authenticated:
|
||||
if not hasattr(request.user, "attendee") or not request.user.attendee.completed_registration:
|
||||
response = redirect("guided_registration")
|
||||
response["Location"] += "?next=%s" % request.path
|
||||
|
|
14
vendor/symposion/speakers/models.py
vendored
14
vendor/symposion/speakers/models.py
vendored
|
@ -1,18 +1,26 @@
|
|||
import datetime
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from symposion import constants
|
||||
from symposion.text_parser import parse
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Speaker(models.Model):
|
||||
|
||||
user = models.OneToOneField(User, null=True, related_name="speaker_profile", verbose_name=_("User"))
|
||||
user = models.OneToOneField(
|
||||
User,
|
||||
null=True,
|
||||
related_name="speaker_profile",
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
name = models.CharField(verbose_name=_("Name"), max_length=100,
|
||||
help_text=_("As you would like it to appear in the"
|
||||
" conference programme."))
|
||||
|
|
4
vendor/symposion/speakers/views.py
vendored
4
vendor/symposion/speakers/views.py
vendored
|
@ -4,13 +4,15 @@ from django.shortcuts import render, redirect, get_object_or_404
|
|||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from symposion.proposals.models import ProposalBase
|
||||
from symposion.speakers.forms import SpeakerForm
|
||||
from symposion.speakers.models import Speaker
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@login_required
|
||||
def speaker_create(request):
|
||||
|
|
66
vendor/symposion/sponsorship/models.py
vendored
66
vendor/symposion/sponsorship/models.py
vendored
|
@ -2,16 +2,18 @@ import datetime
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_init, post_save
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from symposion.conference.models import Conference
|
||||
from symposion.sponsorship.managers import SponsorManager
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
# The benefits we track as individual fields on sponsors
|
||||
# Names are the names in the database as defined by organizers.
|
||||
|
@ -44,7 +46,11 @@ BENEFITS = [
|
|||
|
||||
class SponsorLevel(models.Model):
|
||||
|
||||
conference = models.ForeignKey(Conference, verbose_name=_("Conference"))
|
||||
conference = models.ForeignKey(
|
||||
Conference,
|
||||
verbose_name=_("Conference"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
name = models.CharField(_("Name"), max_length=100)
|
||||
order = models.IntegerField(_("Order"), default=0)
|
||||
cost = models.PositiveIntegerField(_("Cost"))
|
||||
|
@ -64,8 +70,13 @@ class SponsorLevel(models.Model):
|
|||
|
||||
class Sponsor(models.Model):
|
||||
|
||||
applicant = models.ForeignKey(User, related_name="sponsorships", verbose_name=_("Applicant"),
|
||||
null=True)
|
||||
applicant = models.ForeignKey(
|
||||
User,
|
||||
related_name="sponsorships",
|
||||
verbose_name=_("Applicant"),
|
||||
null=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
name = models.CharField(_("Sponsor Name"), max_length=100)
|
||||
display_url = models.URLField(_("display URL"), blank=True)
|
||||
|
@ -73,13 +84,24 @@ class Sponsor(models.Model):
|
|||
annotation = models.TextField(_("Annotation"), blank=True)
|
||||
contact_name = models.CharField(_("Contact Name"), max_length=100)
|
||||
contact_email = models.EmailField(_("Contact Email"))
|
||||
level = models.ForeignKey(SponsorLevel, verbose_name=_("level"))
|
||||
level = models.ForeignKey(
|
||||
SponsorLevel,
|
||||
verbose_name=_("level"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
added = models.DateTimeField(_("added"), default=datetime.datetime.now)
|
||||
active = models.BooleanField(_("active"), default=False)
|
||||
|
||||
# Denormalization (this assumes only one logo)
|
||||
sponsor_logo = models.ForeignKey("SponsorBenefit", related_name="+", null=True, blank=True,
|
||||
editable=False, verbose_name=_("Sponsor logo"))
|
||||
sponsor_logo = models.ForeignKey(
|
||||
"SponsorBenefit",
|
||||
related_name="+",
|
||||
null=True,
|
||||
blank=True,
|
||||
editable=False,
|
||||
verbose_name=_("Sponsor logo"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
# Whether things are complete
|
||||
# True = complete, False = incomplate, Null = n/a for this sponsor level
|
||||
|
@ -242,8 +264,18 @@ class Benefit(models.Model):
|
|||
|
||||
class BenefitLevel(models.Model):
|
||||
|
||||
benefit = models.ForeignKey(Benefit, related_name="benefit_levels", verbose_name=_("Benefit"))
|
||||
level = models.ForeignKey(SponsorLevel, related_name="benefit_levels", verbose_name=_("Level"))
|
||||
benefit = models.ForeignKey(
|
||||
Benefit,
|
||||
related_name="benefit_levels",
|
||||
verbose_name=_("Benefit"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
level = models.ForeignKey(
|
||||
SponsorLevel,
|
||||
related_name="benefit_levels",
|
||||
verbose_name=_("Level"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
# default limits for this benefit at given level
|
||||
max_words = models.PositiveIntegerField(_("Max words"), blank=True, null=True)
|
||||
|
@ -260,8 +292,18 @@ class BenefitLevel(models.Model):
|
|||
|
||||
class SponsorBenefit(models.Model):
|
||||
|
||||
sponsor = models.ForeignKey(Sponsor, related_name="sponsor_benefits", verbose_name=_("Sponsor"))
|
||||
benefit = models.ForeignKey(Benefit, related_name="sponsor_benefits", verbose_name=_("Benefit"))
|
||||
sponsor = models.ForeignKey(
|
||||
Sponsor,
|
||||
related_name="sponsor_benefits",
|
||||
verbose_name=_("Sponsor"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
benefit = models.ForeignKey(
|
||||
Benefit,
|
||||
related_name="sponsor_benefits",
|
||||
verbose_name=_("Benefit"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
||||
|
||||
# Limits: will initially be set to defaults from corresponding BenefitLevel
|
||||
|
|
8
vendor/symposion/sponsorship/tests.py
vendored
8
vendor/symposion/sponsorship/tests.py
vendored
|
@ -1,20 +1,22 @@
|
|||
from cStringIO import StringIO
|
||||
from io import StringIO
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from zipfile import ZipFile
|
||||
|
||||
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 ValidationError
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
from pycon.sponsorship.models import Benefit, Sponsor, SponsorBenefit,\
|
||||
SponsorLevel
|
||||
from symposion.conference.models import current_conference
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class TestSponsorZipDownload(TestCase):
|
||||
def setUp(self):
|
||||
|
|
4
vendor/symposion/teams/backends.py
vendored
4
vendor/symposion/teams/backends.py
vendored
|
@ -5,7 +5,7 @@ from .models import Team
|
|||
|
||||
class TeamPermissionsBackend(object):
|
||||
|
||||
def authenticate(self, username=None, password=None):
|
||||
def authenticate(self, request, username=None, password=None):
|
||||
return None
|
||||
|
||||
def get_team_permissions(self, user_obj, obj=None):
|
||||
|
@ -13,7 +13,7 @@ class TeamPermissionsBackend(object):
|
|||
Returns a set of permission strings that this user has through his/her
|
||||
team memberships.
|
||||
"""
|
||||
if user_obj.is_anonymous() or obj is not None:
|
||||
if user_obj.is_anonymous or obj is not None:
|
||||
return set()
|
||||
if not hasattr(user_obj, "_team_perm_cache"):
|
||||
# Member permissions
|
||||
|
|
4
vendor/symposion/teams/forms.py
vendored
4
vendor/symposion/teams/forms.py
vendored
|
@ -4,10 +4,12 @@ from django.utils.html import escape
|
|||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from symposion.teams.models import Membership
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class TeamInvitationForm(forms.Form):
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from django.db import models, migrations
|
||||
import datetime
|
||||
from django.conf import settings
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -44,11 +45,11 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='membership',
|
||||
name='team',
|
||||
field=models.ForeignKey(verbose_name='Team', to='teams.Team', related_name='memberships'),
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, verbose_name='Team', to='teams.Team', related_name='memberships'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='membership',
|
||||
name='user',
|
||||
field=models.ForeignKey(verbose_name='User', to=settings.AUTH_USER_MODEL, related_name='memberships'),
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, verbose_name='User', to=settings.AUTH_USER_MODEL, related_name='memberships'),
|
||||
),
|
||||
]
|
||||
|
|
25
vendor/symposion/teams/models.py
vendored
25
vendor/symposion/teams/models.py
vendored
|
@ -2,11 +2,15 @@ import datetime
|
|||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.urls import reverse
|
||||
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from reversion import revisions as reversion
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
TEAM_ACCESS_CHOICES = [
|
||||
("open", _("open")),
|
||||
|
@ -36,9 +40,8 @@ class Team(models.Model):
|
|||
created = models.DateTimeField(default=datetime.datetime.now,
|
||||
editable=False, verbose_name=_("Created"))
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self):
|
||||
return ("team_detail", [self.slug])
|
||||
return reverse("team_detail", args=[self.slug])
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -78,10 +81,18 @@ MEMBERSHIP_STATE_CHOICES = [
|
|||
|
||||
class Membership(models.Model):
|
||||
|
||||
user = models.ForeignKey(User, related_name="memberships",
|
||||
verbose_name=_("User"))
|
||||
team = models.ForeignKey(Team, related_name="memberships",
|
||||
verbose_name=_("Team"))
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
related_name="memberships",
|
||||
verbose_name=_("User"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
team = models.ForeignKey(
|
||||
Team,
|
||||
related_name="memberships",
|
||||
verbose_name=_("Team"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
state = models.CharField(max_length=20, choices=MEMBERSHIP_STATE_CHOICES,
|
||||
verbose_name=_("State"))
|
||||
message = models.TextField(blank=True, verbose_name=_("Message"))
|
||||
|
|
2
vendor/symposion/utils/mail.py
vendored
2
vendor/symposion/utils/mail.py
vendored
|
@ -9,7 +9,7 @@ from django.contrib.sites.models import Site
|
|||
|
||||
|
||||
class Sender(object):
|
||||
''' Class for sending e-mails under a templete prefix. '''
|
||||
''' Class for sending e-mails under a template prefix. '''
|
||||
|
||||
def __init__(self, template_prefix):
|
||||
self.template_prefix = template_prefix
|
||||
|
|
Loading…
Reference in a new issue