Implement invite system

This commit is contained in:
Trever Fischer
2012-02-19 22:30:10 -05:00
parent 311c26e445
commit a1ca61b64a
11 changed files with 150 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
from django import forms from django import forms
from django.contrib.auth.models import User
import models import models
class ProfileForm(forms.ModelForm): class ProfileForm(forms.ModelForm):
@@ -9,3 +10,12 @@ class ProfileForm(forms.ModelForm):
class LoginForm(forms.Form): class LoginForm(forms.Form):
username = forms.CharField() username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput) password = forms.CharField(widget=forms.PasswordInput)
class UserForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField()
class InviteClaimForm(forms.Form):
code = forms.CharField()

View File

@@ -9,6 +9,16 @@ class MinecraftProfile(models.Model):
def __unicode__(self): def __unicode__(self):
return self.mc_username return self.mc_username
class Invite(models.Model):
code = models.CharField(max_length=30)
creator = models.ForeignKey(User, related_name='invites')
claimer = models.OneToOneField(User, related_name='claimed_invite', blank=True, null=True)
@models.permalink
def get_absolute_url(self):
return ('profiles.views.claimInvite', [], {'code': self.code})
class Quote(models.Model): class Quote(models.Model):
text = models.CharField(max_length=50) text = models.CharField(max_length=50)

View File

@@ -4,6 +4,11 @@ from django.views.generic.simple import direct_to_template
urlpatterns = patterns('profiles', urlpatterns = patterns('profiles',
url(r'^me$', 'views.profile', name='user_profile'), url(r'^me$', 'views.profile', name='user_profile'),
url(r'^register', 'views.register'),
url(r'^invites/claim$', 'views.claimInvite'),
url(r'^invites/claim/(?P<code>.+)$', 'views.claimInvite'),
url(r'^invites/new$', 'views.createInvite'),
url(r'^invites$', 'views.invites'),
url(r'^edit$', 'views.edit'), url(r'^edit$', 'views.edit'),
url(r'^login$', 'views.login'), url(r'^login$', 'views.login'),
url(r'^logout$', 'views.logout'), url(r'^logout$', 'views.logout'),

View File

@@ -2,10 +2,13 @@ from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
import django.contrib.auth import django.contrib.auth
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
import forms import forms
import models
import shortuuid
@login_required @login_required
def profile(request): def profile(request):
@@ -44,3 +47,53 @@ def login(request):
else: else:
return HttpResponseRedirect(reverse('disabled_account')) return HttpResponseRedirect(reverse('disabled_account'))
return render_to_response('profiles/login.html', {"login_form":form}, context_instance = RequestContext(request)) return render_to_response('profiles/login.html', {"login_form":form}, context_instance = RequestContext(request))
@login_required
def invites(request):
invites = request.user.invites.all()
return render_to_response('profiles/invites.html', {'invites': invites}, context_instance = RequestContext(request))
@login_required
def createInvite(request):
invite = models.Invite()
invite.creator = request.user
invite.code = shortuuid.uuid()[:6]
invite.save()
return HttpResponseRedirect(reverse('profiles.views.invites'))
def register(request):
invite = request.session['profile-invite']
if request.method == 'POST':
userForm = forms.UserForm(request.POST, prefix='user')
profileForm = forms.ProfileForm(request.POST, prefix='profile')
else:
userForm = forms.UserForm(prefix='user')
profileForm = forms.ProfileForm(prefix='profile')
if userForm.is_valid() and profileForm.is_valid():
user = User()
user.username = userForm.cleaned_data['username']
user.email = userForm.cleaned_data['email']
user.set_password(userForm.cleaned_data['password'])
user.save()
invite.claimer = user
invite.save()
del request.session['profile-invite']
return HttpResponseRedirect("/")
return render_to_response('profiles/register.html', {'userForm': userForm, 'profileForm': profileForm, 'invite':invite}, context_instance = RequestContext(request))
def claimInvite(request, code=None):
if request.user.is_authenticated():
invite = models.Invite.objects.get(code__exact=code)
return render_to_response('profiles/show_invite.html', {'invite':invite}, context_instance = RequestContext(request))
if request.method == 'POST':
form = forms.InviteClaimForm(request.POST)
else:
form = forms.InviteClaimForm()
if form.is_valid():
code = form.cleaned_data['code']
if code:
invite = models.Invite.objects.get(code__exact=code)
request.session['profile-invite'] = invite
return HttpResponseRedirect(reverse('profiles.views.register'))
return render_to_response('profiles/claim_invite.html', {'form': form}, context_instance = RequestContext(request))

View File

@@ -34,7 +34,7 @@
{% endif %} {% endif %}
</ul> </ul>
{% else %} {% else %}
<p>Welcome! Do you have an invite?<p> <p>Welcome! Do you have an invite? <a href="{% url profiles.views.claimInvite %}">Claim it!</a><p>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@@ -0,0 +1,11 @@
{% extends "base.html" %}
{%block title%}Claim an Invite{%endblock%}
{%block content %}
<form method="POST" action="{%url profiles.views.claimInvite%}">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Claim!"/>
</form>
{%endblock%}

View File

@@ -0,0 +1,31 @@
{% extends 'base.html' %}
{% block title %}Invites{% endblock %}
{% block content %}
<p>Your Invites:</p>
<table>
<tr class="header">
<th>Code</th>
<th>Invited User</th>
</tr>
{% if invites %}
{% for invite in invites %}
<tr>
<td><a href="{{invite.get_absolute_url}}">{{invite.code}}</a></td>
<td>{{invite.claimer}}</td>
</tr>
{% endfor %}
{% else %}
<tr class="infoBar">
<td colspan="2">No invites!</td>
</tr>
{% endif %}
<tr class="actionBar">
<td colspan="2">
<a href="{% url profiles.views.createInvite %}">Create a new invite</a>
</td>
</tr>
</table>
{% endblock %}

View File

@@ -5,4 +5,5 @@
<p>Welcome, {{ user.username }}</p> <p>Welcome, {{ user.username }}</p>
<a href="{%url profiles.views.edit %}">Edit profile</a> <a href="{%url profiles.views.edit %}">Edit profile</a>
<a href="{%url profiles.views.invites %}">Invites</a>
{%endblock%} {%endblock%}

View File

@@ -0,0 +1,12 @@
{% extends "base.html" %}
{%block title%}Register an Account{%endblock%}
{%block content %}
<form method="POST" action="{%url profiles.views.register %}">
{% csrf_token %}
{{profileForm.as_p}}
{{userForm.as_p}}
<input type="submit" value="Register!"/>
</form>
{%endblock%}

View File

@@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% block title %}Invite{% endblock %}
{% block content %}
<p>To invite a friend to Caminus, simply share them this code, or link to this page:</p>
<div id="invite-code">
<p>Code</p>
<input type="text" value="{{invite.code}}" onClick="this.select()"/>
<br />
<p>Link</p>
<input type="text" value="{{ invite.get_absolute_url }}" onClick="this.select()"/>
</div>
{% endblock %}

View File

@@ -10,7 +10,8 @@ urlpatterns = patterns('',
url(r'^admin/doc/', include('django.contrib.admindocs.urls')), url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
url(r'^forums/', include('forums.urls')), url(r'^forums/', include('forums.urls')),
url(r'^api/', include('api.urls')) url(r'^api/', include('api.urls')),
url(r'^i/(?P<code>.+)', 'profiles.views.claimInvite')
) )
urlpatterns += staticfiles_urlpatterns() urlpatterns += staticfiles_urlpatterns()