fix merge conflic

This commit is contained in:
Thomas Steen Rasmussen 2016-08-08 07:37:24 +02:00
commit 7a887d8a86
24 changed files with 529 additions and 0 deletions

View file

@ -30,6 +30,7 @@ INSTALLED_APPS = [
'news', 'news',
'utils', 'utils',
'villages', 'villages',
'program',
'allauth', 'allauth',
'allauth.account', 'allauth.account',

View file

@ -119,3 +119,18 @@ footer {
align-items: center; align-items: center;
height: 200px; height: 200px;
} }
.event {
max-width: 200px;
height: 100px;
display: inline-block;
margin: 5px 5px;
padding: 5px;
flex: 1 1 auto;
}
.event:hover {
background-color: black !important;
color: white !important;
text-decoration: none;
}

View file

@ -78,6 +78,10 @@ urlpatterns = [
r'^villages/', r'^villages/',
include('villages.urls', namespace='villages') include('villages.urls', namespace='villages')
), ),
url(
r'^program/',
include('program.urls', namespace='program')
),
url(r'^accounts/', include('allauth.urls')), url(r'^accounts/', include('allauth.urls')),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
] ]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-04 17:05
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camps', '0005_auto_20160510_2011'),
]
operations = [
migrations.AlterModelOptions(
name='day',
options={'ordering': ['date'], 'verbose_name': 'Day', 'verbose_name_plural': 'Days'},
),
]

View file

@ -60,6 +60,7 @@ class Day(CreatedUpdatedModel, UUIDModel):
class Meta: class Meta:
verbose_name = _('Day') verbose_name = _('Day')
verbose_name_plural = _('Days') verbose_name_plural = _('Days')
ordering = ['date']
camp = models.ForeignKey( camp = models.ForeignKey(
'camps.Camp', 'camps.Camp',
@ -73,6 +74,12 @@ class Day(CreatedUpdatedModel, UUIDModel):
help_text=_('What date?') help_text=_('What date?')
) )
def __str__(self):
return '{} ({})'.format(
self.date.strftime('%A'),
self.date
)
class Expense(CreatedUpdatedModel, UUIDModel): class Expense(CreatedUpdatedModel, UUIDModel):
class Meta: class Meta:

0
program/__init__.py Normal file
View file

41
program/admin.py Normal file
View file

@ -0,0 +1,41 @@
from django.contrib import admin
from .models import Event, Speaker, EventType
@admin.register(EventType)
class EventTypeAdmin(admin.ModelAdmin):
pass
@admin.register(Speaker)
class SpeakerAdmin(admin.ModelAdmin):
pass
class SpeakerInline(admin.StackedInline):
model = Speaker.events.through
@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
list_display = [
'title',
'event_type',
'get_days',
'start',
'end',
]
def get_days(self, obj):
return ', '.join([
str(day.date.strftime('%a'))
for day in obj.days.all()
])
inlines = [
SpeakerInline
]

7
program/apps.py Normal file
View file

@ -0,0 +1,7 @@
from __future__ import unicode_literals
from django.apps import AppConfig
class ProgramConfig(AppConfig):
name = 'program'

View file

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-07-13 19:38
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('camps', '0005_auto_20160510_2011'),
]
operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('title', models.CharField(max_length=255)),
('description', models.TextField()),
('start', models.TimeField()),
('end', models.TimeField()),
('days', models.ManyToManyField(to='camps.Day')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='EventType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=100)),
('slug', models.SlugField()),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Speaker',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=150)),
('biography', models.TextField()),
('picture', models.ImageField(blank=True, null=True, upload_to=b'')),
('events', models.ManyToManyField(related_name='speakers', related_query_name='speaker', to='program.Event')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='event',
name='event_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='program.EventType'),
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-04 17:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('program', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='eventtype',
name='color',
field=models.CharField(default='#ff0000', max_length=50),
preserve_default=False,
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-04 17:11
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('program', '0002_eventtype_color'),
]
operations = [
migrations.AddField(
model_name='eventtype',
name='light_writing',
field=models.BooleanField(default=False),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-04 17:12
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('program', '0003_eventtype_light_writing'),
]
operations = [
migrations.RenameField(
model_name='eventtype',
old_name='light_writing',
new_name='light_text',
),
]

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-07 13:12
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('program', '0004_auto_20160804_1712'),
]
operations = [
migrations.AddField(
model_name='event',
name='slug',
field=models.SlugField(default='', blank=True),
preserve_default=False,
),
migrations.AlterField(
model_name='speaker',
name='events',
field=models.ManyToManyField(blank=True, related_name='speakers', related_query_name='speaker', to='program.Event'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-07 13:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('program', '0005_auto_20160807_1312'),
]
operations = [
migrations.AlterField(
model_name='event',
name='slug',
field=models.SlugField(blank=True, max_length=255),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-07 13:33
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('program', '0006_auto_20160807_1320'),
]
operations = [
migrations.RenameField(
model_name='event',
old_name='description',
new_name='abstract',
),
]

View file

52
program/models.py Normal file
View file

@ -0,0 +1,52 @@
from __future__ import unicode_literals
from django.db import models
from django.utils.text import slugify
from utils.models import CreatedUpdatedModel
class EventType(CreatedUpdatedModel):
""" Every event needs to have a type. """
name = models.CharField(max_length=100)
slug = models.SlugField()
color = models.CharField(max_length=50)
light_text = models.BooleanField(default=False)
def __str__(self):
return self.name
class Event(CreatedUpdatedModel):
""" Something that is on the program. """
title = models.CharField(max_length=255)
slug = models.SlugField(blank=True, max_length=255)
abstract = models.TextField()
event_type = models.ForeignKey(EventType)
days = models.ManyToManyField('camps.Day')
start = models.TimeField()
end = models.TimeField()
def __str__(self):
return self.title
def save(self, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Event, self).save(**kwargs)
class Speaker(CreatedUpdatedModel):
""" Person anchoring an event. """
name = models.CharField(max_length=150)
biography = models.TextField()
picture = models.ImageField(null=True, blank=True)
events = models.ManyToManyField(
Event,
related_name='speakers',
related_query_name='speaker',
blank=True,
)
def __str__(self):
return self.name

View file

@ -0,0 +1,23 @@
{% extends 'base.html' %}
{% block content %}
<a href="{% url 'program:index' %}" class="btn btn-default" style="display: inline-block; padding: 5px;">
Overview
</a>
{% for day in days %}
{% with day.date|date:"m" as month_padded %}
{% with day.date|date:"d" as day_padded %}
<a href="{% url 'program:day' year=day.date.year month=month_padded day=day_padded %}" class="btn btn-default" style="display: inline-block; padding: 5px;">
{{ day.date|date:"l" }}
</a>
{% endwith %}
{% endwith %}
{% endfor %}
<hr />
{% block program_content %}
{% endblock %}
{% endblock %}

View file

@ -0,0 +1,22 @@
{% extends 'program_base.html' %}
{% block program_content %}
{% for event in events %}
{% ifchanged event.event_type %}
{% if not forloop.first %}</div>{% endif %}
<h3>{{ event.event_type }}</h3>
<div style="display: flex; flex-wrap: wrap;">
{% endifchanged %}
<a class="event"
href="{% url 'program:event' slug=event.slug %}"
style="background-color: {{ event.event_type.color }}; border: 0; color: {% if event.event_type.light_text %}white{% else %}black{% endif %};">
<small>{{ event.start|date:"H:i" }} - {{ event.end|date:"H:i" }}</small>
<br />
{{ event }}
</a>
{% endfor %}
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends 'program_base.html' %}
{% load commonmark %}
{% block program_content %}
<h3>
<small style="background-color: {{ event.event_type.color }}; border: 0; color: {% if event.event_type.light_text %}white{% else %}black{% endif %}; display: inline-block; padding: 5px;">
{{ event.event_type.name }}
</small>
{{ event.title }}
</h3>
<h4>
{{ event.start|date:"H:i" }} - {{ event.end|date:"H:i" }} at
{% for day in event.days.all %}{{ day.date|date:"l" }}{% if not forloop.last %}, {% endif %}{% endfor %}<br />
</h4>
{{ event.abstract|commonmark }}
<hr />
{% if event.speakers.exists %}
{% for speaker in event.speakers.all %}
<h3>{{ speaker }}</h3>
{{ speaker.biography|commonmark }}
{% endfor %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends 'program_base.html' %}
{% block program_content %}
<a href="{% url 'program:index' %}" style="background-color: black; border: 0; color: white; display: inline-block; padding: 5px;">
All
</a>
{% for event_type in event_types %}
<a href="{% url 'program:index' %}?type={{ event_type.slug }}" style="background-color: {{ event_type.color }}; border: 0; color: {% if event_type.light_text %}white{% else %}black{% endif %}; display: inline-block; padding: 5px;">
{{ event_type.name }}
</a>
{% endfor %}
<hr />
{% for day, events in day_events.items %}
{{ day.date|date:"D d/m" }} <br />
<div style="display: flex; flex-wrap: wrap;">
{% for event in events %}
<a class="event"
href="{% url 'program:event' slug=event.slug %}"
style="background-color: {{ event.event_type.color }}; border: 0; color: {% if event.event_type.light_text %}white{% else %}black{% endif %};">
<small>{{ event.start|date:"H:i" }} - {{ event.end|date:"H:i" }}</small>
<br />
{{ event }}
</a>
{% endfor %}
</div>
<hr />
{% endfor %}
{% endblock %}

3
program/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

8
program/urls.py Normal file
View file

@ -0,0 +1,8 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P<slug>[-_\w+]+)/$', views.EventDetailView.as_view(), name='event'),
url(r'^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', views.ProgramDayView.as_view(), name='day'),
url(r'^$', views.ProgramOverviewView.as_view(), name='index'),
]

69
program/views.py Normal file
View file

@ -0,0 +1,69 @@
from collections import OrderedDict
import datetime
from django.views.generic import ListView, TemplateView, DetailView
from camps.models import Day
from . import models
class ProgramOverviewView(ListView):
model = models.Event
template_name = 'program_overview.html'
def get_context_data(self, **kwargs):
context = super(
ProgramOverviewView, self
).get_context_data(**kwargs)
days = Day.objects.all()
context['days'] = days
filter = {}
if 'type' in self.request.GET:
event_type = self.request.GET['type']
filter["event_type__slug"] = event_type
context['day_events'] = OrderedDict([
(
day,
self.get_queryset().filter(
days__in=[day],
**filter
).order_by(
'start'
)
)
for day in days
])
context['event_types'] = models.EventType.objects.all()
return context
class ProgramDayView(TemplateView):
template_name = 'program_day.html'
def get_context_data(self, **kwargs):
context = super(ProgramDayView, self).get_context_data(**kwargs)
year = int(kwargs['year'])
month = int(kwargs['month'])
day = int(kwargs['day'])
date = datetime.date(year=year, month=month, day=day)
day = Day.objects.filter(date=date)
context['events'] = models.Event.objects.filter(days=day).order_by('start', 'event_type')
context['event_types'] = models.EventType.objects.all()
context['days'] = Day.objects.filter(date__year=year)
return context
class EventDetailView(DetailView):
model = models.Event
template_name = 'program_event_detail.html'
def get_context_data(self, **kwargs):
context = super(EventDetailView, self).get_context_data(**kwargs)
# TODO: date__year is hardcoded here - need fix for 2017 :P
context['days'] = Day.objects.filter(date__year=2016)
return context