Move the remanants of the profiles app into the local app for more caminus-only bits

This commit is contained in:
Trever Fischer
2012-03-10 19:14:19 -05:00
parent 77314a81e7
commit 8ee0ce3365
25 changed files with 284 additions and 194 deletions

View File

@@ -5,5 +5,11 @@ class CurrencyAdmin(admin.ModelAdmin):
list_display = ('profile', 'balance')
search_fields = ('profile__mc_username',)
class InviteAdmin(admin.ModelAdmin):
list_display = ('code', 'creator', 'claimer', 'deleted')
search_fields = ('code', 'creator', 'claimer')
list_filter = ('deleted',)
admin.site.register(models.CurrencyAccount, CurrencyAdmin)
admin.site.register(models.Quote)
admin.site.register(models.Invite, InviteAdmin)

13
local/forms.py Normal file
View File

@@ -0,0 +1,13 @@
from django import forms
from django.contrib.auth.models import User
import models
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

@@ -0,0 +1,98 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from django.db.utils import DatabaseError
class Migration(SchemaMigration):
def forwards(self, orm):
try:
db.rename_table('profiles_invite', 'local_invite')
except DatabaseError, e:
# Adding model 'Invite'
db.create_table('local_invite', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('code', self.gf('django.db.models.fields.CharField')(max_length=30)),
('creator', self.gf('django.db.models.fields.related.ForeignKey')(related_name='invites', to=orm['auth.User'])),
('claimer', self.gf('django.db.models.fields.related.OneToOneField')(blank=True, related_name='claimed_invite', unique=True, null=True, to=orm['auth.User'])),
('deleted', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('local', ['Invite'])
def backwards(self, orm):
# Deleting model 'Invite'
db.rename_table('local_invite', 'profiles_invite')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'local.currencyaccount': {
'Meta': {'object_name': 'CurrencyAccount'},
'balance': ('django.db.models.fields.FloatField', [], {'default': '3000'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'profile': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['minecraft.MinecraftProfile']", 'unique': 'True'}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'unique': 'True', 'null': 'True'})
},
'local.invite': {
'Meta': {'ordering': "['deleted']", 'object_name': 'Invite'},
'claimer': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'claimed_invite'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.User']"}),
'code': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invites'", 'to': "orm['auth.User']"}),
'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'local.quote': {
'Meta': {'object_name': 'Quote'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'text': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'minecraft.minecraftprofile': {
'Meta': {'object_name': 'MinecraftProfile'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mc_username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['local']

View File

@@ -1,4 +1,6 @@
from django.db import models
from django.contrib.auth.models import User
import shortuuid
from minecraft.models import MinecraftProfile
from django.db.models.signals import post_save
@@ -22,6 +24,27 @@ class Quote(models.Model):
def __unicode__(self):
return self.text
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)
deleted = models.BooleanField(default=False)
def __unicode__(self):
return self.code
def save(self, *args, **kwargs):
if not self.code:
self.code = shortuuid.uuid()[:6].upper()
super(Invite, self).save(*args, **kwargs)
class Meta:
ordering = ['deleted']
@models.permalink
def get_absolute_url(self):
return ('local.views.claimInvite', [], {'code': self.code})
def create_account(sender, instance, created, **kwargs):
if created:
CurrencyAccount.objects.create(profile=instance)

View File

@@ -1,6 +1,41 @@
from django.test import TestCase
from django.contrib.auth.models import User
from django.test.client import Client
from django.core.urlresolvers import reverse
import models
class InviteTest(TestCase):
def setUp(self):
self.client = Client()
self.user = User.objects.create_user('ValidUsername', 'test@example.com')
self.user.save()
self.invite = models.Invite()
self.invite.creator = self.user
self.invite.save()
def tearDown(self):
self.invite.delete()
self.user.delete()
def testTryBadInvite(self):
resp = self.client.get(reverse('local.views.claimInvite', kwargs={'code':self.invite.code+"-invalid"}), follow=True)
self.assertEqual(404, resp.status_code)
def testTryToReuseInvite(self):
self.invite.claimer = self.user
self.invite.save()
resp = self.client.get(reverse('local.views.claimInvite', kwargs={'code':self.invite.code}), follow=True)
self.assertEqual(404, resp.status_code)
def testTryToUseDeletedInvite(self):
self.invite.deleted = True
self.invite.save()
resp = self.client.get(reverse('local.views.claimInvite', kwargs={'code':self.invite.code}), follow=True)
self.assertEqual(404, resp.status_code)
def testUseInvite(self):
resp = self.client.get(reverse('local.views.claimInvite', kwargs={'code':self.invite.code}), follow=True)
self.assertEqual(200, resp.status_code)
class AccountCreationTest(TestCase):
def testCreation(self):

16
local/urls.py Normal file
View File

@@ -0,0 +1,16 @@
from django.conf.urls.defaults import patterns, include, url
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('local',
url(r'^me$', 'views.profile', name='user_profile'),
url(r'^list$', 'views.list'),
url(r'^register', 'views.register'),
url(r'^invites/claim$', 'views.claimInvite'),
url(r'^invites/claim/(?P<code>.+)$', 'views.claimInvite'),
url(r'^invites/delete/(?P<code>.+)$', 'views.deleteInvite'),
url(r'^invites/new$', 'views.createInvite'),
url(r'^invites$', 'views.invites'),
url(r'^edit$', 'views.edit'),
url(r'^disabled$', direct_to_template, {'template': 'local/disabled.html'}, name='disabled_account')
)

View File

@@ -1 +1,105 @@
# Create your views here.
from django.contrib.auth.decorators import login_required
from django.contrib.sites.models import Site
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
import django.contrib.auth
from django.contrib.auth import authenticate, login
from django.core.exceptions import ObjectDoesNotExist
import forms
import models
from minecraft.forms import ProfileForm
@login_required
def profile(request):
return render_to_response('local/profile.html', context_instance = RequestContext(request))
@login_required
def edit(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user.minecraftprofile)
else:
form = ProfileForm(instance=request.user.minecraftprofile)
if form.is_valid():
profile = request.user.minecraftprofile
profile.mc_username = form.cleaned_data['mc_username']
profile.save()
return HttpResponseRedirect(reverse('local.views.profile'))
return render_to_response('local/edit.html', {"form":form}, context_instance = RequestContext(request))
@login_required
def invites(request):
invites = request.user.invites.all()
return render_to_response('local/invites.html', {'invites': invites}, context_instance = RequestContext(request))
@login_required
def createInvite(request):
invite = models.Invite()
invite.creator = request.user
invite.save()
return HttpResponseRedirect(reverse('local.views.invites'))
def register(request):
invite = request.session['profile-invite']
if request.method == 'POST':
userForm = forms.UserForm(request.POST, prefix='user')
profileForm = ProfileForm(request.POST, prefix='profile')
else:
userForm = forms.UserForm(prefix='user')
profileForm = ProfileForm(prefix='profile')
if userForm.is_valid() and profileForm.is_valid():
oldUser = None
try:
oldUser = User.objects.get(username__exact=userForm.cleaned_data['username'])
except ObjectDoesNotExist, e:
pass
if not oldUser:
user = User.objects.create_user(userForm.cleaned_data['username'], userForm.cleaned_data['email'], userForm.cleaned_data['password'])
user.save()
invite.claimer = user
invite.save()
profile = user.minecraftprofile
profile.mc_username = profileForm.cleaned_data['mc_username']
profile.save()
user = authenticate(username=userForm.cleaned_data['username'], password=userForm.cleaned_data['password'])
login(request, user)
del request.session['profile-invite']
return HttpResponseRedirect("/")
return render_to_response('local/register.html', {'userForm': userForm, 'profileForm': profileForm, 'invite':invite}, context_instance = RequestContext(request))
@login_required
def deleteInvite(request, code=None):
invite = models.Invite.objects.get(code__exact=code)
if invite.claimer:
return HttpResponseRedirect(reverse('local.views.invites'))
if request.method == 'POST':
invite.deleted = True
invite.save()
return HttpResponseRedirect(reverse('local.views.invites'))
return render_to_response('local/delete_invite.html', {'invite':invite}, context_instance = RequestContext(request))
def claimInvite(request, code=None):
if request.user.is_authenticated():
invite = models.Invite.objects.get(code__exact=code)
siteURL = Site.objects.get_current().domain
return render_to_response('local/show_invite.html', {'invite':invite, 'site_url': siteURL}, 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:
try:
invite = models.Invite.objects.get(code__exact=code, claimer__exact=None, deleted__exact=False)
except models.Invite.DoesNotExist:
raise Http404
request.session['profile-invite'] = invite
return HttpResponseRedirect(reverse('local.views.register'))
return render_to_response('local/claim_invite.html', {'form': form}, context_instance = RequestContext(request))
def list(request):
profiles = User.objects.all()
return render_to_response('local/list.html', {'profiles': profiles}, context_instance = RequestContext(request))