# -*- encoding: utf-8 -*- from . import PAID_MEMBERSHIP_GROUP from datetime import timedelta from django.utils import timezone from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import FieldError from django.core.urlresolvers import reverse from django.db import models from django.utils.translation import ugettext as _ from imagekit.models import ImageSpecField from imagekit.processors import SmartResize from os import path from utils import OverwriteStorage import random import hashlib GENDER_CHOICES = ( ('m', _('Male')), ('f', _('Female')), ) def get_upload_path(instance, filename): ''' Erstellt den Pfad und Dateinamen für den Upload dynmisch. @param instance: The Membership Object for the uploaded image @param filename: the filename of the uploaded image ''' extension = path.splitext(filename)[1] return 'membership/%s%s' % (instance.user.username, extension) class ActivationManager(models.Manager): ''' Manages pending user registrations ''' def activate(self, activation_key): ''' searches the pending registrations for the given activation key. Set the corresponding user to active, if the key was found and the key has not expired yet.s @param activation_key: the key found in the activation email ''' try: activation_request = self.get(activation_key=activation_key) if activation_request.expired(): activation_request.user.delete() activation_request.delete() return False elif not activation_request.user.is_active: activation_request.user.is_active = True activation_request.user.save() activation_request.delete() return activation_request.user except self.model.DoesNotExist: return False def create_pending_registration(self, user): ''' creates a PendingActivation instance with an random activation key. @param user: the user that requests activation. ''' salt = str(random.random()) activation_key = hashlib.sha1(salt + user.username).hexdigest() return self.create(user=user, activation_key=activation_key) def expired(self): return self.filter( user__is_active=False, user__date_joined__lt=self.expiration_date ) class ActivationRequest(models.Model): ''' Each ActivationRequest contains an activation key and an user. The key will be send by email to the user if the user clicks on the link he can activate his in_active account. ''' user = models.ForeignKey(User, unique=True, verbose_name=_('user')) activation_key = models.CharField(_('activation key'), max_length=40) objects = ActivationManager() class Meta: verbose_name = _('pending activation') verbose_name_plural = _('pending activations') def __unicode__(self): return _("user registration for %s") % self.user def activate(self): self.user.is_active = True self.user.save() self.delete() @property def expiration_date(self): timespan = timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS) return self.user.date_joined + timespan @property def email(self): return self.user.email def expired(self): if self.user.is_active: return False elif timezone.now() >= self.expiration_date: return True else: return False expired.boolean = True @property def first_name(self): return self.user.first_name @property def last_name(self): return self.user.last_name @property def registration_date(self): return self.user.date_joined @property def username(self): return self.user.username class MembershipManager(models.Manager): def get(self, *args, **kwargs): ''' First try's to fetch the requested Membership Object from the Database, if the requestetd Membership does not Exists (yet) try to fetch the corresponding User, and create the Membership with the filled in Userdata. ''' try: if 'username' in kwargs: return models.Manager.get(self, user__username=kwargs['username'] ) else: return models.Manager.get(self, *args, **kwargs) except FieldError: user = User.objects.get(*args, **kwargs) except Membership.DoesNotExist: if 'user' in kwargs: user = User.objects.get(pk=kwargs['user'].id) else: user = User.objects.get(*args, **kwargs) membership = Membership( user=user, nickname=user.username, first_name=user.first_name, last_name=user.last_name, email=user.email ) return membership class Membership(models.Model): user = models.OneToOneField(User) nickname = models.SlugField(_('Nickname'), unique=True) gender = models.CharField( _("Gender"), max_length=1, choices=GENDER_CHOICES ) first_name = models.CharField(_("Given Name"), max_length=30) last_name = models.CharField(_("Last Name"), max_length=30) email = models.EmailField(_('Email'), unique=True) website = models.URLField(blank=True) avatar = models.ImageField( upload_to=get_upload_path, storage=OverwriteStorage(), blank=True, null=True ) membership = models.BooleanField(_('Membership'), default=False, help_text=_('Yes, I confirm that I am in agreement with the statutes \ and would like to become a member.') ) birthday = models.DateField(_("Birthday Date"), blank=True, null=True) telephone = models.CharField(_("Telephone"), max_length=30, blank=True, null=True ) street_name = models.CharField(_("Address"), max_length=75, blank=True, null=True ) post_code = models.PositiveSmallIntegerField(_("Postcode"), blank=True, null=True ) city = models.CharField(_("Town/City"), max_length=75, blank=True, null=True ) deposit = models.PositiveSmallIntegerField(default=0, editable=False) registration_date = models.DateField(auto_now_add=True, editable=False) paid_until = models.DateField(_('Paid until'), blank=True, null=True, editable=True ) confirmed = models.BooleanField(_('Confirmed'), default=False, help_text=_('This person has paid the membership fee.') ) comment = models.TextField(blank=True) objects = MembershipManager() thumbnail = ImageSpecField( processors=[SmartResize(width=60, height=60)], format='PNG', source='avatar', ) profile = ImageSpecField( processors=[SmartResize(width=140, height=140)], format='PNG', source='avatar', ) class Meta(object): ordering = ('last_name', 'first_name',) verbose_name = _('Membership') verbose_name_plural = _('Memberships') def __unicode__(self): return _('Userprofile for %s' % self.user.username) def clean(self): # Update the Profile Info from the User Object if not self.nickname: self.nickname = self.user.username if not self.first_name: self.first_name = self.user.first_name if not self.last_name: self.last_name = self.user.last_name if not self.email: self.email = self.user.email def get_absolute_url(self): return reverse('membership-details', kwargs={'username': self.user.username} ) def save(self, *args, **kwargs): super(Membership, self).save(*args, **kwargs) self.user.username = self.nickname self.user.first_name = self.first_name self.user.last_name = self.last_name self.user.email = self.email if self.confirmed: self.user.groups.add(PAID_MEMBERSHIP_GROUP) else: self.user.groups.remove(PAID_MEMBERSHIP_GROUP) self.user.save()