Commit 1a281be9 authored by stef's avatar stef

[enh] implemented email verification, + index tablesorting

parent 6611ec9d
...@@ -61,6 +61,7 @@ class Violation(models.Model): ...@@ -61,6 +61,7 @@ class Violation(models.Model):
contractual = models.BooleanField() contractual = models.BooleanField()
contract_excerpt = models.TextField() contract_excerpt = models.TextField()
loophole = models.BooleanField() loophole = models.BooleanField()
activationid= models.CharField(max_length=128)
class Comment(models.Model): class Comment(models.Model):
submitter_email = models.EmailField() submitter_email = models.EmailField()
......
...@@ -6,10 +6,13 @@ from django.core.files import File ...@@ -6,10 +6,13 @@ from django.core.files import File
from django.conf import settings from django.conf import settings
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.contrib import messages
from models import Violation, Attachment, Comment from models import Violation, Attachment, Comment
from tempfile import mkstemp from tempfile import mkstemp
from datetime import datetime from datetime import datetime
import hashlib, os, re, json, hashlib import hashlib, os, re, json, smtplib
from random import randint
from email.mime.text import MIMEText
from urlparse import urljoin from urlparse import urljoin
from BeautifulSoup import BeautifulSoup, Comment as BComment from BeautifulSoup import BeautifulSoup, Comment as BComment
...@@ -38,10 +41,25 @@ def sanitizeHtml(value, base_url=None): ...@@ -38,10 +41,25 @@ def sanitizeHtml(value, base_url=None):
return soup.renderContents().decode('utf8') return soup.renderContents().decode('utf8')
def activate(request):
v=Violation.objects.get(activationid=request.GET.get('key','asdf'))
v.activationid=''
v.save()
messages.add_message(request, messages.INFO, 'Thank you for verifying your submission.')
return HttpResponseRedirect('/') # Redirect after POST
def add(request): def add(request):
if request.method == 'POST': if request.method == 'POST':
form = AddViolation(request.POST) form = AddViolation(request.POST)
if form.is_valid(): if form.is_valid():
actid = hashlib.sha1(''.join([chr(randint(32, 122)) for x in range(12)])).hexdigest()
msg = MIMEText("Your verification key is %s/activate?key=%s\n" % (settings.ROOT_URL or 'http://localhost:8001/',actid))
msg['Subject'] = 'NNMon submission verification'
msg['From'] = 'nnmon@nnmon.lqdn.fr'
msg['To'] = form.cleaned_data['email']
s = smtplib.SMTP('localhost')
s.sendmail('nnmon@nnmon.lqdn.fr', [form.cleaned_data['email']], msg.as_string())
s.quit()
v=Violation( v=Violation(
country = form.cleaned_data['country'], country = form.cleaned_data['country'],
operator = form.cleaned_data['operator'], operator = form.cleaned_data['operator'],
...@@ -53,7 +71,8 @@ def add(request): ...@@ -53,7 +71,8 @@ def add(request):
temporary = form.cleaned_data['temporary'], temporary = form.cleaned_data['temporary'],
contractual = form.cleaned_data['contractual'], contractual = form.cleaned_data['contractual'],
contract_excerpt = sanitizeHtml(form.cleaned_data['contract_excerpt']), contract_excerpt = sanitizeHtml(form.cleaned_data['contract_excerpt']),
loophole = form.cleaned_data['loophole'] loophole = form.cleaned_data['loophole'],
activationid = actid
) )
v.save() v.save()
c = Comment( c = Comment(
...@@ -72,6 +91,8 @@ def add(request): ...@@ -72,6 +91,8 @@ def add(request):
sname=m.hexdigest() sname=m.hexdigest()
a.storage.save(sname,f) a.storage.save(sname,f)
a.save() a.save()
messages.add_message(request, messages.INFO, 'Thank you for submitting this report, you will receive a verification email shortly.')
return HttpResponseRedirect('/') # Redirect after POST return HttpResponseRedirect('/') # Redirect after POST
else: else:
form = AddViolation() form = AddViolation()
...@@ -83,12 +104,12 @@ def add(request): ...@@ -83,12 +104,12 @@ def add(request):
def ajax(request, country=None, operator=None): def ajax(request, country=None, operator=None):
if not operator: if not operator:
return HttpResponse(json.dumps(sorted(list(set([x.operator for x in Violation.objects.filter(country=country)]))))) return HttpResponse(json.dumps(sorted(list(set([x.operator for x in Violation.objects.filter(country=country,activationid='')])))))
else: else:
return HttpResponse(json.dumps(sorted(list(set([x.contract for x in Violation.objects.filter(country=country).filter(operator=operator)]))))) return HttpResponse(json.dumps(sorted(list(set([x.contract for x in Violation.objects.filter(country=country,activationid='',operator=operator)])))))
def index(request): def index(request):
v_list = Violation.objects.all() v_list = Violation.objects.filter(activationid='')
paginator = Paginator(v_list, 25) paginator = Paginator(v_list, 25)
page = request.GET.get('page','1') page = request.GET.get('page','1')
...@@ -99,7 +120,7 @@ def index(request): ...@@ -99,7 +120,7 @@ def index(request):
except EmptyPage: except EmptyPage:
violations = paginator.page(paginator.num_pages) violations = paginator.page(paginator.num_pages)
return render_to_response('list.html', {"violations": violations}) return render_to_response('list.html', {"violations": violations},context_instance=RequestContext(request))
def view(request,id): def view(request,id):
v = get_object_or_404(Violation, pk=id) v = get_object_or_404(Violation, pk=id)
......
...@@ -23,3 +23,43 @@ li { list-style: none; } ...@@ -23,3 +23,43 @@ li { list-style: none; }
table.listing, .pagination { width: 90%; margin: auto; } table.listing, .pagination { width: 90%; margin: auto; }
table.listing thead td { font-weight: bold; border-bottom: 1px solid black; } table.listing thead td { font-weight: bold; border-bottom: 1px solid black; }
/* tables */
table.tablesorter {
font-family:arial;
background-color: #CDCDCD;
margin:10px 0pt 15px;
font-size: 8pt;
width: 100%;
text-align: left;
}
table.tablesorter thead tr th, table.tablesorter tfoot tr th {
background-color: #e6EEEE;
border: 1px solid #FFF;
font-size: 8pt;
padding: 4px;
}
table.tablesorter thead tr .header {
background-image: url(/site_media/img/bg.gif);
background-repeat: no-repeat;
background-position: center right;
cursor: pointer;
}
table.tablesorter tbody td {
color: #3D3D3D;
padding: 4px;
background-color: #FFF;
vertical-align: top;
}
table.tablesorter tbody tr.odd td {
background-color:#F0F0F6;
}
table.tablesorter thead tr .headerSortUp {
background-image: url(/site_media/img/asc.gif);
}
table.tablesorter thead tr .headerSortDown {
background-image: url(/site_media/img/desc.gif);
}
table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
background-color: #8dbdd8;
}
...@@ -173,6 +173,8 @@ LOGIN_REDIRECT_URL = '/' ...@@ -173,6 +173,8 @@ LOGIN_REDIRECT_URL = '/'
CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',) CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',)
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge' CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
try: try:
from local_settings import * from local_settings import *
except: except:
......
...@@ -5,27 +5,36 @@ ...@@ -5,27 +5,36 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="{%media_url%}/js/jquery.1.4.2.min.js"></script> <script type="text/javascript" src="{%media_url%}/js/jquery.1.4.2.min.js"></script>
<script type="text/javascript"> <script type="text/javascript" src="{%media_url%}/js/jquery.tablesorter.min.js"> </script>
$(document).ready(function(){ <script type="text/javascript">
}); $(document).ready(function() {
</script> $("#sortedlist").tablesorter();
});
</script>
{% endblock %} {% endblock %}
{%block content%} {%block content%}
<table class="listing"> {% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<table class="listing tablesorter" id='sortedlist'>
<thead> <thead>
<tr> <tr>
<td>id</td> <th>id</th>
<td>country</td> <th>country</th>
<td>operator</td> <th>operator</th>
<td>contract</td> <th>contract</th>
<td>resource</td> <th>resource</th>
<td>type</td> <th>type</th>
<td>media</td> <th>media</th>
<td>temporary</td> <th>temporary</th>
<td>contractual</td> <th>contractual</th>
<td>contractual_excerpt</td> <th>contractual_excerpt</th>
<td>loophole</td> <th>loophole</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
......
...@@ -10,6 +10,7 @@ urlpatterns = patterns('', ...@@ -10,6 +10,7 @@ urlpatterns = patterns('',
(r'^ajax/(?P<country>[^/]*)(/(?P<operator>[^/]*))?$', bt.ajax), (r'^ajax/(?P<country>[^/]*)(/(?P<operator>[^/]*))?$', bt.ajax),
(r'^add/$', bt.add), (r'^add/$', bt.add),
(r'^view/(?P<id>[0-9]*)$', bt.view), (r'^view/(?P<id>[0-9]*)$', bt.view),
(r'^activate/$', bt.activate),
(r'^accounts/logout$', 'django.contrib.auth.views.logout', {'next_page' : '/'}), (r'^accounts/logout$', 'django.contrib.auth.views.logout', {'next_page' : '/'}),
(r'^accounts/', include('registration.urls')), (r'^accounts/', include('registration.urls')),
(r'^comments/', include('django.contrib.comments.urls')), (r'^comments/', include('django.contrib.comments.urls')),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment