Merge branch 'stable/1.2.x'

Conflicts:
	openslides/application/models.py
	openslides/application/views.py
	openslides/participant/forms.py
	openslides/participant/views.py
This commit is contained in:
Oskar Hahn 2012-08-13 19:16:42 +02:00
commit bd64a6cb5c
20 changed files with 884 additions and 853 deletions

View File

@ -54,7 +54,7 @@ class Overview(TemplateView):
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
if not request.user.has_perm('agenda.can_manage_agenda'): if not request.user.has_perm('agenda.can_manage_agenda'):
messages.error(request, messages.error(request,
_('You are not permitted to manage the agenda.')) _('You are not authorized to manage the agenda.'))
return self.render_to_response(context) return self.render_to_response(context)
transaction.commit() transaction.commit()
for item in Item.objects.all(): for item in Item.objects.all():

View File

@ -51,16 +51,16 @@ class ApplicationImportForm(forms.Form, CssClassMixin):
) )
import_permitted = forms.BooleanField( import_permitted = forms.BooleanField(
required=False, required=False,
label=_("Import applications with status \"permitted\""), label=_("Import motions with status \"authorized\""),
help_text=_('Set the initial status for each application to ' help_text=_('Set the initial status for each motion to '
'"permitted"'), '"authorized"'),
) )
class ConfigForm(forms.Form, CssClassMixin): class ConfigForm(forms.Form, CssClassMixin):
application_min_supporters = forms.IntegerField( application_min_supporters = forms.IntegerField(
widget=forms.TextInput(attrs={'class':'small-input'}), widget=forms.TextInput(attrs={'class':'small-input'}),
label=_("Number of (minimum) required supporters for a application"), label=_("Number of (minimum) required supporters for a motion"),
initial=4, initial=4,
min_value=0, min_value=0,
max_value=8, max_value=8,
@ -69,7 +69,7 @@ class ConfigForm(forms.Form, CssClassMixin):
application_preamble = forms.CharField( application_preamble = forms.CharField(
widget=forms.TextInput(), widget=forms.TextInput(),
required=False, required=False,
label=_("Application preamble") label=_("Motion preamble")
) )
application_pdf_ballot_papers_selection = forms.ChoiceField( application_pdf_ballot_papers_selection = forms.ChoiceField(
widget=forms.Select(), widget=forms.Select(),
@ -90,17 +90,17 @@ class ConfigForm(forms.Form, CssClassMixin):
application_pdf_title = forms.CharField( application_pdf_title = forms.CharField(
widget=forms.TextInput(), widget=forms.TextInput(),
required=False, required=False,
label=_("Title for PDF document (all applications)") label=_("Title for PDF document (all motions)")
) )
application_pdf_preamble = forms.CharField( application_pdf_preamble = forms.CharField(
widget=forms.Textarea(), widget=forms.Textarea(),
required=False, required=False,
label=_("Preamble text for PDF document (all applications)") label=_("Preamble text for PDF document (all motions)")
) )
application_allow_trivial_change = forms.BooleanField( application_allow_trivial_change = forms.BooleanField(
label=_("Allow trivial changes"), label=_("Allow trivial changes"),
help_text=_('Warning: Trivial changes undermine the application ' \ help_text=_('Warning: Trivial changes undermine the motions '
'permission system.'), 'autorisation system.'),
required=False, required=False,
) )

View File

@ -50,7 +50,7 @@ class Application(models.Model, SlideMixin):
('adj', _('Adjourned')), ('adj', _('Adjourned')),
('noc', _('Not Concerned')), ('noc', _('Not Concerned')),
('com', _('Commited a bill')), ('com', _('Commited a bill')),
('nop', _('Rejected (not permitted)')), ('nop', _('Rejected (not authorized)')),
('rev', _('Needs Review')), # Where is this status used? ('rev', _('Needs Review')), # Where is this status used?
#additional actions: #additional actions:
# edit # edit
@ -100,14 +100,14 @@ class Application(models.Model, SlideMixin):
self.save(nonewversion=True) self.save(nonewversion=True)
version.rejected = False version.rejected = False
version.save() version.save()
self.writelog(_("Version %d permitted") % (version.aid, ), self.writelog(_("Version %d authorized") % (version.aid, ),
user) user)
def reject_version(self, version, user = None): def reject_version(self, version, user = None):
if version.id > self.permitted.id: if version.id > self.permitted.id:
version.rejected = True version.rejected = True
version.save() version.save()
self.writelog(pgettext("Rejected means not permitted", "Version %d rejected") self.writelog(pgettext("Rejected means not authorized", "Version %d rejected")
% (version.aid, ), user) % (version.aid, ), user)
return True return True
return False return False
@ -138,9 +138,9 @@ class Application(models.Model, SlideMixin):
if self.status == "pub" and not self.enough_supporters: if self.status == "pub" and not self.enough_supporters:
note.append(_("Searching for supporters.")) note.append(_("Searching for supporters."))
if self.status == "pub" and self.permitted is None: if self.status == "pub" and self.permitted is None:
note.append(_("Not yet permitted.")) note.append(_("Not yet authorized."))
elif self.unpermitted_changes and self.permitted: elif self.unpermitted_changes and self.permitted:
note.append(_("Not yet permitted changes.")) note.append(_("Not yet authorized changes."))
return note return note
@property @property
@ -306,7 +306,7 @@ class Application(models.Model, SlideMixin):
self.set_number() self.set_number()
self.permitted = aversion self.permitted = aversion
self.save() self.save()
self.writelog(_("Version %s permitted") % (aversion.aid), user) self.writelog(_("Version %s authorized") % (aversion.aid), user)
return self.permitted return self.permitted
def notpermit(self, user=None): def notpermit(self, user=None):
@ -320,7 +320,7 @@ class Application(models.Model, SlideMixin):
if self.number is None: if self.number is None:
self.set_number() self.set_number()
self.save() self.save()
self.writelog(_("Version %s not permitted") % (self.last_version.aid), user) self.writelog(_("Version %s not authorized") % (self.last_version.aid), user)
def set_status(self, user, status, force=False): def set_status(self, user, status, force=False):
""" """
@ -332,19 +332,22 @@ class Application(models.Model, SlideMixin):
error = False error = False
break break
if error: if error:
#TODO: Use the Right Error
raise NameError(_('%s is not a valid status.') % status) raise NameError(_('%s is not a valid status.') % status)
if self.status == status: if self.status == status:
raise NameError(_('The application status is already \'%s.\'') \ #TODO: Use the Right Error
raise NameError(_('The motion status is already \'%s.\'') \
% self.status) % self.status)
actions = [] actions = []
actions = self.get_allowed_actions(user) actions = self.get_allowed_actions(user)
if status not in actions and not force: if status not in actions and not force:
raise NameError(_('The application status is: \'%(currentstatus)s\'. '\ #TODO: Use the Right Error
raise NameError(_(
'The motion status is: \'%(currentstatus)s\'. '
'You can not set the status to \'%(newstatus)s\'.') % { 'You can not set the status to \'%(newstatus)s\'.') % {
'currentstatus': self.status, 'currentstatus': self.status,
'newstatus': status 'newstatus': status})
})
oldstatus = self.get_status_display() oldstatus = self.get_status_display()
self.status = status self.status = status
@ -450,7 +453,7 @@ class Application(models.Model, SlideMixin):
def get_agenda_title_supplement(self): def get_agenda_title_supplement(self):
number = self.number or '<i>[%s]</i>' % ugettext('no number') number = self.number or '<i>[%s]</i>' % ugettext('no number')
return '(%s %s)' % (ugettext('Application'), number) return '(%s %s)' % (ugettext('motion'), number)
def __getattr__(self, name): def __getattr__(self, name):
""" """
@ -526,11 +529,10 @@ class Application(models.Model, SlideMixin):
class Meta: class Meta:
permissions = ( permissions = (
('can_see_application', ugettext_noop("Can see application")), ('can_see_application', ugettext_noop("Can see motions")),
('can_create_application', ugettext_noop("Can create application")), ('can_create_application', ugettext_noop("Can create motions")),
('can_support_application', ugettext_noop("Can support application")), ('can_support_application', ugettext_noop("Can support motions")),
('can_manage_application', ugettext_noop("Can manage application")), ('can_manage_application', ugettext_noop("Can manage motions")),
('can_delete_all_applications', ugettext_noop("Can delete all applications")),
) )
@ -599,7 +601,7 @@ def default_config(sender, key, **kwargs):
'application_preamble': _('The Assembly may decide,'), 'application_preamble': _('The Assembly may decide,'),
'application_pdf_ballot_papers_selection': 'CUSTOM_NUMBER', 'application_pdf_ballot_papers_selection': 'CUSTOM_NUMBER',
'application_pdf_ballot_papers_number': '8', 'application_pdf_ballot_papers_number': '8',
'application_pdf_title': _('Applications'), 'application_pdf_title': _('Motions'),
'application_pdf_preamble': '', 'application_pdf_preamble': '',
'application_allow_trivial_change': False, 'application_allow_trivial_change': False,
}.get(key) }.get(key)

View File

@ -6,16 +6,16 @@
{% block submenu %} {% block submenu %}
{% url application_overview as url_applicationoverview %} {% url application_overview as url_applicationoverview %}
<h4>{% trans "Applications" %}</h4> <h4>{% trans "Motions" %}</h4>
<ul> <ul>
<li class="{% if request.path == url_applicationoverview %}selected{% endif %}"><a href="{% url application_overview %}">{% trans "All applications" %}</a></li> <li class="{% if request.path == url_applicationoverview %}selected{% endif %}"><a href="{% url application_overview %}">{% trans "All motions" %}</a></li>
{% if perms.application.can_create_application or perms.application.can_manage_application %} {% if perms.application.can_create_application or perms.application.can_manage_application %}
<li class="{% active request '/application/new' %}"><a href="{% url application_new %}">{% trans "New application" %}</a></li> <li class="{% active request '/application/new' %}"><a href="{% url application_new %}">{% trans "New motion" %}</a></li>
{% endif %} {% endif %}
{% if perms.application.can_manage_application %} {% if perms.application.can_manage_application %}
<li class="{% active request '/application/import' %}"><a href="{% url application_import %}">{% trans 'Import applications' %}</a></li> <li class="{% active request '/application/import' %}"><a href="{% url application_import %}">{% trans 'Import motions' %}</a></li>
{% endif %} {% endif %}
<li><a href="{% url print_applications %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'All applications as PDF' %}</a></li> <li><a href="{% url print_applications %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'All motions as PDF' %}</a></li>
</ul> </ul>
{# second submenu #} {# second submenu #}
@ -31,18 +31,18 @@
<ul> <ul>
{# view application #} {# view application #}
{% url application_view application.id as url_applicationview %} {% url application_view application.id as url_applicationview %}
<li class="{% if request.path == url_applicationview %}selected{% endif %}"><a href="{% url application_view application.id %}">{% trans 'View application' %}</a></li> <li class="{% if request.path == url_applicationview %}selected{% endif %}"><a href="{% url application_view application.id %}">{% trans 'View motion' %}</a></li>
{# edit application #} {# edit application #}
{% if "edit" in actions %} {% if "edit" in actions %}
{% url application_edit application.id as url_applicationedit %} {% url application_edit application.id as url_applicationedit %}
<li class="{% if request.path == url_applicationedit %}selected{% endif %}"><a href="{% url application_edit application.id %}"><img src="{% static 'images/icons/edit.png' %}"> {% trans 'Edit application' %}</a></li> <li class="{% if request.path == url_applicationedit %}selected{% endif %}"><a href="{% url application_edit application.id %}"><img src="{% static 'images/icons/edit.png' %}"> {% trans 'Edit motion' %}</a></li>
{% endif %} {% endif %}
{# delete application #} {# delete application #}
{% if "delete" in actions %} {% if "delete" in actions %}
<li><a href="{% url application_delete application.id %}"><img src="{% static 'images/icons/delete.png' %}"> {% trans 'Delete application' %}</a></li> <li><a href="{% url application_delete application.id %}"><img src="{% static 'images/icons/delete.png' %}"> {% trans 'Delete motion' %}</a></li>
{% endif %} {% endif %}
{# PDF #} {# PDF #}
<li><a href="{% url print_application application.id %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'Application as PDF' %}</a></li> <li><a href="{% url print_application application.id %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'Motion as PDF' %}</a></li>
{# activate and polls #} {# activate and polls #}
{% if perms.projector.can_manage_projector %} {% if perms.projector.can_manage_projector %}
<li> <li>

View File

@ -5,17 +5,17 @@
{% block title %} {% block title %}
{{ block.super }} {{ block.super }}
{% if application %} {% if application %}
{% trans "Edit application" %} {% trans "Edit motion" %}
{% else %} {% else %}
{% trans "New application" %} {% trans "New motion" %}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if application %} {% if application %}
<h1>{% trans "Edit application" %}</h1> <h1>{% trans "Edit motion" %}</h1>
{% else %} {% else %}
<h1>{% trans "New application" %}</h1> <h1>{% trans "New motion" %}</h1>
{% endif %} {% endif %}
<form action="" method="post">{% csrf_token %} <form action="" method="post">{% csrf_token %}

View File

@ -2,11 +2,11 @@
{% load i18n %} {% load i18n %}
{% block title %}{{ block.super }} {% trans "Import applications" %} {% endblock %} {% block title %}{{ block.super }} {% trans "Import motions" %} {% endblock %}
{% block content %} {% block content %}
<h1>{% trans "Import applications" %}</h1> <h1>{% trans "Import motions" %}</h1>
<p>{% trans 'Select a CSV file to import applications!' %}</p> <p>{% trans 'Select a CSV file to import motions!' %}</p>
<p>{% trans 'Required comma separated values: <code>{number, title, text, reason, first_name, last_name}</code> (<code>number</code> and <code>reason</code> are optional and may be empty)' %} <p>{% trans 'Required comma separated values: <code>{number, title, text, reason, first_name, last_name}</code> (<code>number</code> and <code>reason</code> are optional and may be empty)' %}
<br> <br>

View File

@ -4,10 +4,10 @@
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{{ block.super }} {% trans "Applications" %}{% endblock %} {% block title %}{{ block.super }} {% trans "Motions" %}{% endblock %}
{% block content %} {% block content %}
<h1>{% trans "Applications" %}</h1> <h1>{% trans "Motions" %}</h1>
<p><form action="{{ request.url }}" name="filter" method="get"> <p><form action="{{ request.url }}" name="filter" method="get">
{% trans "Filter" %}: {% trans "Filter" %}:
{% if min_supporters > 0 %} {% if min_supporters > 0 %}
@ -19,21 +19,21 @@
<input type="checkbox" name="status" onchange="document.forms['filter'].submit()" <input type="checkbox" name="status" onchange="document.forms['filter'].submit()"
{% if 'on' in request.GET.status %}checked{% endif %}> {% trans "Status" %}: {% if 'on' in request.GET.status %}checked{% endif %}> {% trans "Status" %}:
<select class="default-input" name="statusvalue" onchange="{% if 'on' in request.GET.status %}document.forms['filter'].submit(){% endif %}"> <select class="default-input" name="statusvalue" onchange="{% if 'on' in request.GET.status %}document.forms['filter'].submit(){% endif %}">
<option value="pub" {% if 'pub' in request.GET.statusvalue %}selected{% endif %}>{% trans "Not yet permitted" %}</option> <option value="pub" {% if 'pub' in request.GET.statusvalue %}selected{% endif %}>{% trans "Not yet authorized" %}</option>
<option value="per" {% if 'on' in request.GET.status and 'per' in request.GET.statusvalue %}selected{% endif %}>{% trans "Permitted" %}</option> <option value="per" {% if 'on' in request.GET.status and 'per' in request.GET.statusvalue %}selected{% endif %}>{% trans "Authorized" %}</option>
<option value="acc" {% if 'on' in request.GET.status and 'acc' in request.GET.statusvalue %}selected{% endif %}>{% trans "Accepted" %}</option> <option value="acc" {% if 'on' in request.GET.status and 'acc' in request.GET.statusvalue %}selected{% endif %}>{% trans "Accepted" %}</option>
<option value="rej" {% if 'on' in request.GET.status and 'rej' in request.GET.statusvalue %}selected{% endif %}>{% trans "Rejected" %}</option> <option value="rej" {% if 'on' in request.GET.status and 'rej' in request.GET.statusvalue %}selected{% endif %}>{% trans "Rejected" %}</option>
<option value="wit" {% if 'on' in request.GET.status and 'wit' in request.GET.statusvalue %}selected{% endif %}>{% trans "Withdrawed (by submitter)" %}</option> <option value="wit" {% if 'on' in request.GET.status and 'wit' in request.GET.statusvalue %}selected{% endif %}>{% trans "Withdrawen (by submitter)" %}</option>
<option value="rev" {% if 'rev' in request.GET.statusvalue %}selected{% endif %}>{% trans "Needs Review" %}</option> <option value="rev" {% if 'rev' in request.GET.statusvalue %}selected{% endif %}>{% trans "Needs Review" %}</option>
</select> </select>
</form> </form>
</p> </p>
{{ applications|length }} {{ applications|length }}
{% blocktrans count counter=applications|length %}application{% plural %}applications{% endblocktrans %} {% blocktrans count counter=applications|length %}motion{% plural %}motions{% endblocktrans %}
<table> <table>
<tr> <tr>
<th><a href="?sort=number{% if 'number' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Number" %}</a></th> <th><a href="?sort=number{% if 'number' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Number" %}</a></th>
<th><a href="?sort=title{% if 'title' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Application title" %}</a></th> <th><a href="?sort=title{% if 'title' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Motion title" %}</a></th>
{% if min_supporters > 0 %} {% if min_supporters > 0 %}
<th><a href="?sort=supporter{% if 'supporter' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Number of supporters" %}</a></th> <th><a href="?sort=supporter{% if 'supporter' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Number of supporters" %}</a></th>
{% endif %} {% endif %}
@ -64,24 +64,24 @@
<td> <td>
<span style="width: 1px; white-space: nowrap;"> <span style="width: 1px; white-space: nowrap;">
{% if perms.projector.can_manage_projector %} {% if perms.projector.can_manage_projector %}
<a class="activate_link {% if application.active %}active{% endif %}" href="{% url projector_activate_slide application.sid %}" title="{% trans 'Activate application' %}"> <a class="activate_link {% if application.active %}active{% endif %}" href="{% url projector_activate_slide application.sid %}" title="{% trans 'Activate motion' %}">
<span></span> <span></span>
</a> </a>
{% endif %} {% endif %}
{% if perms.application.can_manage_application %} {% if perms.application.can_manage_application %}
<a href="{% url application_edit application.id %}"><img src="{% static 'images/icons/edit.png' %}" title="{% trans 'Edit application' %}"></a> <a href="{% url application_edit application.id %}"><img src="{% static 'images/icons/edit.png' %}" title="{% trans 'Edit motion' %}"></a>
{% if "delete" in useractions %} {% if "delete" in useractions %}
<a href="{% url application_delete application.id %}"><img src="{% static 'images/icons/delete.png' %}" title="{% trans 'Delete application' %}"></a> <a href="{% url application_delete application.id %}"><img src="{% static 'images/icons/delete.png' %}" title="{% trans 'Delete motion' %}"></a>
{% endif %} {% endif %}
{% endif %} {% endif %}
<a href="{% url print_application application.id %}" title="{% trans 'Application as PDF' %}"><img src="{% static 'images/icons/pdf.png' %}"></a> <a href="{% url print_application application.id %}" title="{% trans 'Motion as PDF' %}"><img src="{% static 'images/icons/pdf.png' %}"></a>
</span> </span>
</td> </td>
</tr> </tr>
{% endwith %} {% endwith %}
{% empty %} {% empty %}
<tr> <tr>
<td colspan="7"><i>{% trans "No applications available." %}</i></td> <td colspan="7"><i>{% trans "No motions available." %}</i></td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -4,12 +4,12 @@
{% load staticfiles %} {% load staticfiles %}
{% block title %} {% block title %}
{{ block.super }} {% trans "Application" %} "{{ application.public_version.title }}" {{ block.super }} {% trans "Motion" %} "{{ application.public_version.title }}"
{{ ballot }}. {% trans "Vote" %} {{ ballot }}. {% trans "Vote" %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1>{{ application.public_version.title }} ({% trans "Application" %} <h1>{{ application.public_version.title }} ({% trans "Motion" %}
{{ application.number }}) {{ ballot }}. {% trans "Vote" %}</h1> {{ application.number }}) {{ ballot }}. {% trans "Vote" %}</h1>
<i class="helptext">{% trans "Special values" %}: -1 = {% trans 'majority' %}; -2 = {% trans 'undocumented' %}</i> <i class="helptext">{% trans "Special values" %}: -1 = {% trans 'majority' %}; -2 = {% trans 'undocumented' %}</i>
<form action="" method="post" class="small-form">{% csrf_token %} <form action="" method="post" class="small-form">{% csrf_token %}

View File

@ -4,7 +4,7 @@
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{{ block.super }} {% trans "Application" %} "{{ version.title }}"{% endblock %} {% block title %}{{ block.super }} {% trans "Motion" %} "{{ version.title }}"{% endblock %}
{% block submenu %} {% block submenu %}
@ -143,7 +143,7 @@
{% if perms.application.can_manage_application %} {% if perms.application.can_manage_application %}
<div class="box"> <div class="box">
<h4><b>{% trans "Manage application" %}</b></h4> <h4><b>{% trans "Manage motion" %}</b></h4>
{% if "pub" in actions or "per" in actions or "nop" in actions or "setnumber" in actions %} {% if "pub" in actions or "per" in actions or "nop" in actions or "setnumber" in actions %}
<h4>{% trans "Formal validation" %}:</h4> <h4>{% trans "Formal validation" %}:</h4>
@ -206,7 +206,7 @@
<div id="main"> <div id="main">
<h1> <h1>
{{ version.title }} {{ version.title }}
({% trans "Application" %} ({% trans "Motion" %}
{% if application.number != None %} {% if application.number != None %}
{{ application.number }}) {{ application.number }})
{% else %} {% else %}
@ -221,11 +221,11 @@
{% if version == application.public_version %} {% if version == application.public_version %}
{% trans "This is not the newest version." %} <a href="{% url application_view_newest application.id %}">{% trans "Go to version" %} {{ application.last_version.aid }}.</a> {% trans "This is not the newest version." %} <a href="{% url application_view_newest application.id %}">{% trans "Go to version" %} {{ application.last_version.aid }}.</a>
{% else %} {% else %}
{% trans "This is not the permitted version." %} <a href="{% url application_view application.id %}">{% trans "Go to version" %} {{ application.public_version.aid }}.</a> {% trans "This is not the authorized version." %} <a href="{% url application_view application.id %}">{% trans "Go to version" %} {{ application.public_version.aid }}.</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
<h2>{% trans "Application" %}:</h2> <h2>{% trans "Motion" %}:</h2>
{{ version.text|linebreaks }} {{ version.text|linebreaks }}
@ -256,7 +256,7 @@
<td style="white-space:nowrap;"> <td style="white-space:nowrap;">
{% if application.status != "pub" %} {% if application.status != "pub" %}
{% if revision == application.permitted %} {% if revision == application.permitted %}
<img title="{% trans 'Version permitted' %}" src="{% static 'images/icons/accept.png' %}"> <img title="{% trans 'Version authorized' %}" src="{% static 'images/icons/accept.png' %}">
{% else %} {% else %}
{% if perms.application.can_manage_application %} {% if perms.application.can_manage_application %}
<a href="{% url application_version_permit revision.id %}"><img title="{% trans 'Permit Version' %}" src="{% static 'images/icons/accept-grey.png' %}"></a> <a href="{% url application_version_permit revision.id %}"><img title="{% trans 'Permit Version' %}" src="{% static 'images/icons/accept-grey.png' %}"></a>

View File

@ -20,7 +20,7 @@
<a href="{% model_url application 'view' %}"> <a href="{% model_url application 'view' %}">
{{ application.public_version.title }} {{ application.public_version.title }}
</a> </a>
({% trans 'Application' %} ({% trans "motion" %}
{% if application.number %} {% if application.number %}
{{ application.number }}) {{ application.number }})
{% else %} {% else %}
@ -28,7 +28,7 @@
{% endif %} {% endif %}
</li> </li>
{% empty %} {% empty %}
<li>{% trans 'No applications available.' %}</li> <li>{% trans 'No motion available.' %}</li>
{% endfor %} {% endfor %}
</ul> </ul>

View File

@ -4,7 +4,7 @@
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{{ block.super }} - {% trans "Application" %} {{ application.number }}{% endblock %} {% block title %}{{ block.super }} - {% trans "Motion" %} {{ application.number }}{% endblock %}
{% block content %} {% block content %}
<div id="sidebar"> <div id="sidebar">
<div class="box"> <div class="box">
@ -60,9 +60,9 @@
<h1> <h1>
{% if application.number != None %} {% if application.number != None %}
{% trans "Application No." %} {{ application.number }} {% trans "Motion No." %} {{ application.number }}
{% else %} {% else %}
{% trans "Application" %} <i>[{% trans "no number" %}]</i> {% trans "Motion" %} <i>[{% trans "no number" %}]</i>
{% endif %} {% endif %}
</h1> </h1>
<b>{{ application.public_version.title }}</b> <b>{{ application.public_version.title }}</b>

View File

@ -177,14 +177,12 @@ def edit(request, application_id=None):
if not is_manager \ if not is_manager \
and not request.user.has_perm('application.can_create_application'): and not request.user.has_perm('application.can_create_application'):
messages.error(request, _("You have not the necessary rights to create or edit applications.")) messages.error(request, _("You have not the necessary rights to create or edit motions."))
return redirect(reverse('application_overview')) return redirect(reverse('application_overview'))
if application_id is not None: if application_id is not None:
application = Application.objects.get(id=application_id) application = Application.objects.get(id=application_id)
if (not hasattr(application.submitter, 'user') or if not request.user == application.submitter and not is_manager:
not request.user == application.submitter.user) \ messages.error(request, _("You can not edit this motion. You are not the submitter."))
and not is_manager:
messages.error(request, _("You can not edit this application. You are not the submitter."))
return redirect(reverse('application_view', args=[application.id])) return redirect(reverse('application_view', args=[application.id]))
actions = application.get_allowed_actions(user=request.user) actions = application.get_allowed_actions(user=request.user)
else: else:
@ -245,10 +243,11 @@ def edit(request, application_id=None):
# remove old supporters # remove old supporters
for supporter in old_supporters.difference(new_supporters): for supporter in old_supporters.difference(new_supporters):
application.unsupport(supporter) application.unsupport(supporter)
if application_id is None: if application_id is None:
messages.success(request, _('New application was successfully created.')) messages.success(request, _('New motion was successfully created.'))
else: else:
messages.success(request, _('Application was successfully modified.')) messages.success(request, _('Motion was successfully modified.'))
if not 'apply' in request.POST: if not 'apply' in request.POST:
return redirect(reverse('application_view', args=[application.id])) return redirect(reverse('application_view', args=[application.id]))
@ -262,9 +261,9 @@ def edit(request, application_id=None):
else: else:
if application.status == "pub" and application.supporters: if application.status == "pub" and application.supporters:
if request.user.has_perm('application.can_manage_application'): if request.user.has_perm('application.can_manage_application'):
messages.warning(request, _("Attention: Do you really want to edit this application? The supporters will <b>not</b> be removed automatically because you can manage applications. Please check if the supports are valid after your changing!")) messages.warning(request, _("Attention: Do you really want to edit this motion? The supporters will <b>not</b> be removed automatically because you can manage motions. Please check if the supports are valid after your changing!"))
else: else:
messages.warning(request, _("Attention: Do you really want to edit this application? All <b>%s</b> supporters will be removed! Try to convince the supporters again.") % len(application.supporters) ) messages.warning(request, _("Attention: Do you really want to edit this motion? All <b>%s</b> supporters will be removed! Try to convince the supporters again.") % application.supporter.count() )
initial = {'title': application.title, initial = {'title': application.title,
'text': application.text, 'text': application.text,
'reason': application.reason} 'reason': application.reason}
@ -296,7 +295,7 @@ def set_number(request, application_id):
""" """
try: try:
Application.objects.get(pk=application_id).set_number(user=request.user) Application.objects.get(pk=application_id).set_number(user=request.user)
messages.success(request, _("Application number was successfully set.")) messages.success(request, _("Motion number was successfully set."))
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
except NameError: except NameError:
@ -312,7 +311,7 @@ def permit(request, application_id):
""" """
try: try:
Application.objects.get(pk=application_id).permit(user=request.user) Application.objects.get(pk=application_id).permit(user=request.user)
messages.success(request, _("Application was successfully permitted.")) messages.success(request, _("Motion was successfully authorized."))
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
except NameError, e: except NameError, e:
@ -327,7 +326,7 @@ def notpermit(request, application_id):
""" """
try: try:
Application.objects.get(pk=application_id).notpermit(user=request.user) Application.objects.get(pk=application_id).notpermit(user=request.user)
messages.success(request, _("Application was successfully rejected.")) messages.success(request, _("Motion was successfully rejected."))
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
except NameError, e: except NameError, e:
@ -343,7 +342,7 @@ def set_status(request, application_id=None, status=None):
if status is not None: if status is not None:
application = Application.objects.get(pk=application_id) application = Application.objects.get(pk=application_id)
application.set_status(user=request.user, status=status) application.set_status(user=request.user, status=status)
messages.success(request, _("Application status was set to: <b>%s</b>.") % application.get_status_display()) messages.success(request, _("Motion status was set to: <b>%s</b>.") % application.get_status_display())
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
except NameError, e: except NameError, e:
@ -358,8 +357,8 @@ def reset(request, application_id):
reset an application. reset an application.
""" """
try: try:
Application.objects.get(pk=application_id).reset(user=request.user.openslides.user) Application.objects.get(pk=application_id).reset(user=request.user)
messages.success(request, _("Application status was reset.") ) messages.success(request, _("Motion status was reset.") )
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
return redirect(reverse('application_view', args=[application_id])) return redirect(reverse('application_view', args=[application_id]))
@ -372,8 +371,8 @@ def support(request, application_id):
support an application. support an application.
""" """
try: try:
Application.objects.get(pk=application_id).support(user=request.user.openslides.user) Application.objects.get(pk=application_id).support(user=request.user)
messages.success(request, _("You have support the application successfully.") ) messages.success(request, _("You have support the motion successfully.") )
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
return redirect(reverse('application_view', args=[application_id])) return redirect(reverse('application_view', args=[application_id]))
@ -387,7 +386,7 @@ def unsupport(request, application_id):
""" """
try: try:
Application.objects.get(pk=application_id).unsupport(user=request.user) Application.objects.get(pk=application_id).unsupport(user=request.user)
messages.success(request, _("You have unsupport the application successfully.") ) messages.success(request, _("You have unsupport the motion successfully.") )
except Application.DoesNotExist: except Application.DoesNotExist:
pass pass
return redirect(reverse('application_view', args=[application_id])) return redirect(reverse('application_view', args=[application_id]))
@ -458,20 +457,20 @@ class ApplicationDelete(DeleteView):
if len(self.applications): if len(self.applications):
for application in self.applications: for application in self.applications:
if not 'delete' in application.get_allowed_actions(user=request.user): if not 'delete' in application.get_allowed_actions(user=request.user):
messages.error(request, _("You can not delete application <b>%s</b>.") % application) messages.error(request, _("You can not delete motion <b>%s</b>.") % application)
continue continue
title = application.title title = application.title
application.delete(force=True) application.delete(force=True)
messages.success(request, _("Application <b>%s</b> was successfully deleted.") % title) messages.success(request, _("Motion <b>%s</b> was successfully deleted.") % title)
elif self.object: elif self.object:
if not 'delete' in self.object.get_allowed_actions(user=request.user): if not 'delete' in self.object.get_allowed_actions(user=request.user):
messages.error(request, _("You can not delete application <b>%s</b>.") % self.object) messages.error(request, _("You can not delete motion <b>%s</b>.") % self.object)
else: else:
title = self.object.title title = self.object.title
self.object.delete(force=True) self.object.delete(force=True)
messages.success(request, _("Application <b>%s</b> was successfully deleted.") % title) messages.success(request, _("Motion <b>%s</b> was successfully deleted.") % title)
else: else:
messages.error(request, _("Invalid request")) messages.error(request, _("Invalid request"))
@ -492,7 +491,7 @@ class ApplicationDelete(DeleteView):
self.object = self.get_object() self.object = self.get_object()
if len(self.applications): if len(self.applications):
self.gen_confirm_form(request, _('Do you really want to delete multiple applications?') % self.object.get_absolute_url('delete')) self.gen_confirm_form(request, _('Do you really want to delete multiple motions?') % self.object.get_absolute_url('delete'))
else: else:
self.gen_confirm_form(request, _('Do you really want to delete <b>%s</b>?') % self.object, self.object.get_absolute_url('delete')) self.gen_confirm_form(request, _('Do you really want to delete <b>%s</b>?') % self.object, self.object.get_absolute_url('delete'))
@ -537,7 +536,7 @@ def permit_version(request, aversion_id):
application.accept_version(aversion, user=request.user) application.accept_version(aversion, user=request.user)
messages.success(request, _("Version <b>%s</b> accepted.") % (aversion.aid)) messages.success(request, _("Version <b>%s</b> accepted.") % (aversion.aid))
else: else:
gen_confirm_form(request, _('Do you really want to permit version <b>%s</b>?') % aversion.aid, reverse('application_version_permit', args=[aversion.id])) gen_confirm_form(request, _('Do you really want to authorize version <b>%s</b>?') % aversion.aid, reverse('application_version_permit', args=[aversion.id]))
return redirect(reverse('application_view', args=[application.id])) return redirect(reverse('application_view', args=[application.id]))
@ -640,11 +639,11 @@ def application_import(request):
application.save(user, trivial_change=True) application.save(user, trivial_change=True)
if applications_generated: if applications_generated:
messages.success(request, ungettext('%d application was successfully imported.', messages.success(request, ungettext('%d motion was successfully imported.',
'%d applications were successfully imported.', applications_generated) % applications_generated) '%d motions were successfully imported.', applications_generated) % applications_generated)
if applications_modified: if applications_modified:
messages.success(request, ungettext('%d application was successfully modified.', messages.success(request, ungettext('%d motion was successfully modified.',
'%d applications were successfully modified.', applications_modified) % applications_modified) '%d motions were successfully modified.', applications_modified) % applications_modified)
if users_generated: if users_generated:
messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated) messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated)
return redirect(reverse('application_overview')) return redirect(reverse('application_overview'))
@ -656,8 +655,8 @@ def application_import(request):
else: else:
messages.error(request, _('Please check the form for errors.')) messages.error(request, _('Please check the form for errors.'))
else: else:
messages.warning(request, _("Attention: Existing applications will be modified if you import new applications with the same number.")) messages.warning(request, _("Attention: Existing motions will be modified if you import new motions with the same number."))
messages.warning(request, _("Attention: Importing an application without a number multiple times will create duplicates.")) messages.warning(request, _("Attention: Importing an motions without a number multiple times will create duplicates."))
form = ApplicationImportForm() form = ApplicationImportForm()
return { return {
'form': form, 'form': form,
@ -704,14 +703,14 @@ class ApplicationPDF(PDFView):
story.append(Spacer(0,0.75*cm)) story.append(Spacer(0,0.75*cm))
applications = Application.objects.order_by('number') applications = Application.objects.order_by('number')
if not applications: # No applications existing if not applications: # No applications existing
story.append(Paragraph(_("No applications available."), stylesheet['Heading3'])) story.append(Paragraph(_("No motions available."), stylesheet['Heading3']))
else: # Print all Applications else: # Print all Applications
# List of applications # List of applications
for application in applications: for application in applications:
if application.number: if application.number:
story.append(Paragraph(_("Application No.")+" %s: %s" % (application.number, application.title), stylesheet['Heading3'])) story.append(Paragraph(_("Motion No.")+" %s: %s" % (application.number, application.title), stylesheet['Heading3']))
else: else:
story.append(Paragraph(_("Application No.")+"&nbsp;&nbsp;&nbsp;: %s" % (application.title), stylesheet['Heading3'])) story.append(Paragraph(_("Motion No.")+"&nbsp;&nbsp;&nbsp;: %s" % (application.title), stylesheet['Heading3']))
# Applications details (each application on single page) # Applications details (each application on single page)
for application in applications: for application in applications:
story.append(PageBreak()) story.append(PageBreak())
@ -723,9 +722,9 @@ class ApplicationPDF(PDFView):
def get_application(self, application, story): def get_application(self, application, story):
# application number # application number
if application.number: if application.number:
story.append(Paragraph(_("Application No.")+" %s" % application.number, stylesheet['Heading1'])) story.append(Paragraph(_("Motion No.")+" %s" % application.number, stylesheet['Heading1']))
else: else:
story.append(Paragraph(_("Application No."), stylesheet['Heading1'])) story.append(Paragraph(_("Motion No."), stylesheet['Heading1']))
# submitter # submitter
cell1a = [] cell1a = []
@ -902,7 +901,7 @@ class Config(FormView):
config['application_pdf_title'] = form.cleaned_data['application_pdf_title'] config['application_pdf_title'] = form.cleaned_data['application_pdf_title']
config['application_pdf_preamble'] = form.cleaned_data['application_pdf_preamble'] config['application_pdf_preamble'] = form.cleaned_data['application_pdf_preamble']
config['application_allow_trivial_change'] = form.cleaned_data['application_allow_trivial_change'] config['application_allow_trivial_change'] = form.cleaned_data['application_allow_trivial_change']
messages.success(self.request, _('Application settings successfully saved.')) messages.success(self.request, _('Motion settings successfully saved.'))
return super(Config, self).form_valid(form) return super(Config, self).form_valid(form)

View File

@ -81,7 +81,7 @@ def default_config(sender, key, **kwargs):
return { return {
'event_name': 'OpenSlides', 'event_name': 'OpenSlides',
'event_description': 'event_description':
_('Presentation system for agenda, applications and elections'), _('Presentation system for agenda, motions and elections'),
'event_date': '', 'event_date': '',
'event_location': '', 'event_location': '',
'event_organizer': '', 'event_organizer': '',

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,10 @@ USE_I18N = True
# calendars according to the current locale # calendars according to the current locale
USE_L10N = True USE_L10N = True
LOCALE_PATHS = (
_fs2unicode(os.path.join(SITE_ROOT, 'locale'))
)
# Absolute path to the directory that holds media. # Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/" # Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = _fs2unicode(os.path.join(SITE_ROOT, './static/')) MEDIA_ROOT = _fs2unicode(os.path.join(SITE_ROOT, './static/'))

View File

@ -24,6 +24,21 @@ class UserCreateForm(forms.ModelForm, CssClassMixin):
groups = forms.ModelMultipleChoiceField( groups = forms.ModelMultipleChoiceField(
queryset=Group.objects.exclude(name__iexact='anonymous'), queryset=Group.objects.exclude(name__iexact='anonymous'),
label=_("User groups"), required=False) label=_("User groups"), required=False)
is_active = forms.BooleanField(label=_("Active"), required=False,
initial=True)
class Meta:
model = User
exclude = ('username', 'password', 'is_staff', 'is_superuser',
'last_login', 'date_joined', 'user_permissions')
class UserEditForm(forms.ModelForm, CssClassMixin):
first_name = forms.CharField(label=_("First name"))
last_name = forms.CharField(label=_("Last name"))
groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(),
label=_("User groups"), required=False)
is_active = forms.BooleanField(label=_("Active"), required=False)
class Meta: class Meta:
model = User model = User
@ -96,7 +111,6 @@ class UsersettingsForm(forms.ModelForm, CssClassMixin):
model = User model = User
fields = ('username', 'first_name', 'last_name', 'email') fields = ('username', 'first_name', 'last_name', 'email')
class UserImportForm(forms.Form, CssClassMixin): class UserImportForm(forms.Form, CssClassMixin):
csvfile = forms.FileField(widget=forms.FileInput(attrs={'size': '50'}), csvfile = forms.FileField(widget=forms.FileInput(attrs={'size': '50'}),
label=_("CSV File")) label=_("CSV File"))

View File

@ -137,7 +137,7 @@ class UsersConnector(object):
if (not self.person_prefix_filter or if (not self.person_prefix_filter or
self.person_prefix_filter == User.person_prefix): self.person_prefix_filter == User.person_prefix):
if self.id_filter: if self.id_filter:
yield users.get(pk=self.id_filter) yield self.users.get(pk=self.id_filter)
else: else:
for user in self.users: for user in self.users:
yield user yield user
@ -145,7 +145,7 @@ class UsersConnector(object):
if (not self.person_prefix_filter or if (not self.person_prefix_filter or
self.person_prefix_filter == Group.person_prefix): self.person_prefix_filter == Group.person_prefix):
if self.id_filter: if self.id_filter:
yield groups.get(pk=self.id_filter) yield self.groups.get(pk=self.id_filter)
else: else:
for group in self.groups: for group in self.groups:
yield group yield group
@ -156,8 +156,8 @@ class UsersConnector(object):
@receiver(receive_persons, dispatch_uid="participant") @receiver(receive_persons, dispatch_uid="participant")
def receive_persons(sender, **kwargs): def receive_persons(sender, **kwargs):
return UsersConnecter(person_prefix_filter=kwargs['person_prefix_filter'], return UsersConnector(person_prefix_filter=kwargs['person_prefix_filter'],
id=kwargs['id_filter']) id_filter=kwargs['id_filter'])
@receiver(default_config_value, dispatch_uid="participant_default_config") @receiver(default_config_value, dispatch_uid="participant_default_config")

View File

@ -26,7 +26,7 @@ class UserTest(TestCase):
self.user1.last_name = u'Mustermann' self.user1.last_name = u'Mustermann'
self.user1.username = gen_username( self.user1.username = gen_username(
self.user1.first_name, self.user1.last_name) self.user1.first_name, self.user1.last_name)
self.user1.firstpassword = gen_password() self.user1.default_password = gen_password()
self.user1.save() self.user1.save()
self.django_user1 = self.user1.django_user self.django_user1 = self.user1.django_user
@ -43,18 +43,18 @@ class UserTest(TestCase):
self.assertEqual(unicode(self.user1), u'Max Mustermann (München)') self.assertEqual(unicode(self.user1), u'Max Mustermann (München)')
def test_reset_password(self): def test_reset_password(self):
self.assertIsInstance(self.user1.firstpassword, basestring) self.assertIsInstance(self.user1.default_password, basestring)
self.assertEqual(len(self.user1.firstpassword), 8) self.assertEqual(len(self.user1.default_password), 8)
self.user1.set_unusable_password() self.user1.set_unusable_password()
self.assertFalse(self.user1.check_password(self.user1.firstpassword)) self.assertFalse(self.user1.check_password(self.user1.default_password))
self.user1.reset_password() self.user1.reset_password()
self.assertTrue(self.user1.check_password(self.user1.firstpassword)) self.assertTrue(self.user1.check_password(self.user1.default_password))
def test_person_api(self): def test_person_api(self):
self.assertTrue(hasattr(self.user1, 'person_id')) self.assertTrue(hasattr(self.user1, 'person_id'))
self.assertEqual(self.user1.person_id, 'user:1') self.assertEqual(self.user1.person_id, 'user:1')
self.assertEqual(get_person('user:1'), self.user1) self.assertEqual(get_person('user:1'), self.user1)
self.assertEqual(len(Persons(person_prefix='user')), 1) self.assertEqual(len(Persons(person_prefix_filter='user')), 1)
class GroupTest(TestCase): class GroupTest(TestCase):

View File

@ -424,6 +424,25 @@ class Config(FormView):
return super(Config, self).form_valid(form) return super(Config, self).form_valid(form)
def login(request):
extra_content = {}
try:
admin = User.objects.get(pk=1)
if admin.check_password(config['admin_password']):
extra_content['first_time_message'] = _(
"Installation was successfully! Use %(user)s "
"(password: %(password)s) for first login.<br>"
"<strong>Important:</strong> Please change the password after "
"first login! Otherwise this message still appears for "
"everyone and could be a security risk.") % {
'user': html_strong(admin.username),
'password': html_strong(config['admin_password'])}
extra_content['next'] = reverse('password_change')
except User.DoesNotExist:
pass
return django_login(request, template_name='participant/login.html', extra_context=extra_content)
@login_required @login_required
@template('participant/settings.html') @template('participant/settings.html')
def user_settings(request): def user_settings(request):
@ -468,25 +487,6 @@ def user_settings_password(request):
} }
def login(request):
extra_content = {}
try:
admin = User.objects.get(pk=1)
if admin.check_password(config['admin_password']):
extra_content['first_time_message'] = _(
"Installation was successfully! Use %(user)s "
"(password: %(password)s) for first login.<br>"
"<strong>Important:</strong> Please change the password after "
"first login! Otherwise this message still appears for "
"everyone and could be a security risk.") % {
'user': html_strong(admin.username),
'password': html_strong(config['admin_password'])}
extra_content['next'] = reverse('password_change')
except User.DoesNotExist:
pass
return django_login(request, template_name='participant/login.html', extra_context=extra_content)
def register_tab(request): def register_tab(request):
""" """
Register the participant tab. Register the participant tab.