Merge branch 'django-and-channels-upgrade'

This commit is contained in:
Thomas Steen Rasmussen 2018-04-14 15:42:39 +02:00
commit 870d1c9d67
26 changed files with 117 additions and 60 deletions

View file

@ -1,6 +1,9 @@
from django.conf.urls import url
from .views import *
app_name = 'backoffice'
urlpatterns = [
url(r'^$', BackofficeIndexView.as_view(), name='index'),
url(r'product_handout/$', ProductHandoutView.as_view(), name='product_handout'),

View file

@ -24,11 +24,12 @@ WKHTMLTOPDF_CMD="{{ wkhtmltopdf_path }}"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "{{ django_channels_backend }}",
"ROUTING": "bornhack.routing.channel_routing",
"CONFIG": {{ django_channels_config }}
},
}
ASGI_APPLICATION = "bornhack.routing.application"
# start redirecting to the next camp instead of the previous camp after
# this much of the time between the camps has passed
CAMP_REDIRECT_PERCENT=25

View file

@ -1,8 +1,14 @@
from django.conf.urls import url
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from program.consumers import ScheduleConsumer
channel_routing = [
ScheduleConsumer.as_route(path=r"^/schedule/"),
]
application = ProtocolTypeRouter({
"websocket": AuthMiddlewareStack(
URLRouter([
url(r"^schedule/", ScheduleConsumer)
])
)
})

View file

@ -62,7 +62,7 @@ urlpatterns = [
name='general-terms'
),
url(r'^accounts/', include('allauth.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^admin/', admin.site.urls),
url(
r'^camps/$',

View file

@ -35,7 +35,7 @@ class Migration(migrations.Migration):
('updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)),
('date', models.DateField(help_text='What date?', verbose_name='Date')),
('camp', models.ForeignKey(to='camps.Camp', help_text='Which camp does this day belong to.', verbose_name='Camp')),
('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='Which camp does this day belong to.', verbose_name='Camp')),
],
options={
'verbose_name_plural': 'Days',
@ -51,8 +51,8 @@ class Migration(migrations.Migration):
('description', models.CharField(max_length=255, help_text='What this expense covers.', verbose_name='Description')),
('amount', models.DecimalField(max_digits=7, help_text='The amount of the expense.', verbose_name='Amount', decimal_places=2)),
('currency', models.CharField(max_length=3, choices=[('btc', 'BTC'), ('dkk', 'DKK'), ('eur', 'EUR'), ('sek', 'SEK')], help_text='What currency the amount is in.', verbose_name='Currency')),
('camp', models.ForeignKey(to='camps.Camp', help_text='The camp to which this expense relates to.', verbose_name='Camp')),
('covered_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, blank=True, help_text='Which user, if any, covered this expense.', verbose_name='Covered by', null=True)),
('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='The camp to which this expense relates to.', verbose_name='Camp')),
('covered_by', models.ForeignKey(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, blank=True, help_text='Which user, if any, covered this expense.', verbose_name='Covered by', null=True)),
],
options={
'verbose_name_plural': 'Expenses',
@ -67,8 +67,8 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)),
('cost', models.DecimalField(default=1500.0, decimal_places=2, help_text='What the user should/is willing to pay for this signup.', verbose_name='Cost', max_digits=7)),
('paid', models.BooleanField(help_text='Whether the user has paid.', verbose_name='Paid?', default=False)),
('camp', models.ForeignKey(to='camps.Camp', help_text='The camp that has been signed up for.', verbose_name='Camp')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, help_text='The user that has signed up.', verbose_name='User')),
('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='The camp that has been signed up for.', verbose_name='Camp')),
('user', models.ForeignKey(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, help_text='The user that has signed up.', verbose_name='User')),
],
options={
'verbose_name_plural': 'Signups',

View file

@ -1,7 +1,7 @@
from django.conf.urls import url
from . import views
app_name = 'news'
urlpatterns = [
url(r'^$', views.NewsIndex.as_view(), kwargs={'archived': False}, name='index'),
url(r'^archive/$', views.NewsIndex.as_view(), kwargs={'archived': True}, name='archive'),

View file

@ -19,7 +19,7 @@ class Migration(migrations.Migration):
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(serialize=False, editable=False, primary_key=True, default=uuid.uuid4)),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, help_text='The django user this profile belongs to.', verbose_name='User')),
('user', models.OneToOneField(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, help_text='The django user this profile belongs to.', verbose_name='User')),
],
options={
'verbose_name_plural': 'Profiles',

View file

@ -19,6 +19,7 @@ class Profile(CreatedUpdatedModel, UUIDModel):
User,
verbose_name=_('User'),
help_text=_('The django user this profile belongs to.'),
on_delete=models.PROTECT
)
name = models.CharField(

View file

@ -2,6 +2,8 @@ from django.conf.urls import url
from .views import ProfileDetail, ProfileUpdate
app_name = 'profiles'
urlpatterns = [
url(r'^$', ProfileDetail.as_view(), name='detail'),
url(r'^edit$', ProfileUpdate.as_view(), name='update'),

View file

@ -1,6 +1,6 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import DetailView, UpdateView
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.contrib import messages
from . import models

View file

@ -1,4 +1,4 @@
from channels.generic.websockets import JsonWebsocketConsumer
from channels.generic.websocket import JsonWebsocketConsumer
from camps.models import Camp
from .models import (
@ -12,13 +12,11 @@ from .models import (
class ScheduleConsumer(JsonWebsocketConsumer):
http_user = True
groups = ['schedule_users']
def connection_groups(self, **kwargs):
return ['schedule_users']
def raw_receive(self, message, **kwargs):
content = self.decode_json(message['text'])
def receive(self, text_data, **kwargs):
user = self.scope['user']
content = self.decode_json(text_data)
action = content.get('action')
data = {}
@ -39,14 +37,27 @@ class ScheduleConsumer(JsonWebsocketConsumer):
events_query_set = Event.objects.filter(camp=camp)
events = list([x.serialize() for x in events_query_set])
event_instances_query_set = EventInstance.objects.filter(event__camp=camp)
event_instances = list([x.serialize(user=message.user) for x in event_instances_query_set])
event_instances_query_set = EventInstance.objects.filter(
event__camp=camp
)
event_instances = list([
x.serialize(user=user)
for x in event_instances_query_set
])
event_locations_query_set = EventLocation.objects.filter(camp=camp)
event_locations = list([x.serialize() for x in event_locations_query_set])
event_locations_query_set = EventLocation.objects.filter(
camp=camp
)
event_locations = list([
x.serialize()
for x in event_locations_query_set
])
event_types_query_set = EventType.objects.filter()
event_types = list([x.serialize() for x in event_types_query_set])
event_types = list([
x.serialize()
for x in event_types_query_set
])
speakers_query_set = Speaker.objects.filter(camp=camp)
speakers = list([x.serialize() for x in speakers_query_set])
@ -67,18 +78,21 @@ class ScheduleConsumer(JsonWebsocketConsumer):
event_instance_id = content.get('event_instance_id')
event_instance = EventInstance.objects.get(id=event_instance_id)
Favorite.objects.create(
user=message.user,
user=user,
event_instance=event_instance
)
if action == 'unfavorite':
event_instance_id = content.get('event_instance_id')
event_instance = EventInstance.objects.get(id=event_instance_id)
favorite = Favorite.objects.get(event_instance=event_instance, user=message.user)
favorite = Favorite.objects.get(
event_instance=event_instance,
user=user
)
favorite.delete()
if data:
self.send(data)
self.send_json(data)
def disconnect(self, message, **kwargs):
pass

View file

@ -11,7 +11,7 @@ from django.db import models
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.text import slugify
from django.conf import settings
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.core.files.storage import FileSystemStorage
from django.urls import reverse
from django.apps import apps
@ -75,6 +75,7 @@ class UserSubmittedModel(CampRelatedModel):
user = models.ForeignKey(
'auth.User',
on_delete=models.PROTECT
)
PROPOSAL_DRAFT = 'draft'
@ -148,7 +149,8 @@ class SpeakerProposal(UserSubmittedModel):
camp = models.ForeignKey(
'camps.Camp',
related_name='speakerproposals'
related_name='speakerproposals',
on_delete=models.PROTECT
)
name = models.CharField(
@ -216,7 +218,8 @@ class EventProposal(UserSubmittedModel):
camp = models.ForeignKey(
'camps.Camp',
related_name='eventproposals'
related_name='eventproposals',
on_delete=models.PROTECT
)
title = models.CharField(
@ -231,6 +234,7 @@ class EventProposal(UserSubmittedModel):
event_type = models.ForeignKey(
'program.EventType',
help_text='The type of event',
on_delete=models.PROTECT
)
speakers = models.ManyToManyField(
@ -300,7 +304,8 @@ class EventLocation(CampRelatedModel):
camp = models.ForeignKey(
'camps.Camp',
related_name='eventlocations'
related_name='eventlocations',
on_delete=models.PROTECT
)
def __str__(self):
@ -379,6 +384,7 @@ class Event(CampRelatedModel):
event_type = models.ForeignKey(
'program.EventType',
help_text='The type of this event',
on_delete=models.PROTECT
)
slug = models.SlugField(
@ -391,6 +397,7 @@ class Event(CampRelatedModel):
'camps.Camp',
related_name='events',
help_text='The camp this event belongs to',
on_delete=models.PROTECT
)
video_url = models.URLField(
@ -410,6 +417,7 @@ class Event(CampRelatedModel):
null=True,
blank=True,
help_text='The event proposal object this event was created from',
on_delete=models.PROTECT
)
class Meta:
@ -463,7 +471,8 @@ class EventInstance(CampRelatedModel):
event = models.ForeignKey(
'program.event',
related_name='instances'
related_name='instances',
on_delete=models.PROTECT
)
when = DateTimeRangeField()
@ -474,7 +483,8 @@ class EventInstance(CampRelatedModel):
location = models.ForeignKey(
'program.EventLocation',
related_name='eventinstances'
related_name='eventinstances',
on_delete=models.PROTECT
)
class Meta:
@ -600,6 +610,7 @@ class Speaker(CampRelatedModel):
null=True,
related_name='speakers',
help_text='The camp this speaker belongs to',
on_delete=models.PROTECT
)
events = models.ManyToManyField(
@ -614,6 +625,7 @@ class Speaker(CampRelatedModel):
null=True,
blank=True,
help_text='The speaker proposal object this speaker was created from',
on_delete=models.PROTECT
)
class Meta:
@ -660,7 +672,10 @@ class Favorite(models.Model):
related_name='favorites',
on_delete=models.PROTECT
)
event_instance = models.ForeignKey('program.EventInstance')
event_instance = models.ForeignKey(
'program.EventInstance',
on_delete=models.PROTECT
)
class Meta:
unique_together = ['user', 'event_instance']

3
src/requirements/dev.txt Normal file
View file

@ -0,0 +1,3 @@
-r production.txt
django-debug-toolbar==1.9.1

View file

@ -1,26 +1,19 @@
Django==2.0.4
channels==2.0.2
channels_redis=2.1.1
CommonMark==0.7.3
Django==1.10.5
Pillow==4.0.0
PyPDF2==1.26.0
Unidecode==0.04.20
argparse==1.2.1
asgi-redis==1.3.0
asyncio==3.4.3
bleach==1.5.0
# fix https://github.com/django/daphne/pull/107
git+https://github.com/tykling/daphne@ws-x-forwarded-for-bugfix
# fix https://github.com/django/channels/issues/622
#channels==1.1.3
git+https://github.com/tykling/channels@master
defusedxml==0.4.1
django-allauth==0.30.0
django-bleach==0.3.0
django-bootstrap3==8.2.2
django-debug-toolbar==1.6
django-channels-panel==0.0.5
django-extensions==1.7.7
django-wkhtmltopdf==3.1.0
docopt==0.6.2

View file

@ -1,5 +1,5 @@
def current_order(request):
if request.user.is_authenticated():
if request.user.is_authenticated:
order = None
orders = request.user.orders.filter(open__isnull=False)

View file

@ -8,7 +8,7 @@ from django.contrib.postgres.fields import DateTimeRangeField, JSONField
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.core.exceptions import ValidationError
from decimal import Decimal
from datetime import timedelta
@ -376,7 +376,7 @@ class EpayPayment(CreatedUpdatedModel, UUIDModel):
verbose_name = 'Epay Payment'
verbose_name_plural = 'Epay Payments'
order = models.OneToOneField('shop.Order')
order = models.OneToOneField('shop.Order', on_delete=models.PROTECT)
callback = models.ForeignKey('shop.EpayCallback', on_delete=models.PROTECT)
txnid = models.IntegerField()
@ -469,8 +469,18 @@ class CreditNote(CreatedUpdatedModel):
class Invoice(CreatedUpdatedModel):
order = models.OneToOneField('shop.Order', null=True, blank=True)
customorder = models.OneToOneField('shop.CustomOrder', null=True, blank=True)
order = models.OneToOneField(
'shop.Order',
null=True,
blank=True,
on_delete=models.PROTECT
)
customorder = models.OneToOneField(
'shop.CustomOrder',
null=True,
blank=True,
on_delete=models.PROTECT
)
pdf = models.FileField(null=True, blank=True, upload_to='invoices/')
sent_to_customer = models.BooleanField(default=False)

View file

@ -1,6 +1,8 @@
from django.conf.urls import url
from .views import *
app_name = 'shop'
urlpatterns = [
url(r'^$', ShopIndexView.as_view(), name='index'),

View file

@ -1,7 +1,7 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse, reverse_lazy
from django.urls import reverse, reverse_lazy
from django.db.models import Count, F
from django.http import (
HttpResponse,

View file

@ -5,7 +5,7 @@ from django.utils.text import slugify
from utils.models import CampRelatedModel
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.conf import settings
import logging
logger = logging.getLogger("bornhack.%s" % __name__)

View file

@ -1,6 +1,9 @@
from django.conf.urls import url, include
from .views import *
app_name = 'teams'
urlpatterns = [
url(
r'^$',

View file

@ -8,9 +8,8 @@ from django.shortcuts import redirect
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.views.generic.detail import SingleObjectMixin
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.conf import settings
from profiles.models import Profile
import logging

View file

@ -3,7 +3,7 @@ import hashlib
import base64
import qrcode
from django.conf import settings
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from utils.models import (
UUIDModel,

View file

@ -6,6 +6,8 @@ from .views import (
ShopTicketDetailView
)
app_name = 'tickets'
urlpatterns = [
url(
r'^$',

View file

@ -1,4 +1,4 @@
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.db import models
from django.utils.text import slugify
from utils.models import UUIDModel, CampRelatedModel

View file

@ -1,6 +1,9 @@
from django.conf.urls import url
from .views import *
app_name = 'villages'
urlpatterns = [
url(r'^$', VillageListView.as_view(), name='list'),
url(r'create/$', VillageCreateView.as_view(), name='create'),

View file

@ -1,6 +1,6 @@
from django.http import Http404
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.http import HttpResponseRedirect
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import SingleObjectMixin