class VoteForm(forms.Form):

    def __init__(self, *args, **kwargs):
        super(VoteForm, self).__init__(*args, **kwargs)

        categories = Category.objects.filter(type=TYPE.VOTED).order_by("name")
        for c in categories:
            if c.is_concept:
                queryset=Team.objects.filter(status=STATUS.ACTIVE,
                                project_type=PROJECT_TYPE.CONCEPT).order_by("name")
            elif c.is_implemented:
                queryset=Team.objects.filter(status=STATUS.ACTIVE,
                                project_type=PROJECT_TYPE.IMPLEMENTED).order_by("name")
            else:
                queryset=Team.objects.filter(status=STATUS.ACTIVE).order_by("name")

            self.fields['cat_%s' % c.id] = forms.ModelChoiceField(
                queryset=queryset,
                label=c.name,
                empty_label="Select a team",
                required=False) class AuthorizeForm(forms.Form):
    user_name = forms.CharField(label='User Name',)
    password = forms.CharField(label='Password', widget=forms.PasswordInput,) class VoteAuthorizeForm(forms.Form):
    user_name = forms.CharField(label='User Name', widget=forms.TextInput(attrs={'autocapitalize': 'off'}))
    password = forms.CharField(label='Password', widget=forms.PasswordInput,)

    def __init__(self, *args, **kwargs):
        super(VoteAuthorizeForm, self).__init__(*args, **kwargs)

        categories = Category.objects.filter(type=TYPE.VOTED).order_by("name")
        for c in categories:
            if c.is_concept:
                queryset=Team.objects.filter(status=STATUS.ACTIVE,
                                project_type=PROJECT_TYPE.CONCEPT).order_by("name")
            elif c.is_implemented:
                queryset=Team.objects.filter(status=STATUS.ACTIVE,
                                project_type=PROJECT_TYPE.IMPLEMENTED).order_by("name")
            else:
                queryset=Team.objects.filter(status=STATUS.ACTIVE).order_by("name")

            self.fields['cat_%s' % c.id] = forms.ModelChoiceField(
                queryset=queryset,
                label=c.name,
                empty_label="Select a team",
                required=False) class VoteCart(models.Model):
    """
    A 'shopping cart' for votes; lets us gather up all of a user's votes,
    and redisplay them for confirmation/correction.

    Once a VoteCart has been completed, its corresponding Votes should be
    disconnected from the VoteCart to preserve the anonymity of the voting.

    The presence of a VoteCart for the user will serve as an indicator that
    they have either started voting or completed voting (in which case, they
    can't vote again, thankyouverymuch).
    """

    user = models.ForeignKey(User)
    status = models.CharField(max_length=1, choices=STATUS.CHOICES)

    create_date = models.DateTimeField('date created', auto_now_add=True)
    mod_date = models.DateTimeField('date modified', auto_now=True) class Vote(models.Model):
    """
    Vote for Pedro!

    An individual vote for a team in a category.

    Once voting is completed, the cart relationship should be nulled out so
    that votes are anonymous once cast.
    """

    team = models.ForeignKey(Team)
    category = models.ForeignKey(Category)
    cart = models.ForeignKey(VoteCart, null=True)

    create_date = models.DateTimeField('date created', auto_now_add=True)
    mode_date = models.DateTimeField('date modified', auto_now=True) class VoteStatus(models.Model):
    """ A model to allow turning voting on and off on the site
        via the admin interface
    """
    online = models.BooleanField()

    def __unicode__(self):
        return self.online and "Online" or "Offline"

    class Meta:
        verbose_name_plural = "Voting status" class STATUS(object):
    """
    Status values for a VoteCart.
    """
    ACTIVE = 'A'
    COMPLETED = 'C'

    CHOICES = (
        (ACTIVE, 'Active'),
        (COMPLETED, 'Completed'),
    ) class Category(models.Model):
    """
    Awards categories that teams can compete for.

    Categories of 'voted' type should be available for popular voting in the
    voting UI.

    Categories of 'judged' type should NOT be available for popular voting as
    they will be decided by a panel of judges outside of the voting system.

    Teams should self-declare a 'judged' category to enter when the team is
    created.
    """

    name = models.CharField('name of category', max_length=255, unique=True)
    slug = models.SlugField('slugified category name', db_index=True,
            unique=True)
    description = models.TextField('description of category')
    type = models.CharField('type of category', max_length=1, db_index=True,
            choices=TYPE.CHOICES)
    project_type = models.CharField('type of project', max_length=1,
                choices=PROJECT_TYPE.CHOICES, blank=True)

    create_date = models.DateTimeField('date created', auto_now_add=True)
    mod_date = models.DateTimeField('date modified', auto_now=True)

    def __unicode__(self):
        return self.name

    @property
    def is_concept(self):
        return self.project_type is not None and self.project_type == PROJECT_TYPE.CONCEPT

    @property
    def is_implemented(self):
        return self.project_type is not None and self.project_type == PROJECT_TYPE.IMPLEMENTED

    class Meta:
        verbose_name_plural = "Categories"
        ordering = ['name'] class TYPE(object):
    """
    Differentiate categories by type; some categories may be decided by
    a panel of judges, while others may be voted on by event participants.
    """
    JUDGED = 'J'
    VOTED = 'V'

    CHOICES = (
        (JUDGED, 'Judged'),
        (VOTED, 'Voted'),
    ) class Team(models.Model):
    """
    A team of participants that will work on a project and compete for fabulous
    prizes, fame, and glory.

    Upon creation, a team needs:

        * a name--hopefully an awesome one
        * a slug, to be used for the URL of the team's page
        * a project description
        * a project type, so that we can differentiate "real" hacks vs. thought
          experiments (aka "code vs. ppt")
        * a creator
        * a captain
        * team members
        * a judged category
        * a charity that the team is supporting

    The creator and captain may have management powers above and beyond
    those of a mere member.
    """

    name = models.CharField('name of team', max_length=255, db_index=True,
            unique=True)
    slug = models.SlugField('slugified team name', db_index=True, unique=True,
            editable=False)

    project = models.TextField('description of project')
    logo = models.ImageField('team logo image', blank=True,
            upload_to=create_unique_team_filename)

    project_type = models.CharField('type of project', max_length=1,
            db_index=True, choices=PROJECT_TYPE.CHOICES)
    status = models.CharField(max_length=1, db_index=True,
            choices=STATUS.CHOICES)

    creator = models.ForeignKey(User,
            related_name="%(app_label)s_%(class)s_creator")
    captain = models.ForeignKey(User,
            related_name="%(app_label)s_%(class)s_captain")
    members = models.ManyToManyField(User,
            related_name="%(app_label)s_%(class)s_members")

    attachments = models.ManyToManyField(Attachment, blank=True,
            related_name="%(app_label)s_%(class)s_attachments")
    images = models.ManyToManyField(ImageAttachment, blank=True,
            related_name="%(app_label)s_%(class)s_images")
    links = models.ManyToManyField(Link, blank=True,
            related_name="%(app_label)s_%(class)s_links")

    category = models.ForeignKey(Category)
    charity = models.ForeignKey(Charity)

    create_date = models.DateTimeField('date created', auto_now_add=True)
    mod_date = models.DateTimeField('date modified', auto_now=True)

    @property
    def is_concept(self):
        return self.project_type == PROJECT_TYPE.CONCEPT

    @property
    def is_implemented(self):
        return self.project_type == PROJECT_TYPE.IMPLEMENTED

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)  #TODO: check if slug exists in DB
        return super(Team, self).save()

    def add_captain_as_member(self):
        if not self.is_member(self.captain):
            self.members.add(self.captain)
            self.save()

    def is_member(self, user):
        return user in self.members.all()

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['name'] class STATUS(object):
    """
    Status of the team
    """
    ACTIVE = 'A'
    DISQUALIFIED = 'D'
    DELETED = 'X'

    CHOICES = (
        (ACTIVE, 'Active'),
        (DISQUALIFIED, 'Disqualified'),
        (DELETED, 'Deleted'),
    ) class Tshirt(models.Model):
class Diet(models.Model):
class Location(models.Model):
class UserProfile(models.Model):
    def __unicode__(self):
    def __unicode__(self):
    def __unicode__(self):
    def __unicode__(self):
    def image(self):
import math
import json
from collections import OrderedDict
from django.core import serializers
from django.http import HttpResponse
from django.shortcuts import render
from django.db.models import Count
from django.db.models.query import QuerySet
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, user_passes_test
from django.views.decorators.csrf import csrf_exempt
from hackday.voting.forms import VoteForm, AuthorizeForm, VoteAuthorizeForm
from hackday.voting.models import VoteCart, Vote, VoteStatus, STATUS
from hackday.voting.moremodels import Category, TYPE
from hackday.teams.models import Team, STATUS as TEAM_STATUS
from hackday.users.models import User, UserProfile
    def default(self, obj):
        if isinstance(obj, QuerySet):
            # `default` must return a python serializable
            # structure, the easiest way is to load the JSON
            # string produced by `serialize` and return it
            return json.loads(serializers.serialize('json', obj))
        return JSONEncoder.default(self,obj)

def ipad_vote(request):
    logout(request)
    env = {}

    try:
        online = VoteStatus.objects.all()[0].online
    except:
        online = False

    if not online:
        return render(request, 'voting/vote_offline.html');

    error_message = None
    user = None
    votes = []

    if request.method == 'POST':
        form = VoteAuthorizeForm(request.POST)
        if form.is_valid():
            user = authenticate(username=form.cleaned_data['user_name'],
                                password=form.cleaned_data['password'])
            if user:
                try:
                    cart = VoteCart.objects.get(user=user.id)
                except:
                    cart = VoteCart(user=user, status=STATUS.ACTIVE)
                    cart.save()

                for key,team in form.cleaned_data.items():
                    if key.startswith('cat_'):
                        category_id = key.replace('cat_', '')
                        category = Category.objects.get(id=category_id)
                        _insert_or_update_vote(cart, category, team)
                        votes.append({'category': category, 'team': team})
                env = {'user': user}
                env['votes'] = votes
                return render(request, 'voting/ipad_vote_complete.html', env);
            else:
                error_message = "Bad username or password"
    else:
        form = VoteAuthorizeForm()

    env['form'] = form
    env['error_message'] = error_message
    return render(request, 'voting/ipad_vote.html', env)

@login_required
def vote(request):
    env = {}

    try:
        online = VoteStatus.objects.all()[0].online
    except:
        online = False

    if not online:
        return render(request, 'voting/vote_offline.html');

    try:
        cart = VoteCart.objects.get(user=request.user.id)
    except:
        cart = VoteCart(user=request.user, status=STATUS.ACTIVE)
        cart.save()

    # voting is complete don't allow more votes
    if cart.status == STATUS.COMPLETED:
        return render(request, 'voting/vote_complete.html');

    if request.method == 'POST':
        form = VoteForm(request.POST)
        if form.is_valid():

            for key,team in form.cleaned_data.items():
                category_id = key.replace('cat_', '')
                category = Category.objects.get(id=category_id)
                _insert_or_update_vote(cart, category, team)
            return render(request, 'voting/vote_complete.html');
    else:
        votes = Vote.objects.filter(cart=cart.id)
        form_init = {}
        for vote in votes:
            form_init['cat_%s' % vote.category.id] = vote.team.id
        form = VoteForm(form_init)

    env['form'] = form
    return render(request, 'voting/vote.html', env)


def info(request):
    categories = Category.objects.filter(type=TYPE.VOTED).order_by('id')
    teams = Team.objects.filter(status=TEAM_STATUS.ACTIVE).order_by('id')
    judged = Category.objects.filter(type=TYPE.JUDGED).order_by('id')

    d = {}
    for category in judged:
        d[category.name] = [t for t in teams if t.category.id == category.id]
        d[category.name].sort()

    ordered_teams = []
    o_dict = OrderedDict(sorted(d.items(), key=lambda t: len(t)))
    for item in o_dict.values():
        ordered_teams += item

    env = {'categories': categories,
           'teams': ordered_teams}
    return render(request, 'voting/info.html', env)

@csrf_exempt
def api_login(request):
    env = {'status': 'unauthorized'}

    if request.method == 'POST':

        form = AuthorizeForm(request.POST)