Initial commit.

This commit is contained in:
Víðir Valberg Guðmundsson 2015-10-03 03:07:05 +02:00
commit 91ca821831
24 changed files with 447 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.idea/
__pycache__/
db.sqlite3

18
README.md Normal file
View file

@ -0,0 +1,18 @@
# Bornhack
Django project to power Bornhack.
Features include:
- Create camp
- Control expenses for a camp
- Manage signups for attendees for a camp
- ...
## Quickstart
$ source path/to/venv/bin/activate
$ pip install -r requirements/development.txt
$ ./manage.py makemigrations
$ ./manage.py migrate
$ ./manage.py createsuperuser
$ ./manage.py runserver

0
bornhack/__init__.py Normal file
View file

65
bornhack/settings.py Normal file
View file

@ -0,0 +1,65 @@
import os
local_dir = lambda x: os.path.join(os.path.dirname(__file___), x)
SECRET_KEY = '1&=htv#6aawk=3rxo$9e)s7g)lt2!x4=04om__sod!v6!uv&6='
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'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',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'bornhack.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [local_dir('templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'bornhack.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = local_dir('static')
MEDIA_URL = '/media/'
MEDIA_ROOT = local_dir('media')

View file

63
bornhack/settings/base.py Normal file
View file

@ -0,0 +1,63 @@
import os
def local_dir(entry):
return os.path.join(
os.path.dirname(os.path.dirname(__file__)),
entry
)
WSGI_APPLICATION = 'bornhack.wsgi.application'
ROOT_URLCONF = 'bornhack.urls'
INSTALLED_APPS = [
'flat',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'profiles',
'camps',
]
STATIC_URL = '/static/'
STATIC_ROOT = local_dir('static')
MEDIA_URL = '/media/'
MEDIA_ROOT = local_dir('media')
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [local_dir('templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
MIDDLEWARE_CLASSES = [
'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',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
]

View file

@ -0,0 +1,13 @@
from .base import *
INSTALLED_APPS += ['debug_toolbar', ]
SECRET_KEY = 'bornhack_development'
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': local_dir('db.sqlite3'),
}
}

View file

@ -0,0 +1,15 @@
from .base import *
import environ
env = environ.Env(
ENGINE='django.db.backends.postgres_psycopg2',
)
environ.Env.read_env()
SECRET_KEY = env('SECRET_KEY')
DEBUG = False
ALLOWED_HOSTS = env('ALLOWED_HOSTS')
DATABASES = {
'default': env.db(),
}

21
bornhack/urls.py Normal file
View file

@ -0,0 +1,21 @@
"""bornhack URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]

22
bornhack/utils.py Normal file
View file

@ -0,0 +1,22 @@
import uuid
from django.db import models
class CreatedUpdatedModel(models.Model):
class Meta:
abstract = True
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class UUIDModel(models.Model):
class Meta:
abstract = True
uuid = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False,
)

16
bornhack/wsgi.py Normal file
View file

@ -0,0 +1,16 @@
"""
WSGI config for bornhack project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bornhack.settings")
application = get_wsgi_application()

0
camps/__init__.py Normal file
View file

29
camps/admin.py Normal file
View file

@ -0,0 +1,29 @@
from django.contrib import admin
from .models import Camp, Expense, Signup
@admin.register(Expense)
class ExpenseAdmin(admin.ModelAdmin):
pass
class ExpenseInlineAdmin(admin.TabularInline):
model = Expense
@admin.register(Signup)
class SignupAdmin(admin.ModelAdmin):
pass
class SignupInlineAdmin(admin.TabularInline):
model = Signup
@admin.register(Camp)
class CampAdmin(admin.ModelAdmin):
inlines = [
ExpenseInlineAdmin,
SignupInlineAdmin
]

View file

120
camps/models.py Normal file
View file

@ -0,0 +1,120 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from bornhack.utils import CreatedUpdatedModel, UUIDModel
class Camp(CreatedUpdatedModel, UUIDModel):
class Meta:
verbose_name = _('Camp')
verbose_name_plural = _('Camps')
name = models.CharField(
verbose_name=_('Name'),
help_text=_('Name of the camp, ie. Bornhack.'),
max_length=255,
)
start = models.DateTimeField(
verbose_name=_('Start date'),
help_text=_('When the camp starts.'),
unique=True,
)
end = models.DateTimeField(
verbose_name=_('End date'),
help_text=_('When the camp ends.'),
unique=True,
)
def __str__(self):
return _('{} {}').format(
self.name,
self.start.year,
)
class Expense(CreatedUpdatedModel, UUIDModel):
class Meta:
verbose_name = _('Expense')
verbose_name_plural = _('Expenses')
camp = models.ForeignKey(
'camps.Camp',
verbose_name=_('Camp'),
help_text=_('The camp to which this expense relates to.'),
)
description = models.CharField(
verbose_name=_('Description'),
help_text=_('What this expense covers.'),
max_length=255,
)
amount = models.DecimalField(
verbose_name=_('Amount'),
help_text=_('The amount of the expense.'),
max_digits=7,
decimal_places=2,
)
CURRENCIES = [
('btc', 'BTC'),
('dkk', 'DKK'),
('eur', 'EUR'),
('sek', 'SEK'),
]
currency = models.CharField(
verbose_name=_('Currency'),
help_text=_('What currency the amount is in.'),
choices=CURRENCIES,
max_length=3,
)
covered_by = models.ForeignKey(
'auth.User',
verbose_name=_('Covered by'),
help_text=_('Which user, if any, covered this expense.'),
null=True,
blank=True,
)
def __str__(self):
return _('{} {} for {}').format(
self.amount,
self.get_currency_display(),
self.camp,
)
class Signup(CreatedUpdatedModel, UUIDModel):
class Meta:
verbose_name = _('Signup')
verbose_name_plural = _('Signups')
camp = models.ForeignKey(
'camps.Camp',
verbose_name=_('Camp'),
help_text=_('The camp that has been signed up for.'),
)
user = models.ForeignKey(
'auth.User',
verbose_name=_('User'),
help_text=_('The user that has signed up.'),
)
cost = models.DecimalField(
verbose_name=_('Cost'),
help_text=_('What the user should/is willing to pay for this signup.'),
max_digits=7,
decimal_places=2,
default=1500.0
)
paid = models.BooleanField(
verbose_name=_('Paid?'),
help_text=_('Whether the user has paid.'),
default=False,
)

3
camps/tests.py Normal file
View file

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

3
camps/views.py Normal file
View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

13
manage.py Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE",
"bornhack.settings.development"
)
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

0
profiles/__init__.py Normal file
View file

5
profiles/admin.py Normal file
View file

@ -0,0 +1,5 @@
from django.contrib import admin
from .models import Profile
admin.site.register(Profile)

View file

32
profiles/models.py Normal file
View file

@ -0,0 +1,32 @@
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from bornhack.utils import CreatedUpdatedModel, UUIDModel
class Profile(CreatedUpdatedModel, UUIDModel):
class Meta:
verbose_name = _('Profile')
verbose_name_plural = _('Profiles')
user = models.OneToOneField(
User,
verbose_name=_('User'),
help_text=_('The django user this profile belongs to.'),
)
@property
def email(self):
return self.user.email
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_profile(sender, created, instance, **kwargs):
if created:
Profile.objects.create(user=instance)

3
profiles/tests.py Normal file
View file

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

3
profiles/views.py Normal file
View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.