Merge branch 'django-and-channels-upgrade'
This commit is contained in:
commit
870d1c9d67
|
@ -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'),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
])
|
||||
)
|
||||
})
|
||||
|
|
|
@ -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/$',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
3
src/requirements/dev.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
-r production.txt
|
||||
|
||||
django-debug-toolbar==1.9.1
|
|
@ -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
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from django.conf.urls import url
|
||||
from .views import *
|
||||
|
||||
app_name = 'shop'
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', ShopIndexView.as_view(), name='index'),
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from django.conf.urls import url, include
|
||||
from .views import *
|
||||
|
||||
|
||||
app_name = 'teams'
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^$',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -6,6 +6,8 @@ from .views import (
|
|||
ShopTicketDetailView
|
||||
)
|
||||
|
||||
app_name = 'tickets'
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^$',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue