class EmailLoginForm(forms.Form):
    email = forms.EmailField(
        max_length=255,
        label='',
        widget=forms.TextInput(attrs={
            'placeholder': 'Email address',
            'class': 'form-control',
        })
    )

    def __init__(self, *args, **kwargs):
        super(EmailLoginForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Login')))

    def clean(self):
        cleaned_data = super(EmailLoginForm, self).clean()
        return cleaned_data class SpeakerForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SpeakerForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Submit')))
        self.fields['image'].help_text += _('Maximum size is %d MB') \
            % settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB
        self.fields['image'].help_text += ' / ' + _('Minimum dimension is %d x %d') \
            % settings.SPEAKER_IMAGE_MINIMUM_DIMENSION

    class Meta:
        model = Speaker
        fields = ('image', 'desc', 'info', )
        widgets = {
            'desc': SummernoteInplaceWidget(),
        }
        labels = {
            'image': _('Photo'),
            'desc': _('Profile'),
            'info': _('Additional information'),
        }

    def clean_image(self):
        image = self.cleaned_data.get('image')
        if image:
            try:
                if image._size > settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB * 1024 * 1024:
                    raise forms.ValidationError(
                        _('Maximum size is %d MB')
                        % settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB
                    )
            except AttributeError:
                pass

            w, h = get_image_dimensions(image)
            if w < settings.SPEAKER_IMAGE_MINIMUM_DIMENSION[0] \
                    or h < settings.SPEAKER_IMAGE_MINIMUM_DIMENSION[1]:
                raise forms.ValidationError(
                    _('Minimum dimension is %d x %d')
                    % settings.SPEAKER_IMAGE_MINIMUM_DIMENSION
                )

        return image class ProgramForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProgramForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Submit')))

    class Meta:
        model = Program
        fields = ('name', 'slide_url', 'video_url', 'is_recordable', 'desc', )
        widgets = {
            'desc': SummernoteInplaceWidget(),
        }
        labels = {
            'name': _('Title'),
            'slide_url': _('Slide URL'),
            'video_url': _('Video URL'),
            'is_recordable': _('Photography and recording is allowed'),
            'desc': _('Description'),
        } class ProposalForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProposalForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Submit')))

    class Meta:
        model = Proposal
        fields = ('title', 'brief', 'desc', 'comment', 'difficulty', 'duration', 'language',)
        widgets = {
            'desc': SummernoteInplaceWidget(),
            'comment': SummernoteInplaceWidget(),
        }

        labels = {
            'title': _('Proposal title (required)'),
            'brief': _('Brief (required)'),
            'desc': _('Detailed description (required)'),
            'comment': _('Comment to reviewers (optional)'),

            'difficulty': _('Session difficulty'),
            'duration': _('Session duration'),
            'language': _('Language'),
        } class ProfileForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Submit')))
        self.fields['image'].help_text += _('Maximum size is %d MB') \
            % settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB
        self.fields['image'].help_text += ' / ' + _('Minimum dimension is %d x %d') \
            % settings.SPEAKER_IMAGE_MINIMUM_DIMENSION

    class Meta:
        model = Profile
        fields = ('name', 'phone', 'organization', 'nationality', 'image', 'bio')
        widgets = {
            'bio': SummernoteInplaceWidget(),
        }
        labels = {
            'image': _('Photo'),
        }

    def clean_image(self):
        image = self.cleaned_data.get('image')
        if image:
            try:
                if image._size > settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB * 1024 * 1024:
                    raise forms.ValidationError(
                        _('Maximum size is %d MB')
                        % settings.SPEAKER_IMAGE_MAXIMUM_FILESIZE_IN_MB
                    )
            except AttributeError:
                pass

            w, h = get_image_dimensions(image)
            if w < settings.SPEAKER_IMAGE_MINIMUM_DIMENSION[0] \
                    or h < settings.SPEAKER_IMAGE_MINIMUM_DIMENSION[1]:
                raise forms.ValidationError(
                    _('Minimum dimension is %d x %d')
                    % settings.SPEAKER_IMAGE_MINIMUM_DIMENSION
                )

        return image class TutorialProposalForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(TutorialProposalForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', _('Submit')))

    class Meta:
        model = TutorialProposal
        fields = ('title', 'type', 'brief', 'desc', 'difficulty', 'duration', 'language', 'capacity', )
        widgets = {
            'desc': SummernoteInplaceWidget(),
            'comment': SummernoteInplaceWidget(),
        }

        labels = {
            'title': _('Title'),
            'type': _('Type'),
            'brief': _('Brief'),
            'desc': _('Detailed description'),

            'difficulty': _('Session difficulty'),
            'duration': _('Session duration'),
            'language': _('Language'),
            'capacity': _('Capacity'),
        } def sendEmailToken(request, token):
    variables = Context({
        'request': request,
        'token': token,
    })
    html = get_template('mail/token_html.html').render(variables)
    text = get_template('mail/token_text.html').render(variables)

    msg = EmailMultiAlternatives(
        settings.EMAIL_LOGIN_TITLE,
        text,
        settings.EMAIL_SENDER,
        [token.email])
    msg.attach_alternative(html, "text/html")
    msg.send(fail_silently=False) class Room(models.Model):
    name = models.CharField(max_length=100)
    location = models.CharField(max_length=255, null=True, blank=True)
    desc = models.TextField(null=True, blank=True)

    def get_absolute_url(self):
        return reverse('room', args=[self.id])

    def __unicode__(self):
        return self.name class Program(models.Model):
    name = models.CharField(max_length=255, db_index=True)
    brief = models.TextField(null=True, blank=True)
    desc = models.TextField(null=True, blank=True)
    slide_url = models.CharField(max_length=255, null=True, blank=True)
    pdf_url = models.CharField(max_length=255, null=True, blank=True)
    video_url = models.CharField(max_length=255, null=True, blank=True)
    speakers = models.ManyToManyField(Speaker, blank=True)
    difficulty = models.CharField(max_length=1,
                                  choices=(
                                      ('B', _('Beginner')),
                                      ('I', _('Intermediate')),
                                      ('E', _('Experienced')),
                                  ), default='B')

    duration = models.CharField(max_length=1,
                                choices=(
                                    ('S', _('25 mins')),
                                    ('L', _('40 mins')),
                                ), default='S')

    language = models.CharField(max_length=1,
                                choices=(
                                    ('E', _('English')),
                                    ('K', _('Korean')),
                                ), default='E')

    date = models.ForeignKey(ProgramDate, null=True, blank=True)
    rooms = models.ManyToManyField(Room, blank=True)
    times = models.ManyToManyField(ProgramTime, blank=True)
    category = models.ForeignKey(ProgramCategory, null=True, blank=True)

    is_recordable = models.BooleanField(default=True)

    def get_absolute_url(self):
        return reverse('program', args=[self.id])

    def room(self):
        rooms = self.rooms.all()

        if rooms.count() == Room.objects.all().count():
            return ''

        return ', '.join([_.name for _ in self.rooms.all()])

    def begin_time(self):
        return self.times.all()[0].begin.strftime("%H:%M")

    def get_speakers(self):
        return ', '.join([u'{}({})'.format(_.name, _.email) for _ in self.speakers.all()])
    get_speakers.short_description = u'Speakers'

    def get_times(self):
        times = self.times.all()

        if times:
            return '%s - %s' % (times[0].begin.strftime("%H:%M"),
                                times[len(times) - 1].end.strftime("%H:%M"))
        else:
            return _("Not arranged yet")

    def __unicode__(self):
        return self.name class ProgramDate(models.Model):
    day = models.DateField()

    def __unicode__(self):
        return _date(self.day, "Y-m-d (D)") class ProgramTime(models.Model):
    name = models.CharField(max_length=100)
    begin = models.TimeField()
    end = models.TimeField()

    def __meta__(self):
        ordering = ['begin']

    def __unicode__(self):
        return '%s - %s / %s' % (self.begin, self.end, self.name) class ProgramCategory(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    slug = models.SlugField(max_length=100, unique=True)

    show_in_mobile = models.BooleanField(default=True)
    show_in_list = models.BooleanField(default=True)

    def __unicode__(self):
        return self.name class Speaker(models.Model):
    slug = models.SlugField(max_length=100, unique=True)
    name = models.CharField(max_length=100, db_index=True)
    organization = models.CharField(max_length=100, null=True, blank=True)
    email = models.EmailField(max_length=255, db_index=True,
                              null=True, blank=True)
    image = models.ImageField(upload_to='speaker', null=True, blank=True)
    desc = models.TextField(null=True, blank=True)
    info = JSONField(blank=True, help_text=_('help-text-for-speaker-info'))

    class Meta:
        ordering = ['name']

    def get_badges(self, size_class=""):
        badge = \
            '<a class="btn btn-social btn-social-default {} btn-{}" href="{}" target="_blank">' \
            '<i class="fa fa-external-link fa-{}"></i>{}</a>'
        fa_replacement = {
            "homepage": "home",
            "blog": "pencil",
        }
        result = []
        for site, url in self.info.iteritems():
            result.append(badge.format(
                size_class,
                site, url,
                fa_replacement.get(site, site), site.capitalize()
            ))
        return '<div class="badges">{}</div>'.format(' '.join(result))

    def get_badges_xs(self):
        return self.get_badges("btn-xs")

    def get_absolute_url(self):
        return reverse('speaker', args=[self.slug])

    def get_image_url(self):
        if self.image:
            return self.image.url

        return static('image/anonymous.png')

    def __unicode__(self):
        return '%s / %s' % (self.name, self.slug) class Sponsor(models.Model):
    slug = models.SlugField(max_length=100, unique=True)
    name = models.CharField(max_length=100, db_index=True)
    image = models.ImageField(upload_to='sponsor', null=True, blank=True)
    url = models.CharField(max_length=255, null=True, blank=True)
    desc = models.TextField(null=True, blank=True)
    level = models.ForeignKey(SponsorLevel, null=True, blank=True)

    class Meta:
        ordering = ['id']

    def get_absolute_url(self):
        return reverse('sponsor', args=[self.slug])

    def __unicode__(self):
        return self.name class Announcement(models.Model):
    title = models.CharField(max_length=100, db_index=True)
    desc = models.TextField(null=True, blank=True)

    announce_after = models.DateTimeField(null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-id']

    def at(self):
        return self.announce_after if self.announce_after else self.created

    def __unicode__(self):
        return self.title class Preference(models.Model):
    user = models.ForeignKey(User)
    program = models.ForeignKey(Program)

    class Meta:
        unique_together = ('user', 'program') class TutorialProposal(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    title = models.CharField(max_length=255)
    brief = models.TextField(max_length=1000)
    desc = models.TextField()
    comment = models.TextField(max_length=4000, null=True, blank=True)

    type = models.CharField(max_length=1,
                            default='T',
                            choices=(
                                ('T', _('Tutorial')),
                                ('S', _('Sprint')),
                            ))

    difficulty = models.CharField(max_length=1,
                                  choices=(
                                      ('B', _('Beginner')),
                                      ('I', _('Intermediate')),
                                      ('E', _('Experienced')),
                                  ))

    duration = models.CharField(max_length=1,
                                choices=(
                                    ('S', _('1 hour')),
                                    ('M', _('2 hours')),
                                    ('L', _('4 hours')),
                                ))

    language = models.CharField(max_length=1,
                                choices=(
                                    ('E', _('English')),
                                    ('K', _('Korean')),
                                ),
                                default='E')

    capacity = models.CharField(max_length=1,
                                choices=(
                                    ('S', _('10 people')),
                                    ('M', _('45 people')),
                                    ('L', _('100 people')),
                                ))

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('tutorial', args=[self.id]) class EmailToken(models.Model):
    email = models.EmailField(max_length=255)
    token = models.CharField(max_length=64, unique=True)
    created = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        self.token = str(uuid4())
        super(EmailToken, self).save(*args, **kwargs) class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    phone = models.CharField(max_length=100, null=True, blank=True)
    organization = models.CharField(max_length=100, null=True, blank=True)
    nationality = models.CharField(max_length=100, null=True, blank=True)
    image = SorlImageField(upload_to='profile', null=True, blank=True)
    bio = models.TextField(max_length=4000, null=True, blank=True)

    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            Profile.objects.create(user=instance)

    def get_absolute_url(self):
        return reverse('profile')

    @property
    def is_empty(self):
        return self.name == '' or self.phone is None or self.organization is None or self.bio is None class Proposal(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    title = models.CharField(max_length=255)
    brief = models.TextField(max_length=1000)
    desc = models.TextField(max_length=4000)
    comment = models.TextField(max_length=4000, null=True, blank=True)

    difficulty = models.CharField(max_length=1,
                                  choices=(
                                      ('B', _('Beginner')),
                                      ('I', _('Intermediate')),
                                      ('E', _('Experienced')),
                                  ))

    duration = models.CharField(max_length=1,
                                choices=(
                                    ('S', _('25 mins')),
                                    ('L', _('40 mins')),
                                ))

    language = models.CharField(max_length=1,
                                choices=(
                                    ('E', _('English')),
                                    ('K', _('Korean')),
                                ),
                                default='E')

    def __unicode__(self):
        return self.title class TutorialCheckin(models.Model):
    user = models.ForeignKey(User)
    tutorial = models.ForeignKey(TutorialProposal)

    class Meta:
        unique_together = ('user', 'tutorial') class Registration(models.Model):
    user = models.ForeignKey(User)
    merchant_uid = models.CharField(max_length=32)
    option = models.ForeignKey(Option, null=True)
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=255)
    company = models.CharField(max_length=100, blank=True)
    phone_number = models.CharField(max_length=20)
    transaction_code = models.CharField(max_length=36, blank=True)
    additional_price = models.IntegerField(default=0)
    payment_method = models.CharField(
        max_length=20,
        default='card',
        choices=(
            ('card', u'Credit Card'),
            ('bank', u'Bank Transfer'),
            ('vbank', u'Virtual Bank Transfer'),
        )
    )
    payment_status = models.CharField(
        max_length=10,
        default='ready',
        choices=(
            ('ready', u'Ready'),
            ('paid', u'Paid'),
            ('deleted', u'Deleted'),
            ('cancelled', u'Cancelled'),
        )
    )
    payment_message = models.CharField(max_length=255, null=True, blank=True)
    vbank_num = models.CharField(max_length=255, null=True, blank=True)
    vbank_name = models.CharField(max_length=20, null=True, blank=True)
    vbank_date = models.CharField(max_length=50, null=True, blank=True)
    vbank_holder = models.CharField(max_length=20, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    confirmed = models.DateTimeField(null=True, blank=True)
    canceled = models.DateTimeField(null=True, blank=True) class Option(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()
    is_active = models.BooleanField(default=False)
    price = models.IntegerField()
    has_additional_price = models.BooleanField(default=False)
    total = models.IntegerField(default=500)

    @property
    def is_soldout(self):
        return self.total <= Registration.objects.filter(option=self, payment_status__in=['paid', 'ready']).count()

    def __unicode__(self):
        return self.name
import logging
import random
from django.contrib import messages
from django.contrib.auth import login as user_login, logout as user_logout
from django.contrib.auth.models import User
from django.contrib.flatpages.models import FlatPage
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from django.views.generic import ListView, DetailView, UpdateView, CreateView
from datetime import datetime, timedelta
from .forms import (EmailLoginForm, SpeakerForm, ProgramForm,
                    ProposalForm, ProfileForm, TutorialProposalForm)
from .helper import sendEmailToken
from .models import (Room, Program, ProgramDate, ProgramTime, ProgramCategory,
                     Speaker, Sponsor, Announcement, Preference, TutorialProposal,
                     EmailToken, Profile, Proposal, TutorialCheckin)
from registration.models import Registration, Option
# -*- coding: utf-8 -*-

logger = logging.getLogger(__name__)
payment_logger = logging.getLogger('payment')


def index(request):
    return render(request, 'index.html', {
        'index': True,
        'base_content': FlatPage.objects.get(url='/index/').content,
        'recent_announcements': Announcement.objects.all()[:3],
    })


def schedule(request):
    dates = ProgramDate.objects.all()
    times = ProgramTime.objects.all()

    rooms = Room.objects.all()