Commit 9b45de72 authored by Christophe Siraut's avatar Christophe Siraut

Cleanup

parent 4a168dd6
clean: clean:
find . -name "*.pyc" -exec rm {} \; find . -name "*.pyc" -exec rm {} \;
find . -name "*~" -exec rm {} \; find . -name "*~" -exec rm {} \;
find . -name ".svn" -exec rm -r {} \; find . -name ".svn" -exec rm -r {} \;
update:
git pull --rebase
python manage.py syncdb --noinput
python manage.py collectstatic --noinput
chown -R www-data .
translation: translation:
#django-admin.py makemessages -l fr #django-admin.py makemessages -l fr
python manage.py makemessages -a python manage.py makemessages -a
python manage.py compilemessages python manage.py compilemessages
lint:
#django-lint
pylint --generated-members=objects,_meta,id sondage
pylint --generated-members=objects,_meta,id accounts
...@@ -22,11 +22,11 @@ Create/update a translation file: ...@@ -22,11 +22,11 @@ Create/update a translation file:
Edit and translate the translation file: Edit and translate the translation file:
# gedit locale/fr/LC_MESSAGES/django.po # vi locale/fr/LC_MESSAGES/django.po
Compile translated messages: Compile translated messages/update a translation file:
# django-admin compilemessages # make translation
Fast installation Fast installation
================= =================
...@@ -37,9 +37,8 @@ Clone nuages archive somewhere in your home folder ...@@ -37,9 +37,8 @@ Clone nuages archive somewhere in your home folder
# cd # cd
# git clone http://git.domainepublic.net/git/nuages.git # git clone http://git.domainepublic.net/git/nuages.git
You can have local customizations in the local_settings.py file You can have local customizations in the local_settings.py file (and avoid modify the original settings.py)
# cp settings.py local_settings.py
# vi local_settings.py # vi local_settings.py
Build nuages database Build nuages database
...@@ -61,10 +60,9 @@ Copy nuages to /usr/local/lib/nuages ...@@ -61,10 +60,9 @@ Copy nuages to /usr/local/lib/nuages
# cd /usr/local/lib # cd /usr/local/lib
# git clone http://git.domainepublic.net/git/nuages.git # git clone http://git.domainepublic.net/git/nuages.git
Optionally edit project setings and set DEBUG option to False You can have local customizations in the local_settings.py file. Optionally set DEBUG option to False.
# cd /usr/local/lib/nuages # vi local_settings.py
# vi settings.py
Build nuages database Build nuages database
...@@ -94,7 +92,7 @@ There are several ways to configure Apache and python, we recommend wsgi, simply ...@@ -94,7 +92,7 @@ There are several ways to configure Apache and python, we recommend wsgi, simply
Adapt the path in file apache/django.wsgi Adapt the path in file apache/django.wsgi
Fix permission for apache user Set permission for apache user
sudo chown -R www-data /usr/local/lib/nuages sudo chown -R www-data /usr/local/lib/nuages
...@@ -114,8 +112,15 @@ Another option is to add attributes in settings.py, this make email work only wh ...@@ -114,8 +112,15 @@ Another option is to add attributes in settings.py, this make email work only wh
EMAIL_HOST_PASSWORD = 'password' EMAIL_HOST_PASSWORD = 'password'
EMAIL_USE_TLS = False EMAIL_USE_TLS = False
Migrations Update
========== ======
In order to update your nuages installation, you can issue:
# make update
Migration
=========
When models change, we need to perform some manual steps to keep existing data: When models change, we need to perform some manual steps to keep existing data:
...@@ -126,3 +131,4 @@ When models change, we need to perform some manual steps to keep existing data: ...@@ -126,3 +131,4 @@ When models change, we need to perform some manual steps to keep existing data:
# ./manage.py reset sondage accounts # ./manage.py reset sondage accounts
# ./manage.py syncdb # ./manage.py syncdb
# ./manage.py loaddata < fixture/*.json # ./manage.py loaddata < fixture/*.json
from models import * from accounts.models import UserProfile
from django.contrib import admin from django.contrib import admin
admin.site.register(UserProfile) admin.site.register(UserProfile)
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.signals import user_logged_in from django.contrib.auth.signals import user_logged_in
from django.core.exceptions import ObjectDoesNotExist
class UserProfile(models.Model): class UserProfile(models.Model):
user = models.OneToOneField(User) user = models.OneToOneField(User)
email_notifications = models.BooleanField() email_notifications = models.BooleanField()
def login_handler(user, **kwargs): def login_handler(user, **kwargs):
"""Verify user profile exists"""
try: try:
profile = UserProfile.objects.get(user=user) profile = UserProfile.objects.get(user=user)
except: except ObjectDoesNotExist:
profile = UserProfile(user=user) profile = UserProfile(user=user)
profile.save() profile.save()
return return
......
from django.conf import settings from django.conf import settings
from django.shortcuts import render, HttpResponseRedirect from django.shortcuts import render, HttpResponseRedirect
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
from accounts.forms import UserProfileForm from accounts.forms import UserProfileForm
def _(string): def _(string):
"""ugettext_lazy shortcut"""
return unicode(ugettext_lazy(string)) return unicode(ugettext_lazy(string))
def email_notify(poll, voter): def email_notify(poll, voter):
subject = _("Nuages email notification") """Send email notification"""
message = _("User %s has voted.") % voter subject = _("Nuages email notification")
message += "\n\n" message = _("User %s has voted.") % voter
message += _("The link to your poll: %s") % poll.link message += "\n\n"
message += "\n\n" message += _("The link to your poll: %s") % poll.link
message += _("Current results:") message += "\n\n"
message += "\n\n" message += _("Current results:")
for choice in poll.choice_set.all(): message += "\n\n"
message += "%s: %i\n" % (choice.choice, choice.votecount) for choice in poll.choice_set.all():
poll.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL) message += "%s: %i\n" % (choice.choice, choice.votecount)
poll.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
@login_required @login_required
def profile(request): def profile(request):
"""profile view"""
if request.method == 'POST': if request.method == 'POST':
form = UserProfileForm(request.POST) form = UserProfileForm(request.POST)
if form.is_valid(): if form.is_valid():
for k,v in form.cleaned_data.iteritems(): for k, v in form.cleaned_data.iteritems():
setattr(request.user.userprofile, k, v) setattr(request.user.userprofile, k, v)
request.user.userprofile.save() request.user.userprofile.save()
return HttpResponseRedirect(reverse('home')) return HttpResponseRedirect(reverse('home'))
......
...@@ -44,7 +44,7 @@ LANGUAGES = ( ...@@ -44,7 +44,7 @@ LANGUAGES = (
('fr', 'Francais'), ('fr', 'Francais'),
('en', 'English'), ('en', 'English'),
('nl', 'Nederlands'), ('nl', 'Nederlands'),
('ca', 'Catalan'); ('ca', 'Catalan')
) )
SITE_ID = 1 SITE_ID = 1
......
from models import * from sondage.models import Poll, Choice, Bulletin, Vote
from django.contrib import admin from django.contrib import admin
admin.site.register(Poll) admin.site.register(Poll)
......
...@@ -10,8 +10,16 @@ class PollForm(forms.ModelForm): ...@@ -10,8 +10,16 @@ class PollForm(forms.ModelForm):
fields = ('title','description') fields = ('title','description')
class ChoiceForm(forms.ModelForm): class ChoiceForm(forms.ModelForm):
choice = forms.DateTimeField(widget=forms.DateTimeInput(format='%d-%m-%Y %H:%M',attrs={'class':'hasdatepicker','size':'18',}),input_formats=['%d-%m-%Y %H:%M']) choice = forms.DateTimeField(
details = forms.CharField(required=False,max_length='200',widget=forms.TextInput(attrs={'size':'32',})) widget=forms.DateTimeInput(format='%d-%m-%Y %H:%M',
attrs={'class':'hasdatepicker','size':'18',}),
input_formats=['%d-%m-%Y %H:%M']
)
details = forms.CharField(
required=False,
max_length='200',
widget=forms.TextInput(attrs={'size':'32',})
)
class Meta: class Meta:
model = Choice model = Choice
exclude = ('poll','votecount') exclude = ('poll','votecount')
...@@ -21,7 +29,11 @@ class BulletinForm(forms.ModelForm): ...@@ -21,7 +29,11 @@ class BulletinForm(forms.ModelForm):
model = Bulletin model = Bulletin
class VoteForm(forms.ModelForm): class VoteForm(forms.ModelForm):
comment = forms.CharField(required=False,max_length=80,widget=forms.TextInput(attrs={'class':'comment'})) comment = forms.CharField(
required=False,
max_length=80,
widget=forms.TextInput(attrs={'class':'comment'})
)
choice = forms.CharField() choice = forms.CharField()
class Meta: class Meta:
model = Vote model = Vote
......
...@@ -11,13 +11,13 @@ def _createId(): ...@@ -11,13 +11,13 @@ def _createId():
class Poll(models.Model): class Poll(models.Model):
# Override django id AutoField with randomly generatyed hash # Override django id AutoField with randomly generatyed hash
id = models.CharField(primary_key=True,unique=True,max_length=8,default=_createId) id = models.CharField(primary_key=True, unique=True, max_length=8, default=_createId)
title = models.CharField(_('Title'),max_length=80) title = models.CharField(_('Title'), max_length=80)
pub_date = models.DateField(auto_now_add=True) pub_date = models.DateField(auto_now_add=True)
upd_date = models.DateField(auto_now=True) upd_date = models.DateField(auto_now=True)
author = models.CharField(max_length=40) author = models.CharField(max_length=40)
description = models.CharField(max_length=300) description = models.CharField(max_length=300)
user = models.ForeignKey(User,blank=True,null=True) user = models.ForeignKey(User, blank=True, null=True)
def __unicode__(self): def __unicode__(self):
return self.title return self.title
...@@ -29,16 +29,16 @@ class Poll(models.Model): ...@@ -29,16 +29,16 @@ class Poll(models.Model):
class Choice(models.Model): class Choice(models.Model):
poll = models.ForeignKey(Poll) poll = models.ForeignKey(Poll)
choice = models.DateTimeField() choice = models.DateTimeField()
details = models.CharField(max_length=200,blank=True) details = models.CharField(max_length=200, blank=True)
votecount = models.IntegerField(default=0,blank=True) votecount = models.IntegerField(default=0, blank=True)
class Meta: class Meta:
ordering = ['choice'] ordering = ['choice']
def __unicode__(self): def __unicode__(self):
return str(self.choice) # hacky? return str(self.choice) # hacky?
class Bulletin(models.Model): class Bulletin(models.Model):
poll = models.ForeignKey(Poll,editable=False) poll = models.ForeignKey(Poll, editable=False)
voter = models.CharField("",max_length=40) voter = models.CharField("", max_length=40)
def __unicode__(self): def __unicode__(self):
return self.voter return self.voter
...@@ -47,15 +47,9 @@ class Vote(models.Model): ...@@ -47,15 +47,9 @@ class Vote(models.Model):
choice = models.ForeignKey(Choice) choice = models.ForeignKey(Choice)
bulletin = models.ForeignKey(Bulletin) bulletin = models.ForeignKey(Bulletin)
voice = models.BooleanField() voice = models.BooleanField()
comment = models.CharField(max_length=80,blank=True) comment = models.CharField(max_length=80, blank=True)
class Meta: class Meta:
ordering = ['choice'] ordering = ['choice']
def __unicode__(self): def __unicode__(self):
return str(self.voice) return str(self.voice)
"""
# First, define the Manager subclass.
class VoteBuletin(models.Manager):
def get_query_set(self):
return super(VoteBuletin, self).get_query_set().filter(author='Roald Dahl')
"""
# Here are the views for sondage
import datetime
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response from django.shortcuts import get_object_or_404, render_to_response
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
...@@ -15,29 +12,26 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -15,29 +12,26 @@ from django.utils.translation import ugettext_lazy as _
from django.conf import settings from django.conf import settings
from accounts.views import email_notify from accounts.views import email_notify
from accounts.forms import UserProfileForm from accounts.forms import UserProfileForm
from django.core.exceptions import ObjectDoesNotExist
def new(request): def new(request):
if request.method == 'POST': # If the form has been submitted... if request.method == 'POST':
if request.user.is_authenticated(): if request.user.is_authenticated():
instance = Poll(author=str(request.user), user=request.user) instance = Poll(author=str(request.user), user=request.user)
else: else:
instance = Poll(author=str(request.user)) instance = Poll(author=str(request.user))
form = PollForm(request.POST, instance=instance) # A form bound to the POST data form = PollForm(request.POST, instance=instance)
if form.is_valid(): # All validation rules pass if form.is_valid():
poll_id = form.cleaned_data.get('title') # Process the data in form.cleaned_data new_poll = Poll(**form.cleaned_data).save()
new_poll = form.save()
key = 'is_' + new_poll.id + '_author' key = 'is_' + new_poll.id + '_author'
request.session[key] = True # This writes cookie request.session[key] = True # This writes cookie
redir = '/' + str(new_poll.id) + '/edit/choices/' redir = '/' + str(new_poll.id) + '/edit/choices/'
return HttpResponseRedirect(redir) return HttpResponseRedirect(redir)
else: else:
form = PollForm() # An unbound form form = PollForm() # An unbound form
return render_to_response('sondage/poll_form.html', {'form': form}, context_instance=RequestContext(request)) return render_to_response('sondage/poll_form.html',
{'form': form}, context_instance=RequestContext(request))
@login_required @login_required
def secure_update_object(*args, **kwargs): def secure_update_object(*args, **kwargs):
...@@ -58,7 +52,7 @@ def get_ordereditem_formset(form, formset=BaseInlineFormSet, **kwargs): ...@@ -58,7 +52,7 @@ def get_ordereditem_formset(form, formset=BaseInlineFormSet, **kwargs):
def editchoices(request, poll_id): def editchoices(request, poll_id):
poll = get_object_or_404(Poll.objects.all(),id=poll_id) poll = get_object_or_404(Poll.objects.all(), id=poll_id)
language_code = request.LANGUAGE_CODE language_code = request.LANGUAGE_CODE
error_message = '' error_message = ''
if poll.author == 'AnonymousUser': # Anonymous wants to edit his new poll if poll.author == 'AnonymousUser': # Anonymous wants to edit his new poll
...@@ -87,11 +81,10 @@ def editchoices(request, poll_id): ...@@ -87,11 +81,10 @@ def editchoices(request, poll_id):
this_choice = instance['choice'] this_choice = instance['choice']
if not instance.get('DELETE'): if not instance.get('DELETE'):
try: try:
choice = Choice.objects.get(poll=poll,choice=instance['choice']) choice = Choice.objects.get(poll=poll, choice=instance['choice'])
choice.details = instance['details'] choice.details = instance['details']
choice.save() choice.save()
except ObjectDoesNotExist:
except (KeyError, Choice.DoesNotExist):
choice = Choice(poll=poll, choice=instance['choice'], details=instance['details']) choice = Choice(poll=poll, choice=instance['choice'], details=instance['details'])
choice.save() choice.save()
# If bulletins for this poll existed before edition # If bulletins for this poll existed before edition
...@@ -102,7 +95,7 @@ def editchoices(request, poll_id): ...@@ -102,7 +95,7 @@ def editchoices(request, poll_id):
nvote.save() nvote.save()
else: else:
try: try:
choice = Choice.objects.get(poll=poll,choice=this_choice) choice = Choice.objects.get(poll=poll, choice=this_choice)
""" """
Removing a Choice will remove all childeren Vote objects. Removing a Choice will remove all childeren Vote objects.
When Django deletes an object, it emulates the behavior of When Django deletes an object, it emulates the behavior of
...@@ -110,7 +103,7 @@ def editchoices(request, poll_id): ...@@ -110,7 +103,7 @@ def editchoices(request, poll_id):
objects which had foreign keys pointing at the object to be objects which had foreign keys pointing at the object to be
deleted will be deleted along with it.""" deleted will be deleted along with it."""
choice.delete() choice.delete()
except: except :
pass pass
except: except:
# probably an empty datefield? # probably an empty datefield?
...@@ -120,7 +113,7 @@ def editchoices(request, poll_id): ...@@ -120,7 +113,7 @@ def editchoices(request, poll_id):
else: else:
#vforms=OrderedItemFormset(request.POST, instance=poll) #vforms=OrderedItemFormset(request.POST, instance=poll)
error_message = _("There are some errors in the form you posted.") error_message = _("There are some errors in the form you posted.")
vforms=instances vforms = instances
else: else:
if Choice.objects.filter(poll=poll_id).count() == 0: if Choice.objects.filter(poll=poll_id).count() == 0:
...@@ -136,7 +129,7 @@ def editchoices(request, poll_id): ...@@ -136,7 +129,7 @@ def editchoices(request, poll_id):
@login_required @login_required
def delete(request, poll_id): def delete(request, poll_id):
poll = get_object_or_404(Poll.objects.all(),id=poll_id) poll = get_object_or_404(Poll.objects.all(), id=poll_id)
if poll.author == str(request.user): if poll.author == str(request.user):
poll.delete() poll.delete()
...@@ -151,12 +144,12 @@ def make_buletin_form(poll, **kwargs): ...@@ -151,12 +144,12 @@ def make_buletin_form(poll, **kwargs):
def vote(request, poll_id): def vote(request, poll_id):
error_message = None error_message = None
poll = get_object_or_404(Poll.objects.all(),id=poll_id) poll = get_object_or_404(Poll.objects.all(), id=poll_id)
has_voted = False has_voted = False
if request.method == 'POST': if request.method == 'POST':
form = BulletinForm(request.POST,initial={'poll': poll.id,}) form = BulletinForm(request.POST, initial={'poll': poll.id,})
vforms = [ [VoteForm(request.POST, prefix=choice, instance=choice) ] for choice in Choice.objects.filter(poll=poll.id) ] vforms = [ [VoteForm(request.POST, prefix=choice, instance=choice) ] for choice in Choice.objects.filter(poll=poll.id) ]
if form.is_valid(): if form.is_valid():
...@@ -177,22 +170,22 @@ def vote(request, poll_id): ...@@ -177,22 +170,22 @@ def vote(request, poll_id):
pass pass
""" """
if not Bulletin.objects.filter(poll=poll.id,voter=voter): if not Bulletin.objects.filter(poll=poll.id, voter=voter):
bulletin = Bulletin(poll=poll,voter=voter) bulletin = Bulletin(poll=poll, voter=voter)
bulletin.save() bulletin.save()
else: else:
bulletin = Bulletin.objects.get(poll=poll.id,voter=voter) bulletin = Bulletin.objects.get(poll=poll.id, voter=voter)
for forms in vforms: for forms in vforms:
for vorm in forms: for vorm in forms:
if vorm.is_valid(): if vorm.is_valid():
try: try:
choice = Choice.objects.get(choice=vorm.cleaned_data['choice'],poll=poll) choice = Choice.objects.get(choice=vorm.cleaned_data['choice'], poll=poll)
except: except:
return HttpResponse(vorm.cleaned_data['choice']) return HttpResponse(vorm.cleaned_data['choice'])
if not Vote.objects.filter(choice=choice,bulletin=bulletin): if not Vote.objects.filter(choice=choice, bulletin=bulletin):
new = Vote(choice=choice,bulletin=bulletin,comment=vorm.cleaned_data['comment']) new = Vote(choice=choice, bulletin=bulletin, comment=vorm.cleaned_data['comment'])
if vorm.cleaned_data['voice']: if vorm.cleaned_data['voice']:
new.voice = vorm.cleaned_data['voice'] new.voice = vorm.cleaned_data['voice']
new.save() new.save()
...@@ -206,7 +199,7 @@ def vote(request, poll_id): ...@@ -206,7 +199,7 @@ def vote(request, poll_id):
request.session['name'] = voter # This writes cookie request.session['name'] = voter # This writes cookie
has_voted = True # Used to show "Forget me" has_voted = True # Used to show "Forget me"
else: else:
old = Vote.objects.get(choice=choice,bulletin=bulletin) old = Vote.objects.get(choice=choice, bulletin=bulletin)
if old.voice: if old.voice:
if not vorm.cleaned_data['voice']: if not vorm.cleaned_data['voice']:
...@@ -255,7 +248,7 @@ def vote(request, poll_id): ...@@ -255,7 +248,7 @@ def vote(request, poll_id):
we should concatenate the existing votes with empty remaing ones... we should concatenate the existing votes with empty remaing ones...
Give an empty bulletin for now. Give an empty bulletin for now.
""" """
vforms = [ [ VoteForm(initial={'choice': vote.choice,'voice': vote.voice, 'comment': vote.comment,}, prefix=vote.choice) ] for vote in Vote.objects.filter(bulletin=bulletin).order_by('choice__choice') ] vforms = [ [ VoteForm(initial={'choice': vote.choice,'voice': vote.voice, 'comment': vote.comment}, prefix=vote.choice) ] for vote in Vote.objects.filter(bulletin=bulletin).order_by('choice__choice') ]
except: except:
pass pass
...@@ -268,7 +261,7 @@ def vote(request, poll_id): ...@@ -268,7 +261,7 @@ def vote(request, poll_id):
voter = request.session.get('name') voter = request.session.get('name')
#error_message = 'Modify your vote? (clear cookie if you are not ' + voter + ')' #error_message = 'Modify your vote? (clear cookie if you are not ' + voter + ')'
try: try:
bulletin = Bulletin.objects.get(poll=poll,voter=voter) bulletin = Bulletin.objects.get(poll=poll, voter=voter)
error_message = voter + ' has voted' error_message = voter + ' has voted'
diff = len(vforms) - len(Vote.objects.filter(bulletin=bulletin)) diff = len(vforms) - len(Vote.objects.filter(bulletin=bulletin))
if diff == 0: if diff == 0:
...@@ -294,13 +287,13 @@ def exp_csv(request, poll_id): ...@@ -294,13 +287,13 @@ def exp_csv(request, poll_id):
response = HttpResponse(mimetype='text/csv') response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=nuages.csv' response['Content-Disposition'] = 'attachment; filename=nuages.csv'
poll = get_object_or_404(Poll.objects.all(),id=poll_id) poll = get_object_or_404(Poll.objects.all(), id=poll_id)
choices = Choice.objects.filter(poll=poll) choices = Choice.objects.filter(poll=poll)
bulletins = Bulletin.objects.filter(poll=poll) bulletins = Bulletin.objects.filter(poll=poll)
writer = csv.writer(response, quotechar='"', quoting=csv.QUOTE_ALL) writer = csv.writer(response, quotechar='"', quoting=csv.QUOTE_ALL)
fr = ["",] fr = ["",]
for c in choices: for c in choices:
fr.append(c) fr.append(c)
writer.writerow(fr) writer.writerow(fr)
for b in bulletins: for b in bulletins:
r = [b.voter.encode("utf-8"),] r = [b.voter.encode("utf-8"),]
......
Markdown is supported
0% or