Commit 110b4e5b authored by stef's avatar stef
Browse files

[enh] added email+attachments

parent 8c063369
......@@ -2,6 +2,7 @@ from django import forms
from django.conf import settings
from django.utils.translation import ugettext as _
from bt.models import Violation, COUNTRIES, RESOURCES, TYPES, MEDIA
from bt.multifile import MultiFileField
from operator import itemgetter
class AdvancedEditor(forms.Textarea):
......@@ -19,6 +20,8 @@ class AddViolation(forms.Form):
operator = forms.CharField(required=True, max_length=256, help_text=_('The ISP or operator providing the Internet service.'))
contract = forms.CharField(required=True, max_length=256, help_text=_('The specific contract at the ISP provider. (please be as specific as possible)'))
comment = forms.CharField(required=True, widget=AdvancedEditor(), help_text=_('Please describe the symptoms you are experiencing. What service or site, or person is unavailable or seems artificially slowed down.'))
email = forms.EmailField(required=True, help_text=_("We need your email to validate your report. We're not storing the email later on."))
attachments = MultiFileField(required=False, help_text=_("Attach screenshot, document or any other relevant information."))
resource = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(RESOURCES,key=itemgetter(1))), help_text=_('The what is the affected resource.'))
resource_name = forms.CharField(required=False, max_length=4096, help_text=_('Please specify the name of the affected resource.'))
type = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(TYPES,key=itemgetter(1))), help_text=_('Is the Resource Blocked or otherwise discrimated?'))
A newforms widget and field to allow multiple file uploads.
Created by Edward Dale (
Released into the Public Domain
from django.utils.encoding import force_unicode
from django.utils.datastructures import MultiValueDict
from django.utils.translation import ugettext
from django.forms.fields import Field, EMPTY_VALUES
from django.core.files.uploadedfile import UploadedFile
from django.forms.widgets import FileInput
from django.forms.util import ErrorList, ValidationError, flatatt
class MultiFileInput(FileInput):
A widget to be used by the MultiFileField to allow the user to upload
multiple files at one time.
def __init__(self, attrs=None, *args, **kwargs):
Create a MultiFileInput.
The 'count' attribute can be specified to default the number of
file boxes initially presented.
super(MultiFileInput, self).__init__(attrs, *args, **kwargs)
self.attrs = {'count':1}
if attrs:
def render(self, name, value, attrs=None):
Renders the MultiFileInput.
Should not be overridden. Instead, subclasses should override the
js, link, and/or fields methods which provide content to this method.
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name+'[]')
count = final_attrs['count']
if count<1: count=1
del final_attrs['count']
js = self.js(name, value, count, final_attrs)
link =, value, count, final_attrs)
fields = self.fields(name, value, count, final_attrs)
return js+link+fields
def fields(self, name, value, count, attrs=None):
Renders the necessary number of file input boxes.
return u''.join([u'<input class="attachments"%s />\n' % flatatt(dict(attrs, id=attrs['id']+str(i))) for i in range(count)])
def link(self, name, value, count, attrs=None):
Renders a link to add more file input boxes.
return u"<a id='add_attach' onclick=\"javascript:new_%(name)s()\">+</a>" % {'name':name}
def js(self, name, value, count, attrs=None):
Renders a bit of Javascript to add more file input boxes.
return u"""
function new_%(name)s() {
""" % {'id':attrs['id'], 'name':name, 'count':count}
def value_from_datadict(self, data, files, name):
File widgets take data from FILES, not POST.
name = name+'[]'
if isinstance(files, MultiValueDict):
return files.getlist(name)
return None
def id_for_label(self, id_):
The first file input box always has a 0 appended to it's id.
if id_:
id_ += '0'
return id_
id_for_label = classmethod(id_for_label)
class MultiFileField(Field):
A field allowing users to upload multiple files at once.
widget = MultiFileInput
count = 1
def __init__(self, count=1, strict=False, *args, **kwargs):
strict is whether the number of files uploaded must equal count
self.count = count
self.strict = strict
super(MultiFileField, self).__init__(*args, **kwargs)
def widget_attrs(self, widget):
Adds the count to the MultiFileInput widget.
if isinstance(widget, MultiFileInput):
return {'count':self.count}
return {}
def clean(self, data):
Cleans the data and makes sure that all the files had some content.
Also checks whether a file was required.
super(MultiFileField, self).clean(data)
if not self.required and data in EMPTY_VALUES:
return None
f = map(lambda a: UploadedFile(a['filename'], a['content']), data)
except TypeError:
raise ValidationError(ugettext(u"No file was submitted. Check the encoding type on the form."))
except KeyError:
raise ValidationError(ugettext(u"No file was submitted."))
for a_file in f:
if not a_file.content:
raise ValidationError(ugettext(u"The submitted file is empty."))
if self.strict and len(f) != self.count:
raise ValidationError(ugettext(u"An incorrect number of files were uploaded."))
return f
class FixedMultiFileInput(MultiFileInput):
A MultiFileInput widget that doesn't print the javascript code to allow
the user to add more file input boxes.
def link(self, name, value, count, attrs=None):
return u''
def js(self, name, value, count, attrs=None):
return u''
......@@ -3,7 +3,10 @@ img { border: 0; }
h1, h2, h3, h4, div, ul { padding: 0; margin: 0; }
h2 { margin: auto; width: 50%; padding 4em; }
#addForm { margin: auto; width: 50%; padding 4em; }
.fieldWrapper { margin: 1em; }
.fieldWrapper { margin: 1em; width: 100%; }
.fieldWrapper label { width: 120px; display: inline-block; }
#show_optionals { text-decoration: underline; color: blue; cursor: pointer; }
.attachments { float: right; margin-top: 0.4em; display: block; clear: both; }
#add_attach { cursor: pointer; }
#show_optionals { text-decoration: underline; color: blue; cursor: pointer; clear: both; }
#optional { clear: both; }
.help_text { font-size: 0.7em; left: 30px; width: 20%; position: absolute; }
......@@ -35,6 +35,8 @@ $(document).ready(function(){
$('#id_contract').change(function() {
if($(this).val().length>0) {
......@@ -16,11 +16,11 @@
<h2>{% trans "New Violation" %}</h2>
<form id='addForm' name="addForm" action="{% root_url %}/add/" method="post">
{% for field in form %}
{% if field.label = 'Resource' %}<div id="show_optionals">{% trans "Show expert details" %}</div><div id="optional">{%endif%}
{% if field.label = 'Resource' %}<div id="show_optionals">{% trans "Provide optional details" %}</div><div id="optional">{%endif%}
<div class="fieldWrapper">
{{ field.errors }}
<div class="help_text">{{ field.help_text }}</div>
{{ field.label_tag }} {{ field }}
{{ field.label_tag }} {{ field|safe }}
{% endfor %}
Supports Markdown
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