just a commit before we start the days work

This commit is contained in:
Thomas Steen Rasmussen 2017-01-20 16:18:10 +01:00
parent 9b089de165
commit b4f3c386c3
84 changed files with 436 additions and 199 deletions

View file

@ -4,6 +4,11 @@ from django.utils import timezone
def camp(request):
"""
if we have a camp_slug url component then get the "current" Camp object.
Return it after adding the slug to request.session along with a "camps"
queryset containing all camps (used to build the menu and such)
"""
if 'camp_slug' in request.resolver_match.kwargs:
camp = Camp.objects.get(slug=request.resolver_match.kwargs['camp_slug'])
request.session['campslug'] = camp.slug
@ -12,7 +17,7 @@ def camp(request):
camp = None
return {
'camps': Camp.objects.all().order_by('-camp_start'),
'camps': Camp.objects.all().order_by('-camp'),
'camp': camp
}

View file

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2016-12-29 22:01
from __future__ import unicode_literals
import django.contrib.postgres.fields.ranges
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camps', '0012_auto_20161228_2312'),
]
operations = [
migrations.RemoveField(
model_name='camp',
name='buildup_start',
),
migrations.RemoveField(
model_name='camp',
name='camp_end',
),
migrations.RemoveField(
model_name='camp',
name='camp_start',
),
migrations.RemoveField(
model_name='camp',
name='teardown_end',
),
migrations.AddField(
model_name='camp',
name='buildup',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp buildup period.', null=True, verbose_name=b'Buildup Period'),
),
migrations.AddField(
model_name='camp',
name='camp',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp period.', null=True, verbose_name=b'Camp Period'),
),
migrations.AddField(
model_name='camp',
name='teardown',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp teardown period.', null=True, verbose_name=b'Teardown period'),
),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2016-12-29 22:02
from __future__ import unicode_literals
import django.contrib.postgres.fields.ranges
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camps', '0013_auto_20161229_2201'),
]
operations = [
migrations.AlterField(
model_name='camp',
name='buildup',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp buildup period.', verbose_name=b'Buildup Period'),
),
migrations.AlterField(
model_name='camp',
name='camp',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp period.', verbose_name=b'Camp Period'),
),
migrations.AlterField(
model_name='camp',
name='teardown',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp teardown period.', verbose_name=b'Teardown period'),
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-16 16:34
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camps', '0014_auto_20161229_2202'),
]
operations = [
migrations.RemoveField(
model_name='expense',
name='refund_user',
),
migrations.DeleteModel(
name='Expense',
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-16 16:37
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('camps', '0015_auto_20170116_1634'),
]
operations = [
migrations.AddField(
model_name='camp',
name='description',
field=models.TextField(default=b'', help_text=b'Description of the camp, shown on the camp frontpage. HTML and markdown supported.', verbose_name=b'Description'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-16 21:59
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('camps', '0016_camp_description'),
]
operations = [
migrations.RemoveField(
model_name='camp',
name='description',
),
]

View file

@ -1,6 +1,8 @@
import datetime
from django.db import models
from utils.models import UUIDModel, CreatedUpdatedModel
from program.models import EventType
from django.contrib.postgres.fields import DateTimeRangeField
class Camp(CreatedUpdatedModel, UUIDModel):
@ -25,69 +27,34 @@ class Camp(CreatedUpdatedModel, UUIDModel):
help_text='The url slug to use for this camp'
)
buildup_start = models.DateTimeField(
verbose_name='Buildup Start date',
help_text='When the camp buildup starts.',
buildup = DateTimeRangeField(
verbose_name='Buildup Period',
help_text='The camp buildup period.',
)
camp_start = models.DateTimeField(
verbose_name='Start date',
help_text='When the camp starts.',
camp = DateTimeRangeField(
verbose_name='Camp Period',
help_text='The camp period.',
)
camp_end = models.DateTimeField(
verbose_name='End date',
help_text='When the camp ends.',
)
teardown_end = models.DateTimeField(
verbose_name='Start date',
help_text='When the camp teardown ends.',
teardown = DateTimeRangeField(
verbose_name='Teardown period',
help_text='The camp teardown period.',
)
def __unicode__(self):
return "%s - %s" % (self.title, self.tagline)
@property
def event_types(self):
# return all event types with at least one event in this camp
return EventType.objects.filter(event__instances__isnull=False, event__camp=self).distinct()
class Expense(CreatedUpdatedModel, UUIDModel):
class Meta:
verbose_name = 'Expense'
verbose_name_plural = 'Expenses'
@property
def logo_small(self):
return 'img/%(slug)s/logo/%(slug)s-logo-small.png' % {'slug': self.slug}
payment_time = models.DateTimeField(
verbose_name='Expense date/time',
help_text='The date and time this expense was paid.',
)
description = models.CharField(
verbose_name='Description',
help_text='What this expense covers.',
max_length=255,
)
dkk_amount = models.DecimalField(
verbose_name='DKK Amount',
help_text='The DKK amount of the expense.',
max_digits=7,
decimal_places=2,
)
receipt = models.ImageField(
verbose_name='Image of receipt',
help_text='Upload a scan or image of the receipt',
)
refund_user = models.ForeignKey(
'auth.User',
verbose_name='Refund user',
help_text='Which user, if any, covered this expense and should be refunded.',
null=True,
blank=True,
)
refund_paid = models.BooleanField(
default=False,
verbose_name='Refund paid?',
help_text='Has this expense been refunded to the user?',
)
@property
def logo_large(self):
return 'img/%(slug)s/logo/%(slug)s-logo-large.png' % {'slug': self.slug}

View file

@ -1,5 +1,12 @@
{% extends 'base.html' %}
{% load commonmark %}
{% load static from staticfiles %}
{% block content %}
{{ camp.title }}
<div class="row">
<div class="col-md-12">
<img src="{% static camp.logo_large %}" class="img-responsive" id="front-logo" />
<br />
{{ camp.description|commonmark }}
{% endblock content %}

View file

@ -0,0 +1,61 @@
{% extends 'base.html' %}
{% load commonmark %}
{% load static from staticfiles %}
{% load imageutils %}
{% block content %}
<div class="row">
<div class="col-md-12">
<img src="{% static camp.logo_large %}" class="img-responsive" id="front-logo" />
<br />
<div class="col-md-8 text-container">
<div class="lead">
<strong>Bornhack 2016</strong> was the first BornHack. It took place from <strong>August 27 to September 3rd 2016</strong> on the Danish island of Bornholm. The tagline of this event was <strong>Initial Commit</strong>.
</div>
</div>
<div class="col-md-4">
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2612.jpg' 'A quiet moment in the chillout area by the bar' %}
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-4">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5128.JPG' 'Emma Holten speaking at BornHack 2016' %}
</div>
<div class="col-md-8 text-container">
<div class="lead">
With <strong>3 keynotes, 38 talks, and 9 workshops</strong> we had an ambitious program which was well received by participants. We also had an <strong>amazing list of sponsors</strong> making the event financially possible.
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-8 text-container">
<p class="lead">Many of the speakers and keynotes were present for the <strong>full week</strong>, providing participants with <strong>ample opportunity to discuss projects and exchange ideas</strong>.</p>
</div>
<div class="col-md-4">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5149.JPG' 'Danish politicians debating at BornHack 2016' %}
</div>
</div>
<br />
<div class="row">
<div class="col-md-4">
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2631.jpg' 'The BornHack 2016 organiser team' %}
</div>
<div class="col-md-8 text-container">
<div class="lead">
The team behind BornHack 2016 had <strong>a lot of help</strong> from volunteer participants when it was needed. We are <strong>very grateful</strong> and will repay the kindness by continuing to organise awesome events.
</div>
</div>
</div>
{% endblock content %}

View file

@ -5,6 +5,8 @@ from .models import *
class CampDetailView(DetailView):
model = Camp
template_name = 'camp_detail.html'
slug_url_kwarg = 'camp_slug'
def get_template_names(self):
return 'camp_detail_%s.html' % self.get_object().slug

View file

@ -74,4 +74,7 @@ class InfoItem(CreatedUpdatedModel):
# this anchor is already in use on a category, so it cannot be used here (they must be unique on the entire page)
raise ValidationError({'anchor': 'Anchor is already in use on an info category for this camp'})
def __str__(self):
return '%s (%s)' % (self.headline, self.category)

View file

@ -6,6 +6,9 @@ News | {{ block.super }}
{% endblock %}
{% block content %}
{% if request.resolver_match.kwargs.archived %}
<i>Showing archived news items. <a href="{% url 'news:index' archived=False %}">Show regular news items</a></i>
{% endif %}
{% for item in news_items %}
<div>
<h3><a href="{% url 'news:detail' slug=item.slug %}">{{ item.title }}</a> <small>{{ item.published_at|date:"Y-m-d" }}</small></h3>
@ -17,4 +20,9 @@ News | {{ block.super }}
{% empty %}
<h3>No news yet. Stay tuned!</h3>
{% endfor %}
{% endblock %}
{% if not request.resolver_match.kwargs.archived %}
<hr />
<i><a href="{% url 'news:archive' archived=True %}">Show archived news items</a></i>
{% endif %}
{% endblock %}

View file

@ -3,6 +3,8 @@ from . import views
urlpatterns = [
url(r'^$', views.NewsIndex.as_view(), name='index'),
url(r'^$', views.NewsIndex.as_view(), kwargs={'archived': False}, name='index'),
url(r'^archive/$', views.NewsIndex.as_view(), kwargs={'archived': True}, name='archive'),
url(r'(?P<slug>[-_\w+]+)/$', views.NewsDetail.as_view(), name='detail'),
]

View file

@ -7,11 +7,11 @@ class NewsIndex(ListView):
template_name = 'news_index.html'
context_object_name = 'news_items'
def get_queryset(self, **kwargs):
def get_queryset(self):
return NewsItem.objects.filter(
published_at__isnull=False,
published_at__lt=timezone.now(),
archived=False
archived=self.kwargs['archived']
)

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2016-12-29 21:49
from __future__ import unicode_literals
import django.contrib.postgres.fields.ranges
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('program', '0010_auto_20161212_1809'),
]
operations = [
migrations.AlterModelOptions(
name='eventinstance',
options={'ordering': ['when']},
),
migrations.RemoveField(
model_name='eventinstance',
name='end',
),
migrations.RemoveField(
model_name='eventinstance',
name='start',
),
migrations.AddField(
model_name='eventinstance',
name='when',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(null=True),
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2016-12-29 21:50
from __future__ import unicode_literals
import django.contrib.postgres.fields.ranges
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('program', '0011_auto_20161229_2149'),
]
operations = [
migrations.AlterField(
model_name='eventinstance',
name='when',
field=django.contrib.postgres.fields.ranges.DateTimeRangeField(),
),
]

View file

@ -1,5 +1,5 @@
from __future__ import unicode_literals
from django.contrib.postgres.fields import DateTimeRangeField
from django.db import models
from django.utils.text import slugify
@ -18,7 +18,7 @@ class EventType(CreatedUpdatedModel):
class Event(CreatedUpdatedModel):
""" Something that is on the program. """
""" Something that is on the program one or more times. """
title = models.CharField(max_length=255)
slug = models.SlugField(blank=True, max_length=255)
abstract = models.TextField()
@ -40,19 +40,17 @@ class Event(CreatedUpdatedModel):
class EventInstance(CreatedUpdatedModel):
""" An instance of an event """
event = models.ForeignKey('program.event', related_name='instances')
start = models.DateTimeField()
end = models.DateTimeField()
when = DateTimeRangeField()
class Meta:
ordering = ['start']
ordering = ['when']
def __unicode__(self):
return '%s (%s to %s)' % (self.event, self.start, self.end)
return '%s (%s)' % (self.event, self.when)
class Speaker(CreatedUpdatedModel):
""" Person anchoring an event. """
""" A Person anchoring an event. """
name = models.CharField(max_length=150)
biography = models.TextField()
picture = models.ImageField(null=True, blank=True)

View file

@ -4,8 +4,8 @@
<a href="{% url 'schedule: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 'schedule: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;">
{% for event_type in camp.event_types %}
<a href="{% url 'schedule_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 %}

View file

@ -26,62 +26,13 @@ class ProgramOverviewView(CampViewMixin, 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(CampViewMixin, 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['date'] = date
context['events'] = models.Event.objects.filter(days=day).order_by('event_type', 'start')
context['event_types'] = models.EventType.objects.all()
context['days'] = Day.objects.filter(date__year=year)
return context
class EventDetailView(CampViewMixin, 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -33,7 +33,7 @@
</button>
<a class="navbar-brand" href="/">
{% if request.resolver_match.kwargs.camp_slug %}
<img src="{{ baseurl }}/img/{{ camp.slug }}/{{ camp.slug }}-logo-small.png" class="img-responsive" />
<img src="{% static camp.logo_small %}" class="img-responsive" />
{% else %}
<img src="{% static 'img/logo-small.png' %}" class="img-responsive" />
{% endif %}
@ -44,13 +44,14 @@
<li><a href="{% url 'news:index' %}">News</a></li>
<li><a href="{% url 'shop:index' %}">Shop</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ camp.title|default:"Camps" }}<span class="caret"></span></a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Camps<span class="caret"></span></a>
<ul class="dropdown-menu">
{% for camp in camps %}
<li><a href="{% url 'camp_detail' camp_slug=camp.slug %}">{{ camp.title }}</a></li>
{% endfor %}
</ul>
</li>
<li><a href="{% url 'contact' %}">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
@ -83,7 +84,7 @@
{% block footer %}
<a href="{% url 'general-terms' %}">General Terms &amp; Conditions</a> |
<a href="{% url 'conduct' %}">Code of Conduct</a> |
<a href="{% url 'privacy-policy' %}">Privacy Policy</a>
<a href="{% url 'privacy-policy' %}">Privacy Policy</a> |
<a href="{% url 'contact' %}">Contact</a>
{% endblock %}
</div>

View file

@ -1,12 +1,11 @@
{% extends 'base.html' %}
{% load static from staticfiles %}
{% load imageutils %}
{% block content %}
<div class="row">
<div class="col-md-12">
<img src="{% static 'img/logo.png' %}" class="img-responsive"
id="front-logo" />
<img src="{% static 'img/logo-large.png' %}" class="img-responsive" id="front-logo" />
<br />
@ -19,11 +18,7 @@
</div>
</div>
<div class="col-md-4">
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_162831.jpg">
<img class="img-thumbnail"
src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_162831_tn.jpg"
alt="Tents at CCCamp2015" title="Tents at CCCamp2015">
</a>
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1961.JPG' 'BornHack' %}
</div>
</div>
@ -31,11 +26,7 @@
<div class="row">
<div class="col-md-4">
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/jarlsgaard.jpg">
<img class="img-thumbnail"
src="https://people.bornhack.org/tyk/ohm_cccamp_pics/jarlsgaard_tn.jpg"
alt="Jarlsgaard from above" title="Jarlsgaard from above">
</a>
{% thumbnail 'img/bornhack-2016/ahf' 'jarlsgaard.jpg' 'Jarlsgård buildings from above' %}
</div>
<div class="col-md-8 text-container">
<div class="lead">
@ -57,11 +48,7 @@
</p>
</div>
<div class="col-md-4">
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5755.jpg">
<img class="img-thumbnail"
src="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5755_tn.jpg"
alt="Hacking in Baconsvin village at OHM2013" title="Hacking in Baconsvin village at OHM2013">
</a>
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5090.JPG' 'Talk at BornHack 2016' %}
</div>
</div>
@ -87,43 +74,15 @@
</div>
<p align="center">
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_141706.jpg">
<img class="img-thumbnail"
src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_141706_tn.jpg"
alt="Hacking sign at CCCamp2015" title="Hacking sign at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_163606.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_163606_tn.jpg"
alt="Entrance to Baconsvin village at CCCamp2015" title="Entrance to Baconsvin village at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_201635.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150812_201635_tn.jpg"
alt="Dome being built at CCCamp2015" title="Dome being built at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5746.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5746_tn.jpg"
alt="Person swinging lights in the night at OHM2013" title="Person swinging lights in the night at OHM2013">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150814_145204.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150814_145204_tn.jpg"
alt="Queer Feminist Geeks village at CCCamp2015" title="Queer Feminist Geeks village at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_154027.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_154027_tn.jpg"
alt="Dome at CCCamp2015" title="Dome at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5736.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/_MG_5736_tn.jpg"
alt="Lights at night at OHM2013" title="Lights at night at OHM2013">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_154119.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150815_154119_tn.jpg"
alt="Free Chelsea Manning sign at CCCamp2015" title="Free Chelsea Manning sign at CCCamp2015">
</a>
<a href="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150816_153404.jpg">
<img class="img-thumbnail" src="https://people.bornhack.org/tyk/ohm_cccamp_pics/IMG_20150816_153404_tn.jpg"
alt="Swedish Embassy sign at CCCamp2015" title="Swedish Embassy sign at CCCamp2015">
</a>
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1983.JPG' 'Happy organisers welcoming people at the entrance to BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1986.JPG' 'A bus full of hackers arrive at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5265.JPG' 'Happy organisers welcoming people to BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2452.jpg' 'Soldering the BornHack 2016 badge' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2485.jpg' 'Colored light in the grass' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2624.jpg' 'Working on decorations' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2604.jpg' 'Sitting around the campfire at BornHack 2016' %}
</p>
</div>

View file

@ -18,16 +18,57 @@ class Command(BaseCommand):
def handle(self, *args, **options):
self.output('Creating camps...')
camp1 = Camp.objects.create(
name='BornHack 2016',
title='BornHack 2016',
tagline='Initial Commit',
slug='bornhack-2016',
start=timezone.datetime(2016, 8, 27, 12, 0, tzinfo=timezone.utc),
end=timezone.datetime(2016, 9, 4, 12, 0, tzinfo=timezone.utc)
buildup = (
timezone.datetime(2016, 8, 25, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2016, 8, 27, 12, 0, tzinfo=timezone.utc),
),
camp = (
timezone.datetime(2016, 8, 27, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2016, 9, 04, 12, 0, tzinfo=timezone.utc),
),
teardown = (
timezone.datetime(2016, 9, 04, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2016, 9, 06, 12, 0, tzinfo=timezone.utc),
),
)
camp2 = Camp.objects.create(
name='BornHack 2015',
slug='bornhack-2015',
start=timezone.datetime(2015, 8, 27, 12, 0, tzinfo=timezone.utc),
end=timezone.datetime(2015, 9, 4, 12, 0, tzinfo=timezone.utc)
title='BornHack 2017',
tagline='Make Tradition',
slug='bornhack-2017',
buildup = (
timezone.datetime(2017, 8, 20, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2017, 8, 22, 12, 0, tzinfo=timezone.utc),
),
camp = (
timezone.datetime(2017, 8, 22, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2017, 8, 29, 12, 0, tzinfo=timezone.utc),
),
teardown = (
timezone.datetime(2015, 8, 29, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2015, 8, 31, 12, 0, tzinfo=timezone.utc),
),
)
camp3 = Camp.objects.create(
title='BornHack 2018',
tagline='Undecided',
slug='bornhack-2018',
buildup = (
timezone.datetime(2018, 8, 13, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2018, 8, 16, 12, 0, tzinfo=timezone.utc),
),
camp = (
timezone.datetime(2018, 8, 16, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2018, 8, 23, 12, 0, tzinfo=timezone.utc),
),
teardown = (
timezone.datetime(2018, 8, 23, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2018, 8, 26, 12, 0, tzinfo=timezone.utc),
),
)
self.output('Creating news...')
@ -46,15 +87,15 @@ class Command(BaseCommand):
content='unpublished news body here',
)
news4 = NewsItem.objects.create(
title='welcome to bornhack 2015',
title='welcome to bornhack 2017',
content='news body here',
published_at=timezone.datetime(2015, 8, 22, 12, 0, tzinfo=timezone.utc),
published_at=timezone.datetime(2017, 8, 22, 12, 0, tzinfo=timezone.utc),
archived=True
)
news5 = NewsItem.objects.create(
title='bornhack 2015 is over',
title='bornhack 2017 is over',
content='news body here',
published_at=timezone.datetime(2015, 8, 27, 12, 0, tzinfo=timezone.utc),
published_at=timezone.datetime(2017, 8, 29, 12, 0, tzinfo=timezone.utc),
archived=True
)
@ -190,8 +231,10 @@ class Command(BaseCommand):
self.output("creating eventinstances...")
ei1 = EventInstance.objects.create(
event=ev3,
start=timezone.datetime(2016, 8, 27, 12, 0, tzinfo=timezone.utc),
end=timezone.datetime(2016, 8, 27, 13, 0, tzinfo=timezone.utc),
when=(
timezone.datetime(2016, 8, 27, 12, 0, tzinfo=timezone.utc),
timezone.datetime(2016, 8, 27, 13, 0, tzinfo=timezone.utc)
)
)
ei2 = EventInstance.objects.create(
event=ev1,

View file

@ -0,0 +1,2 @@
<a href="{{ path }}/{{ filename }}"><img class="img-thumbnail" src="{{ path }}/thumbnail_{{ filename }}.png" alt="{{ description }}" title="{{ description }}"></a>

View file

@ -0,0 +1,18 @@
from django import template
from django.contrib.staticfiles.templatetags.staticfiles import static
register = template.Library()
@register.inclusion_tag('thumbnail.html')
def thumbnail(path, filename, description):
"""
Returns the HTML to show an image including thumbnail.
Assumes the thumbnail is called 'thumbnail_foo.jpg.png' if the image is called 'foo.jpg'.
Path should be relative inside static root.
Description is used for alt-text and mouseover.
"""
return {
'path': static('') + path,
'filename': filename,
'description': description,
}

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2016-12-29 21:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('villages', '0008_auto_20161228_2209'),
]
operations = [
migrations.AlterField(
model_name='village',
name='private',
field=models.BooleanField(default=False, help_text='Check if your village is invite only. Leave unchecked to welcome strangers.'),
),
]

View file

@ -24,7 +24,7 @@ class Village(CreatedUpdatedModel, UUIDModel):
private = models.BooleanField(
default=False,
help_text='Check if your village is privately organized'
help_text='Check if your village is invite only. Leave unchecked to welcome strangers.'
)
deleted = models.BooleanField(

View file

@ -2,7 +2,7 @@
{% load bootstrap3 %}
{% block content %}
<h3>Create {{ camp.title }} Village</h3>
<form method="post">
{% csrf_token %}

View file

@ -12,15 +12,12 @@ Villages | {{ block.super }}
is fairly simple: a village is just a spot on the campsite where you and a
bunch of your friends/likeminded people camp together. Apart from peoples
individual tents which they sleep in, many villages bring a large common tent
where you can hack and hang out during the day.
</p>
<p class="lead">
It is also possible to rent a tent, chairs and tables in the shop!
where you can hack and hang out during the day. It is also possible to rent a
tent, chairs and tables in the shop!
</p>
{% if user.is_authenticated %}
<a href="{% url 'village_create' camp_slug=camp.slug %}" class="btn btn-primary">Create a village</a>
<a href="{% url 'village_create' camp_slug=camp.slug %}" class="btn btn-primary">Create a new {{ camp.title }} village</a>
{% endif %}
<hr />