david / django-invitation-backend (http://code.welldev.org/django-invitation/)
fork of django-invitation
A fork of django-invitation to use the new django-registration-backends branch. See http://bitbucket.org/ubernostrum/django-registr... for the reasons.
Clone this repository (size: 52.3 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-invitation-backend
| commit 26: | be8229c1326b |
| parent 25: | 7b31544810e9 |
| branch: | default |
remaining_invitations_for_user creates InvitationUser if it does not exist.
This is a fix for issue #9
http://bitbucket.org/david/django-invitation/issue/9/
Thanks zebuline for the report and patch.
django-invitation-backend /
invitation
/
models.py
| r26:be8229c1326b | 156 loc | 5.9 KB | embed / history / annotate / raw / |
|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | import os
import random
import datetime
from django.db import models
from django.conf import settings
from django.utils.http import int_to_base36
from django.utils.hashcompat import sha_constructor
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.contrib.sites.models import Site
from registration.models import SHA1_RE
class InvitationKeyManager(models.Manager):
def get_key(self, invitation_key):
"""
Return InvitationKey, or None if it doesn't (or shouldn't) exist.
"""
# Don't bother hitting database if invitation_key doesn't match pattern.
if not SHA1_RE.search(invitation_key):
return None
try:
key = self.get(key=invitation_key)
except self.model.DoesNotExist:
return None
return key
def is_key_valid(self, invitation_key):
"""
Check if an ``InvitationKey`` is valid or not, returning a boolean,
``True`` if the key is valid.
"""
invitation_key = self.get_key(invitation_key)
return invitation_key and invitation_key.is_usable()
def create_invitation(self, user):
"""
Create an ``InvitationKey`` and returns it.
The key for the ``InvitationKey`` will be a SHA1 hash, generated
from a combination of the ``User``'s username and a random salt.
"""
salt = sha_constructor(str(random.random())).hexdigest()[:5]
key = sha_constructor("%s%s%s" % (datetime.datetime.now(), salt, user.username)).hexdigest()
return self.create(from_user=user, key=key)
def remaining_invitations_for_user(self, user):
"""
Return the number of remaining invitations for a given ``User``.
"""
invitation_user, created = InvitationUser.objects.get_or_create(
inviter=user,
defaults={'invitations_remaining': settings.INVITATIONS_PER_USER})
return invitation_user.invitations_remaining
def delete_expired_keys(self):
for key in self.all():
if key.key_expired():
key.delete()
class InvitationKey(models.Model):
key = models.CharField(_('invitation key'), max_length=40)
date_invited = models.DateTimeField(_('date invited'),
default=datetime.datetime.now)
from_user = models.ForeignKey(User,
related_name='invitations_sent')
registrant = models.ForeignKey(User, null=True, blank=True,
related_name='invitations_used')
objects = InvitationKeyManager()
def __unicode__(self):
return u"Invitation from %s on %s" % (self.from_user.username, self.date_invited)
def is_usable(self):
"""
Return whether this key is still valid for registering a new user.
"""
return self.registrant is None and not self.key_expired()
def key_expired(self):
"""
Determine whether this ``InvitationKey`` has expired, returning
a boolean -- ``True`` if the key has expired.
The date the key has been created is incremented by the number of days
specified in the setting ``ACCOUNT_INVITATION_DAYS`` (which should be
the number of days after invite during which a user is allowed to
create their account); if the result is less than or equal to the
current date, the key has expired and this method returns ``True``.
"""
expiration_date = datetime.timedelta(days=settings.ACCOUNT_INVITATION_DAYS)
return self.date_invited + expiration_date <= datetime.datetime.now()
key_expired.boolean = True
def mark_used(self, registrant):
"""
Note that this key has been used to register a new user.
"""
self.registrant = registrant
self.save()
def send_to(self, email):
"""
Send an invitation email to ``email``.
"""
current_site = Site.objects.get_current()
subject = render_to_string('invitation/invitation_email_subject.txt',
{ 'site': current_site,
'invitation_key': self })
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
message = render_to_string('invitation/invitation_email.txt',
{ 'invitation_key': self,
'expiration_days': settings.ACCOUNT_INVITATION_DAYS,
'site': current_site })
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email])
class InvitationUser(models.Model):
inviter = models.ForeignKey(User, unique=True)
invitations_remaining = models.IntegerField()
def __unicode__(self):
return u"InvitationUser for %s" % self.inviter.username
def user_post_save(sender, instance, created, **kwargs):
"""Create InvitationUser for user when User is created."""
if created:
invitation_user = InvitationUser()
invitation_user.inviter = instance
invitation_user.invitations_remaining = settings.INVITATIONS_PER_USER
invitation_user.save()
models.signals.post_save.connect(user_post_save, sender=User)
def invitation_key_post_save(sender, instance, created, **kwargs):
"""Decrement invitations_remaining when InvitationKey is created."""
if created:
invitation_user = InvitationUser.objects.get(inviter=instance.from_user)
remaining = invitation_user.invitations_remaining
invitation_user.invitations_remaining = remaining-1
invitation_user.save()
models.signals.post_save.connect(invitation_key_post_save, sender=InvitationKey)
|
