docbow/docbow_project/docbow/forms.py

195 lines
6.8 KiB
Python

import os.path
from django.forms import ModelForm, Form, \
ModelMultipleChoiceField, Textarea, EmailField, \
CharField
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.contrib.admin.widgets import FilteredSelectMultiple as AdminFilteredSelectMultiple
from django.forms import ValidationError
from models import Document, username, MailingList, FileType, Content, \
AttachedFile, AutomaticForwarding
from uni_form.helpers import FormHelper, Submit, Layout, ButtonHolder
import pyuca
from widgets import TextInpuWithPredefinedValues, JqueryFileUploadInput
from fields import RecipientField
class UserChoiceField(ModelMultipleChoiceField):
def label_from_instance(self, obj):
return username(obj)
def order_choices(choices):
return sorted(list(choices),
key=lambda x: pyuca.collator.sort_key(x[1]))
def order_field_choices(field):
field.choices = order_choices(field.choices)
class RecipientForm(object):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
user_qs = kwargs.pop('user_qs', User.objects.filter())
user_qs = user_qs.filter(is_active=True, delegations_by__isnull=True)
list_qs = kwargs.pop('list_qs', MailingList.objects.all())
super(RecipientForm, self).__init__(*args, **kwargs)
self.fields['recipients'].user = user
self.fields['recipients'].user_qs = user_qs
self.fields['recipients'].list_qs = list_qs
self.fields['recipients'].reset_choices()
class ForwardingForm(RecipientForm, Form):
recipients = RecipientField(label=_('Recipients'))
layout = Layout(
'recipients',
ButtonHolder(
Submit('forward', _('forward the document'))),
)
helper = FormHelper()
helper.form_method = 'POST'
helper.add_layout(layout)
helper.form_action = ''
def max_filename_length():
field = AttachedFile._meta.get_field_by_name('content')[0]
prefix = field.generate_filename(None, '')
max_length = field.max_length
return max_length - len(prefix)
class FileForm(RecipientForm, ModelForm):
user = None
recipients = RecipientField(label=_('Recipients'))
layout = Layout(
'filetype',
'content',
'recipients',
'comment',
ButtonHolder(
Submit('send', _('send a file'))),
)
content = forms.Field(label=_('Attached files'),
widget=JqueryFileUploadInput(max_filename_length=max_filename_length()))
helper = FormHelper()
helper.form_method = 'POST'
helper.add_layout(layout)
helper.form_action = ''
def __init__(self, *args, **kwargs):
self.filetype_qs = kwargs.pop('filetype_qs', FileType.objects.all())
super(FileForm, self).__init__(*args, **kwargs)
old_widget = self.fields['comment'].widget
self.fields['comment'].widget = TextInpuWithPredefinedValues(attrs=old_widget.attrs,
choices=self.get_predefined_comments())
self.fields['filetype'].empty_label = '---'
self.fields['filetype'].queryset = self.filetype_qs
order_field_choices(self.fields['filetype'])
def get_predefined_comments(self):
choices = [ (content.description,)*2 for content in Content.objects.all() ]
choices.insert(0, ('---','---'))
return choices
class Meta:
model = Document
exclude = ('sender','date', 'to_user', 'to_list')
class Media:
css = { 'all': ('css/send-file.css', 'docbow/css/send_file_form.css'
)}
def clean(self):
cleaned_data = super(FileForm, self).clean()
upload_id, files = self.cleaned_data.get('content', (None, []))
if not files:
self._errors['content'] = self.error_class([_(u'You must attach at least one file.')])
return cleaned_data
def save_attachments(self):
instance = self.instance
upload_id, uploaded_files = self.cleaned_data.get('content', (None, []))
for uploaded_file in uploaded_files:
uploaded_file.name = os.path.basename(uploaded_file.name)
AttachedFile(document=instance,
name=os.path.basename(uploaded_file.name),
content=uploaded_file).save()
class ContactForm(Form):
layout = Layout(
'subject',
'message',
ButtonHolder(
Submit('send', _('send your message'))),
)
helper = FormHelper()
helper.form_method = 'POST'
helper.add_layout(layout)
helper.form_action = ''
subject = forms.CharField(max_length=100, label=_('Subject'),
required=True)
message = forms.CharField(widget=Textarea(attrs={'rows': 25, 'cols': 80}),
label=_('Message'), required=True)
class AnonymousContactForm(ContactForm):
layout = Layout(
'name',
'email',
'phone_number',
'subject',
'message',
ButtonHolder(
Submit('send', _('send your message'))),
)
helper = FormHelper()
helper.form_method = 'POST'
helper.add_layout(layout)
helper.form_action = ''
name = forms.CharField(max_length=100, label=_('Name'), required=True)
email = forms.EmailField(max_length=100, label=_('Email'), required=False)
phone_number = forms.CharField(max_length=100, label=_('Phone number'),
required=False)
class MailingListForm(ModelForm):
def __init__(self, *args, **kwargs):
ModelForm.__init__(self, *args, **kwargs)
self.fields['members'].queryset = User.objects.all().order_by('username')
self.fields['members'].label_from_instance = lambda y: username(y)
class Meta:
model = MailingList
widgets = {
'members': AdminFilteredSelectMultiple(_('Persons'), False),
}
class DelegationForm(Form):
layout = Layout(
'first_name', 'last_name', 'email',
ButtonHolder(
Submit('create', _('Create a new delegation'))),
)
helper = FormHelper()
helper.form_method = 'POST'
helper.add_layout(layout)
helper.form_action = ''
first_name = CharField(label=_('Firstname'))
last_name = CharField(label=_('Lastname'))
email = EmailField(label=_('Email'))
class AutomaticForwardingForm(ModelForm):
class Meta:
model = AutomaticForwarding
def clean(self):
cleaned_data = super(AutomaticForwardingForm, self).clean()
if not cleaned_data.get('forward_to_user') and not cleaned_data.get('forward_to_list'):
raise ValidationError(_('A forwarding rule must have at least one recipient, person or list.'))
return cleaned_data