Merge remote branch 'upstream/master'
This commit is contained in:
commit
0c797aa476
@ -11,14 +11,14 @@
|
|||||||
"item"
|
"item"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_create_application",
|
"can_create_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_see_application",
|
"can_see_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_nominate_other",
|
"can_nominate_other",
|
||||||
@ -44,6 +44,11 @@
|
|||||||
"can_see_projector",
|
"can_see_projector",
|
||||||
"projector",
|
"projector",
|
||||||
"projectorslide"
|
"projectorslide"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"can_see_dashboard",
|
||||||
|
"projector",
|
||||||
|
"projectorslide"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -60,19 +65,19 @@
|
|||||||
"item"
|
"item"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_create_application",
|
"can_create_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_see_application",
|
"can_see_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_support_application",
|
"can_support_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_nominate_other",
|
"can_nominate_other",
|
||||||
@ -98,6 +103,11 @@
|
|||||||
"can_see_projector",
|
"can_see_projector",
|
||||||
"projector",
|
"projector",
|
||||||
"projectorslide"
|
"projectorslide"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"can_see_dashboard",
|
||||||
|
"projector",
|
||||||
|
"projectorslide"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -119,19 +129,19 @@
|
|||||||
"item"
|
"item"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_create_application",
|
"can_create_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_manage_application",
|
"can_manage_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_see_application",
|
"can_see_motion",
|
||||||
"application",
|
"motion",
|
||||||
"application"
|
"motion"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"can_manage_assignment",
|
"can_manage_assignment",
|
||||||
@ -177,6 +187,11 @@
|
|||||||
"can_see_projector",
|
"can_see_projector",
|
||||||
"projector",
|
"projector",
|
||||||
"projectorslide"
|
"projectorslide"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"can_see_dashboard",
|
||||||
|
"projector",
|
||||||
|
"projectorslide"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -206,6 +221,11 @@
|
|||||||
"can_see_projector",
|
"can_see_projector",
|
||||||
"projector",
|
"projector",
|
||||||
"projectorslide"
|
"projectorslide"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"can_see_dashboard",
|
||||||
|
"projector",
|
||||||
|
"projectorslide"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = (1, 2, 0, 'final', 1)
|
VERSION = (1, 3, 0, 'alpha', 1)
|
||||||
|
|
||||||
|
|
||||||
def get_version(version=None):
|
def get_version(version=None):
|
||||||
"""Derives a PEP386-compliant version number from VERSION."""
|
"""
|
||||||
# TODO: Get the Version Hash from GIT.
|
Derives a PEP386-compliant version number from VERSION. Adds id of
|
||||||
|
the current git commit.
|
||||||
|
"""
|
||||||
if version is None:
|
if version is None:
|
||||||
version = VERSION
|
version = VERSION
|
||||||
assert len(version) == 5
|
assert len(version) == 5
|
||||||
@ -17,67 +20,24 @@ def get_version(version=None):
|
|||||||
|
|
||||||
# Now build the two parts of the version number:
|
# Now build the two parts of the version number:
|
||||||
# main = X.Y[.Z]
|
# main = X.Y[.Z]
|
||||||
# sub = .devN - for pre-alpha releases
|
# sub = {a|b|c}N for alpha, beta and rc releases
|
||||||
# | {a|b|c}N - for alpha, beta and rc releases
|
# git's commit id is added
|
||||||
|
|
||||||
parts = 2 if version[2] == 0 else 3
|
main_parts = 2 if version[2] == 0 else 3
|
||||||
main = '.'.join(str(x) for x in version[:parts])
|
main = '.'.join(str(x) for x in version[:main_parts])
|
||||||
|
|
||||||
sub = ''
|
if version[3] != 'final':
|
||||||
if version[3] == 'alpha' and version[4] == 0:
|
mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
|
||||||
mercurial_version = hg_version()
|
sub = mapping[version[3]] + str(version[4])
|
||||||
if mercurial_version != 'unknown':
|
try:
|
||||||
sub = '.dev%s' % mercurial_version
|
git_head_path = '.git/' + open('.git/HEAD', 'r').read()[5:].rstrip()
|
||||||
|
except IOError:
|
||||||
|
git_commit_id = 'unknown'
|
||||||
else:
|
else:
|
||||||
sub = '.dev'
|
import os
|
||||||
|
git_commit_id = open(os.path.abspath(git_head_path), 'r').read().rstrip()
|
||||||
elif version[3] != 'final':
|
sub = '%s commit %s' % (sub, git_commit_id)
|
||||||
sub = "-" + version[3] + str(version[4])
|
else:
|
||||||
|
sub = ''
|
||||||
|
|
||||||
return main + sub
|
return main + sub
|
||||||
|
|
||||||
|
|
||||||
def hg_version():
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from os.path import realpath, join, dirname
|
|
||||||
try:
|
|
||||||
from mercurial import ui as hgui
|
|
||||||
from mercurial.localrepo import localrepository
|
|
||||||
from mercurial.node import short as shorthex
|
|
||||||
from mercurial.error import RepoError
|
|
||||||
nomercurial = False
|
|
||||||
except ImportError:
|
|
||||||
return 'unknown'
|
|
||||||
|
|
||||||
os.environ['HGRCPATH'] = ''
|
|
||||||
conts = realpath(join(dirname(__file__)))
|
|
||||||
try:
|
|
||||||
ui = hgui.ui()
|
|
||||||
repository = localrepository(ui, join(conts, '..'))
|
|
||||||
ctx = repository['.']
|
|
||||||
if ctx.tags() and ctx.tags() != ['tip']:
|
|
||||||
version = ' '.join(ctx.tags())
|
|
||||||
else:
|
|
||||||
version = '%(num)s:%(id)s' % {
|
|
||||||
'num': ctx.rev(), 'id': shorthex(ctx.node())
|
|
||||||
}
|
|
||||||
except TypeError:
|
|
||||||
version = 'unknown'
|
|
||||||
except RepoError:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# This value defines the timeout for sockets in seconds. Per default python
|
|
||||||
# sockets do never timeout and as such we have blocking workers.
|
|
||||||
# Socket timeouts are set globally within the whole application.
|
|
||||||
# The value *must* be a floating point value.
|
|
||||||
socket.setdefaulttimeout(10.0)
|
|
||||||
|
|
||||||
return version
|
|
||||||
|
|
||||||
|
|
||||||
## import os, site
|
|
||||||
##
|
|
||||||
## SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
|
|
||||||
## site.addsitedir(SITE_ROOT)
|
|
||||||
|
@ -177,12 +177,12 @@ class ItemDelete(DeleteView):
|
|||||||
if self.get_answer() == 'all':
|
if self.get_answer() == 'all':
|
||||||
self.object.delete(with_children=True)
|
self.object.delete(with_children=True)
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
_("Item %s and his children were successfully deleted.") \
|
_("Item %s and his children were successfully deleted.")
|
||||||
% html_strong(self.object))
|
% html_strong(self.object))
|
||||||
elif self.get_answer() == 'yes':
|
elif self.get_answer() == 'yes':
|
||||||
self.object.delete(with_children=False)
|
self.object.delete(with_children=False)
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
_("Item %s was successfully deleted.") \
|
_("Item %s was successfully deleted.")
|
||||||
% html_strong(self.object))
|
% html_strong(self.object))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% load tags %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load staticfiles %}
|
|
||||||
|
|
||||||
{% block submenu %}
|
|
||||||
{% url application_overview as url_applicationoverview %}
|
|
||||||
<h4>{% trans "Motions" %}</h4>
|
|
||||||
<ul>
|
|
||||||
<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 %}
|
|
||||||
<li class="{% active request '/application/new' %}"><a href="{% url application_new %}">{% trans "New motion" %}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{% if perms.application.can_manage_application %}
|
|
||||||
<li class="{% active request '/application/import' %}"><a href="{% url application_import %}">{% trans 'Import motions' %}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
<li><a href="{% url print_applications %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'All motions as PDF' %}</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{# second submenu #}
|
|
||||||
{% if application %}
|
|
||||||
<br>
|
|
||||||
<h3>{% trans "Application No." %}
|
|
||||||
{% if application.number != None %}
|
|
||||||
{{ application.number }}
|
|
||||||
{% else %}
|
|
||||||
<i>[-]</i>
|
|
||||||
{% endif %}
|
|
||||||
</h3>
|
|
||||||
<ul>
|
|
||||||
{# view application #}
|
|
||||||
{% 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 motion' %}</a></li>
|
|
||||||
{# edit application #}
|
|
||||||
{% if "edit" in actions %}
|
|
||||||
{% 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 motion' %}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{# delete application #}
|
|
||||||
{% if "delete" in actions %}
|
|
||||||
<li><a href="{% url application_delete application.id %}"><img src="{% static 'images/icons/delete.png' %}"> {% trans 'Delete motion' %}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{# PDF #}
|
|
||||||
<li><a href="{% url print_application application.id %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'Motion as PDF' %}</a></li>
|
|
||||||
{# activate and polls #}
|
|
||||||
{% if perms.projector.can_manage_projector %}
|
|
||||||
<li>
|
|
||||||
<a class="activate_link {% if item.active %}active{% endif %}" href="{% url projector_activate_slide application.sid %}"><img src="{% static 'images/icons/projector.png' %}"> {% trans 'Show Application' %}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if perms.application.can_manage_application %}
|
|
||||||
{% for poll in application.polls %}
|
|
||||||
{% url application_poll_view poll.id as url_applicationpollview %}
|
|
||||||
<li class="{% if request.path == url_applicationpollview %}selected{% endif %}"><a href="{% url application_poll_view poll.id %}"><img src="{% static 'images/icons/edit.png' %}"> {{ forloop.counter }}. {% trans "Vote" %}</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
{# Agenda Item #}
|
|
||||||
{% if perms.agenda.can_manage_agenda %}
|
|
||||||
<li>
|
|
||||||
<a href="{% url application_create_agenda application.id %}">{% trans 'New agenda item' %}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
@ -1,34 +0,0 @@
|
|||||||
{% load staticfiles %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load tags %}
|
|
||||||
|
|
||||||
<ul style="line-height: 180%">
|
|
||||||
{% for application in applications %}
|
|
||||||
<li class="{% if application.active %}activeline{% endif %}">
|
|
||||||
<a href="{% url projector_activate_slide application.sid %}" class="activate_link {% if application.active %}active{% endif %}">
|
|
||||||
<div></div>
|
|
||||||
</a>
|
|
||||||
<a href="{% model_url application 'delete' %}" title="{% trans 'Delete' %}" class="icon delete right">
|
|
||||||
<span></span>
|
|
||||||
</a>
|
|
||||||
<a href="{% model_url application 'edit' %}" title="{% trans 'Edit' %}" class="icon edit right">
|
|
||||||
<span></span>
|
|
||||||
</a>
|
|
||||||
<a href="{% url projctor_preview_slide application.sid %}" title="{% trans 'Preview' %}" class="icon preview right">
|
|
||||||
<span></span>
|
|
||||||
</a>
|
|
||||||
<a href="{% model_url application 'view' %}">
|
|
||||||
{{ application.public_version.title }}
|
|
||||||
</a>
|
|
||||||
({% trans "motion" %}
|
|
||||||
{% if application.number %}
|
|
||||||
{{ application.number }})
|
|
||||||
{% else %}
|
|
||||||
<i>[{% trans "no number" %}]</i>)
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
|
||||||
<li>{% trans 'No motion available.' %}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
@ -1,141 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
openslides.application.urls
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
URL list for the application app.
|
|
||||||
|
|
||||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
|
||||||
:license: GNU GPL, see LICENSE for more details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.conf.urls.defaults import url, patterns
|
|
||||||
|
|
||||||
from openslides.application.views import (ApplicationDelete, ViewPoll,
|
|
||||||
ApplicationPDF, ApplicationPollPDF, CreateAgendaItem)
|
|
||||||
|
|
||||||
urlpatterns = patterns('openslides.application.views',
|
|
||||||
url(r'^$',
|
|
||||||
'overview',
|
|
||||||
name='application_overview',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/$',
|
|
||||||
'view',
|
|
||||||
name='application_view',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/agenda/$',
|
|
||||||
CreateAgendaItem.as_view(),
|
|
||||||
name='application_create_agenda',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/newest/$',
|
|
||||||
'view',
|
|
||||||
{'newest': True},
|
|
||||||
name='application_view_newest',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^new/$',
|
|
||||||
'edit',
|
|
||||||
name='application_new',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^import/$',
|
|
||||||
'application_import',
|
|
||||||
name='application_import',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/edit/$',
|
|
||||||
'edit',
|
|
||||||
name='application_edit',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/del/$',
|
|
||||||
ApplicationDelete.as_view(),
|
|
||||||
name='application_delete',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^del/$',
|
|
||||||
ApplicationDelete.as_view(),
|
|
||||||
{ 'application_id' : None , 'application_ids' : None },
|
|
||||||
name='application_delete',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/setnumber/$',
|
|
||||||
'set_number',
|
|
||||||
name='application_set_number',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/setstatus/(?P<status>[a-z]{3})/$',
|
|
||||||
'set_status',
|
|
||||||
name='application_set_status',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/permit/$',
|
|
||||||
'permit',
|
|
||||||
name='application_permit',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^version/(?P<aversion_id>\d+)/permit/$',
|
|
||||||
'permit_version',
|
|
||||||
name='application_version_permit',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^version/(?P<aversion_id>\d+)/reject/$',
|
|
||||||
'reject_version',
|
|
||||||
name='application_version_reject',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/notpermit/$',
|
|
||||||
'notpermit',
|
|
||||||
name='application_notpermit',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/reset/$',
|
|
||||||
'reset',
|
|
||||||
name='application_reset',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/support/$',
|
|
||||||
'support',
|
|
||||||
name='application_support',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/unsupport/$',
|
|
||||||
'unsupport',
|
|
||||||
name='application_unsupport',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/gen_poll/$',
|
|
||||||
'gen_poll',
|
|
||||||
name='application_gen_poll',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^print/$',
|
|
||||||
ApplicationPDF.as_view(),
|
|
||||||
{'application_id': None},
|
|
||||||
name='print_applications',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<application_id>\d+)/print/$',
|
|
||||||
ApplicationPDF.as_view(),
|
|
||||||
name='print_application',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^poll/(?P<poll_id>\d+)/print/$',
|
|
||||||
ApplicationPollPDF.as_view(),
|
|
||||||
name='print_application_poll',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^poll/(?P<poll_id>\d+)/$',
|
|
||||||
ViewPoll.as_view(),
|
|
||||||
name='application_poll_view',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^poll/(?P<poll_id>\d+)/del/$',
|
|
||||||
'delete_poll',
|
|
||||||
name='application_poll_delete',
|
|
||||||
),
|
|
||||||
)
|
|
@ -218,7 +218,7 @@ class Assignment(models.Model, SlideMixin):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
# Remove any Agenda-Item, which is related to this application.
|
# Remove any Agenda-Item, which is related to this assignment.
|
||||||
for item in Item.objects.filter(related_sid=self.sid):
|
for item in Item.objects.filter(related_sid=self.sid):
|
||||||
item.delete()
|
item.delete()
|
||||||
super(Assignment, self).delete()
|
super(Assignment, self).delete()
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<div style="margin-right: 250px; min-width: 400px;">
|
<div style="margin-right: 250px; min-width: 400px;">
|
||||||
<h1>{{ assignment }}</h1>
|
<h1>{{ assignment }}</h1>
|
||||||
<p>{{ assignment.description }}</p>
|
<p>{{ assignment.description|linebreaks }}</p>
|
||||||
|
|
||||||
<h3>{% trans "Candidates" %}</h3>
|
<h3>{% trans "Candidates" %}</h3>
|
||||||
<ol>
|
<ol>
|
||||||
|
@ -430,11 +430,11 @@ class AssignmentPDF(PDFView):
|
|||||||
for candidate, poll_list in vote_results.iteritems():
|
for candidate, poll_list in vote_results.iteritems():
|
||||||
row = []
|
row = []
|
||||||
|
|
||||||
candidate_string = candidate.user.get_full_name()
|
candidate_string = candidate.clean_name
|
||||||
if candidate in elected_candidates:
|
if candidate in elected_candidates:
|
||||||
candidate_string = "* " + candidate_string
|
candidate_string = "* " + candidate_string
|
||||||
if candidate.category:
|
if candidate.name_suffix:
|
||||||
candidate_string += "\n(%s)" % candidate.category
|
candidate_string += "\n(%s)" % candidate.name_suffix
|
||||||
row.append(candidate_string)
|
row.append(candidate_string)
|
||||||
for vote in poll_list:
|
for vote in poll_list:
|
||||||
if vote == None:
|
if vote == None:
|
||||||
@ -565,7 +565,7 @@ class AssignmentPollPDF(PDFView):
|
|||||||
if self.poll.yesnoabstain:
|
if self.poll.yesnoabstain:
|
||||||
for option in options:
|
for option in options:
|
||||||
candidate = option.candidate
|
candidate = option.candidate
|
||||||
cell.append(Paragraph(candidate.user.get_full_name(),
|
cell.append(Paragraph(candidate.clean_name,
|
||||||
stylesheet['Ballot_option_name']))
|
stylesheet['Ballot_option_name']))
|
||||||
if candidate.name_suffix:
|
if candidate.name_suffix:
|
||||||
cell.append(Paragraph("(%s)" % candidate.name_suffix,
|
cell.append(Paragraph("(%s)" % candidate.name_suffix,
|
||||||
@ -591,10 +591,10 @@ class AssignmentPollPDF(PDFView):
|
|||||||
else:
|
else:
|
||||||
for option in options:
|
for option in options:
|
||||||
candidate = option.candidate
|
candidate = option.candidate
|
||||||
cell.append(Paragraph(circle + candidate.user.get_full_name(),
|
cell.append(Paragraph(circle + candidate.clean_name,
|
||||||
stylesheet['Ballot_option_name']))
|
stylesheet['Ballot_option_name']))
|
||||||
if candidate.category:
|
if candidate.name_suffix:
|
||||||
cell.append(Paragraph("(%s)" % candidate.category,
|
cell.append(Paragraph("(%s)" % candidate.name_suffix,
|
||||||
stylesheet['Ballot_option_group_right']))
|
stylesheet['Ballot_option_group_right']))
|
||||||
else:
|
else:
|
||||||
cell.append(Paragraph(" ",
|
cell.append(Paragraph(" ",
|
||||||
|
@ -66,8 +66,9 @@ class GeneralConfig(FormView):
|
|||||||
try:
|
try:
|
||||||
anonymous = Group.objects.get(name='Anonymous')
|
anonymous = Group.objects.get(name='Anonymous')
|
||||||
except Group.DoesNotExist:
|
except Group.DoesNotExist:
|
||||||
default_perms = [u'can_see_agenda', u'can_see_projector',
|
default_perms = ['can_see_agenda', 'can_see_projector',
|
||||||
u'can_see_application', u'can_see_assignment']
|
'can_see_motion', 'can_see_assignment',
|
||||||
|
'can_see_dashboard']
|
||||||
anonymous = Group()
|
anonymous = Group()
|
||||||
anonymous.name = 'Anonymous'
|
anonymous.name = 'Anonymous'
|
||||||
anonymous.save()
|
anonymous.save()
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.application.forms
|
openslides.motion.forms
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Forms for the application app.
|
Forms for the motion app.
|
||||||
|
|
||||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
@ -15,36 +15,36 @@ from django.utils.translation import ugettext_lazy as _, ugettext_noop
|
|||||||
|
|
||||||
from openslides.utils.forms import CssClassMixin
|
from openslides.utils.forms import CssClassMixin
|
||||||
from openslides.utils.person import PersonFormField, MultiplePersonFormField
|
from openslides.utils.person import PersonFormField, MultiplePersonFormField
|
||||||
from openslides.application.models import Application
|
from openslides.motion.models import Motion
|
||||||
|
|
||||||
|
|
||||||
class ApplicationForm(forms.Form, CssClassMixin):
|
class MotionForm(forms.Form, CssClassMixin):
|
||||||
title = forms.CharField(widget=forms.TextInput(), label=_("Title"))
|
title = forms.CharField(widget=forms.TextInput(), label=_("Title"))
|
||||||
text = forms.CharField(widget=forms.Textarea(), label=_("Text"))
|
text = forms.CharField(widget=forms.Textarea(), label=_("Text"))
|
||||||
reason = forms.CharField(widget=forms.Textarea(), required=False,
|
reason = forms.CharField(widget=forms.Textarea(), required=False,
|
||||||
label=_("Reason"))
|
label=_("Reason"))
|
||||||
|
|
||||||
|
|
||||||
class ApplicationFormTrivialChanges(ApplicationForm):
|
class MotionFormTrivialChanges(MotionForm):
|
||||||
trivial_change = forms.BooleanField(required=False,
|
trivial_change = forms.BooleanField(required=False,
|
||||||
label=_("Trivial change"),
|
label=_("Trivial change"),
|
||||||
help_text=_("Trivial changes don't create a new version."))
|
help_text=_("Trivial changes don't create a new version."))
|
||||||
|
|
||||||
|
|
||||||
class ApplicationManagerForm(forms.ModelForm, CssClassMixin):
|
class MotionManagerForm(forms.ModelForm, CssClassMixin):
|
||||||
submitter = PersonFormField()
|
submitter = PersonFormField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Application
|
model = Motion
|
||||||
exclude = ('number', 'status', 'permitted', 'log', 'supporter')
|
exclude = ('number', 'status', 'permitted', 'log', 'supporter')
|
||||||
|
|
||||||
|
|
||||||
class ApplicationManagerFormSupporter(ApplicationManagerForm):
|
class MotionManagerFormSupporter(MotionManagerForm):
|
||||||
# TODO: Do not show the submitter in the user-list
|
# TODO: Do not show the submitter in the user-list
|
||||||
supporter = MultiplePersonFormField(required=False, label=_("Supporters"))
|
supporter = MultiplePersonFormField(required=False, label=_("Supporters"))
|
||||||
|
|
||||||
|
|
||||||
class ApplicationImportForm(forms.Form, CssClassMixin):
|
class MotionImportForm(forms.Form, CssClassMixin):
|
||||||
csvfile = forms.FileField(
|
csvfile = forms.FileField(
|
||||||
widget=forms.FileInput(attrs={'size':'50'}),
|
widget=forms.FileInput(attrs={'size':'50'}),
|
||||||
label=_("CSV File"),
|
label=_("CSV File"),
|
||||||
@ -58,7 +58,7 @@ class ApplicationImportForm(forms.Form, CssClassMixin):
|
|||||||
|
|
||||||
|
|
||||||
class ConfigForm(forms.Form, CssClassMixin):
|
class ConfigForm(forms.Form, CssClassMixin):
|
||||||
application_min_supporters = forms.IntegerField(
|
motion_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 motion"),
|
label=_("Number of (minimum) required supporters for a motion"),
|
||||||
initial=4,
|
initial=4,
|
||||||
@ -66,12 +66,12 @@ class ConfigForm(forms.Form, CssClassMixin):
|
|||||||
max_value=8,
|
max_value=8,
|
||||||
help_text=_("Choose 0 to disable the supporting system"),
|
help_text=_("Choose 0 to disable the supporting system"),
|
||||||
)
|
)
|
||||||
application_preamble = forms.CharField(
|
motion_preamble = forms.CharField(
|
||||||
widget=forms.TextInput(),
|
widget=forms.TextInput(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Motion preamble")
|
label=_("Motion preamble")
|
||||||
)
|
)
|
||||||
application_pdf_ballot_papers_selection = forms.ChoiceField(
|
motion_pdf_ballot_papers_selection = forms.ChoiceField(
|
||||||
widget=forms.Select(),
|
widget=forms.Select(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Number of ballot papers (selection)"),
|
label=_("Number of ballot papers (selection)"),
|
||||||
@ -81,24 +81,24 @@ class ConfigForm(forms.Form, CssClassMixin):
|
|||||||
("CUSTOM_NUMBER", _("Use the following custom number")),
|
("CUSTOM_NUMBER", _("Use the following custom number")),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
application_pdf_ballot_papers_number = forms.IntegerField(
|
motion_pdf_ballot_papers_number = forms.IntegerField(
|
||||||
widget=forms.TextInput(attrs={'class':'small-input'}),
|
widget=forms.TextInput(attrs={'class':'small-input'}),
|
||||||
required=False,
|
required=False,
|
||||||
min_value=1,
|
min_value=1,
|
||||||
label=_("Custom number of ballot papers")
|
label=_("Custom number of ballot papers")
|
||||||
)
|
)
|
||||||
application_pdf_title = forms.CharField(
|
motion_pdf_title = forms.CharField(
|
||||||
widget=forms.TextInput(),
|
widget=forms.TextInput(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Title for PDF document (all motions)")
|
label=_("Title for PDF document (all motions)")
|
||||||
)
|
)
|
||||||
application_pdf_preamble = forms.CharField(
|
motion_pdf_preamble = forms.CharField(
|
||||||
widget=forms.Textarea(),
|
widget=forms.Textarea(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Preamble text for PDF document (all motions)")
|
label=_("Preamble text for PDF document (all motions)")
|
||||||
)
|
)
|
||||||
|
|
||||||
application_allow_trivial_change = forms.BooleanField(
|
motion_allow_trivial_change = forms.BooleanField(
|
||||||
label=_("Allow trivial changes"),
|
label=_("Allow trivial changes"),
|
||||||
help_text=_('Warning: Trivial changes undermine the motions '
|
help_text=_('Warning: Trivial changes undermine the motions '
|
||||||
'autorisation system.'),
|
'autorisation system.'),
|
@ -1,10 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.application.models
|
openslides.motion.models
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Models for the application app.
|
Models for the motion app.
|
||||||
|
|
||||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
@ -34,13 +34,13 @@ from openslides.projector.models import SlideMixin
|
|||||||
from openslides.agenda.models import Item
|
from openslides.agenda.models import Item
|
||||||
|
|
||||||
|
|
||||||
class ApplicationSupporter(models.Model):
|
class MotionSupporter(models.Model):
|
||||||
application = models.ForeignKey("Application")
|
motion = models.ForeignKey("Motion")
|
||||||
person = PersonField()
|
person = PersonField()
|
||||||
|
|
||||||
|
|
||||||
class Application(models.Model, SlideMixin):
|
class Motion(models.Model, SlideMixin):
|
||||||
prefix = "application"
|
prefix = "motion"
|
||||||
STATUS = (
|
STATUS = (
|
||||||
('pub', _('Published')),
|
('pub', _('Published')),
|
||||||
('per', _('Permitted')),
|
('per', _('Permitted')),
|
||||||
@ -74,10 +74,10 @@ class Application(models.Model, SlideMixin):
|
|||||||
@property
|
@property
|
||||||
def last_version(self):
|
def last_version(self):
|
||||||
"""
|
"""
|
||||||
Return last version of the application.
|
Return last version of the motion.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return AVersion.objects.filter(application=self).order_by('id') \
|
return AVersion.objects.filter(motion=self).order_by('id') \
|
||||||
.reverse()[0]
|
.reverse()[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
@ -85,7 +85,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
@property
|
@property
|
||||||
def public_version(self):
|
def public_version(self):
|
||||||
"""
|
"""
|
||||||
Return permitted, if the application was permitted, else last_version
|
Return permitted, if the motion was permitted, else last_version
|
||||||
"""
|
"""
|
||||||
if self.permitted is not None:
|
if self.permitted is not None:
|
||||||
return self.permitted
|
return self.permitted
|
||||||
@ -115,14 +115,14 @@ class Application(models.Model, SlideMixin):
|
|||||||
@property
|
@property
|
||||||
def versions(self):
|
def versions(self):
|
||||||
"""
|
"""
|
||||||
Return a list of all versions of the application.
|
Return a list of all versions of the motion.
|
||||||
"""
|
"""
|
||||||
return AVersion.objects.filter(application=self)
|
return AVersion.objects.filter(motion=self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def creation_time(self):
|
def creation_time(self):
|
||||||
"""
|
"""
|
||||||
Return the time of the creation of the application.
|
Return the time of the creation of the motion.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self.versions[0].time
|
return self.versions[0].time
|
||||||
@ -132,7 +132,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
@property
|
@property
|
||||||
def notes(self):
|
def notes(self):
|
||||||
"""
|
"""
|
||||||
Return some information of the application.
|
Return some information of the motion.
|
||||||
"""
|
"""
|
||||||
note = []
|
note = []
|
||||||
if self.status == "pub" and not self.enough_supporters:
|
if self.status == "pub" and not self.enough_supporters:
|
||||||
@ -146,9 +146,9 @@ class Application(models.Model, SlideMixin):
|
|||||||
@property
|
@property
|
||||||
def unpermitted_changes(self):
|
def unpermitted_changes(self):
|
||||||
"""
|
"""
|
||||||
Return True if the application has unpermitted changes.
|
Return True if the motion has unpermitted changes.
|
||||||
|
|
||||||
The application has unpermitted changes, if the permitted-version
|
The motion has unpermitted changes, if the permitted-version
|
||||||
is not the lastone and the lastone is not rejected.
|
is not the lastone and the lastone is not rejected.
|
||||||
TODO: rename the property in unchecked__changes
|
TODO: rename the property in unchecked__changes
|
||||||
"""
|
"""
|
||||||
@ -160,35 +160,35 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def supporters(self):
|
def supporters(self):
|
||||||
for object in self.applicationsupporter_set.all():
|
for object in self.motionsupporter_set.all():
|
||||||
yield object.person
|
yield object.person
|
||||||
|
|
||||||
def is_supporter(self, person):
|
def is_supporter(self, person):
|
||||||
try:
|
try:
|
||||||
return self.applicationsupporter_set.filter(person=person).exists()
|
return self.motionsupporter_set.filter(person=person).exists()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enough_supporters(self):
|
def enough_supporters(self):
|
||||||
"""
|
"""
|
||||||
Return True, if the application has enough supporters
|
Return True, if the motion has enough supporters
|
||||||
"""
|
"""
|
||||||
min_supporters = int(config['application_min_supporters'])
|
min_supporters = int(config['motion_min_supporters'])
|
||||||
if self.status == "pub":
|
if self.status == "pub":
|
||||||
return self.count_supporters() >= min_supporters
|
return self.count_supporters() >= min_supporters
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def count_supporters(self):
|
def count_supporters(self):
|
||||||
return self.applicationsupporter_set.count()
|
return self.motionsupporter_set.count()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def missing_supporters(self):
|
def missing_supporters(self):
|
||||||
"""
|
"""
|
||||||
Return number of missing supporters
|
Return number of missing supporters
|
||||||
"""
|
"""
|
||||||
min_supporters = int(config['application_min_supporters'])
|
min_supporters = int(config['motion_min_supporters'])
|
||||||
delta = min_supporters - self.count_supporters()
|
delta = min_supporters - self.count_supporters()
|
||||||
if delta > 0:
|
if delta > 0:
|
||||||
return delta
|
return delta
|
||||||
@ -197,9 +197,9 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def save(self, user=None, nonewversion=False, trivial_change=False):
|
def save(self, user=None, nonewversion=False, trivial_change=False):
|
||||||
"""
|
"""
|
||||||
Save the Application, and create a new AVersion if necessary
|
Save the Motion, and create a new AVersion if necessary
|
||||||
"""
|
"""
|
||||||
super(Application, self).save()
|
super(Motion, self).save()
|
||||||
if nonewversion:
|
if nonewversion:
|
||||||
return
|
return
|
||||||
last_version = self.last_version
|
last_version = self.last_version
|
||||||
@ -229,14 +229,14 @@ class Application(models.Model, SlideMixin):
|
|||||||
version = AVersion(title=getattr(self, 'title', ''),
|
version = AVersion(title=getattr(self, 'title', ''),
|
||||||
text=getattr(self, 'text', ''),
|
text=getattr(self, 'text', ''),
|
||||||
reason=getattr(self, 'reason', ''),
|
reason=getattr(self, 'reason', ''),
|
||||||
application=self)
|
motion=self)
|
||||||
version.save()
|
version.save()
|
||||||
self.writelog(_("Version %s created") % version.aid, user)
|
self.writelog(_("Version %s created") % version.aid, user)
|
||||||
is_manager = user.has_perm('application.can_manage_application')
|
is_manager = user.has_perm('motion.can_manage_motion')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
is_manager = False
|
is_manager = False
|
||||||
|
|
||||||
supporters = self.applicationsupporter_set.all()
|
supporters = self.motionsupporter_set.all()
|
||||||
if (self.status == "pub"
|
if (self.status == "pub"
|
||||||
and supporters
|
and supporters
|
||||||
and not is_manager):
|
and not is_manager):
|
||||||
@ -245,7 +245,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def reset(self, user):
|
def reset(self, user):
|
||||||
"""
|
"""
|
||||||
Reset the application.
|
Reset the motion.
|
||||||
"""
|
"""
|
||||||
self.status = "pub"
|
self.status = "pub"
|
||||||
self.permitted = None
|
self.permitted = None
|
||||||
@ -254,43 +254,39 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def support(self, person):
|
def support(self, person):
|
||||||
"""
|
"""
|
||||||
Add a Supporter to the list of supporters of the application.
|
Add a Supporter to the list of supporters of the motion.
|
||||||
"""
|
"""
|
||||||
if person == self.submitter:
|
if person == self.submitter:
|
||||||
# TODO: Use own Exception
|
# TODO: Use own Exception
|
||||||
raise NameError('Supporter can not be the submitter of a ' \
|
raise NameError('Supporter can not be the submitter of a '
|
||||||
'application.')
|
'motion.')
|
||||||
if self.permitted is not None:
|
|
||||||
# TODO: Use own Exception
|
|
||||||
raise NameError('This application is already permitted.')
|
|
||||||
if not self.is_supporter(person):
|
if not self.is_supporter(person):
|
||||||
ApplicationSupporter(application=self, person=person).save()
|
MotionSupporter(motion=self, person=person).save()
|
||||||
self.writelog(_("Supporter: +%s") % (person))
|
self.writelog(_("Supporter: +%s") % (person))
|
||||||
|
# TODO: Raise a precise exception for the view in else-clause
|
||||||
|
|
||||||
def unsupport(self, person):
|
def unsupport(self, person):
|
||||||
"""
|
"""
|
||||||
remove a supporter from the list of supporters of the application
|
remove a supporter from the list of supporters of the motion
|
||||||
"""
|
"""
|
||||||
if self.permitted is not None:
|
|
||||||
# TODO: Use own Exception
|
|
||||||
raise NameError('This application is already permitted.')
|
|
||||||
try:
|
try:
|
||||||
object = self.applicationsupporter_set.get(person=person).delete()
|
object = self.motionsupporter_set.get(person=person).delete()
|
||||||
except ApplicationSupporter.DoesNotExist:
|
except MotionSupporter.DoesNotExist:
|
||||||
|
# TODO: Don't do nothing but raise a precise exception for the view
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.writelog(_("Supporter: -%s") % (person))
|
self.writelog(_("Supporter: -%s") % (person))
|
||||||
|
|
||||||
def set_number(self, number=None, user=None):
|
def set_number(self, number=None, user=None):
|
||||||
"""
|
"""
|
||||||
Set a number for ths application.
|
Set a number for ths motion.
|
||||||
"""
|
"""
|
||||||
if self.number is not None:
|
if self.number is not None:
|
||||||
# TODO: Use own Exception
|
# TODO: Use own Exception
|
||||||
raise NameError('This application has already a number.')
|
raise NameError('This motion has already a number.')
|
||||||
if number is None:
|
if number is None:
|
||||||
try:
|
try:
|
||||||
number = Application.objects.aggregate(Max('number')) \
|
number = Motion.objects.aggregate(Max('number')) \
|
||||||
['number__max'] + 1
|
['number__max'] + 1
|
||||||
except TypeError:
|
except TypeError:
|
||||||
number = 1
|
number = 1
|
||||||
@ -301,7 +297,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def permit(self, user=None):
|
def permit(self, user=None):
|
||||||
"""
|
"""
|
||||||
Change the status of this application to permit.
|
Change the status of this motion to permit.
|
||||||
"""
|
"""
|
||||||
self.set_status(user, "per")
|
self.set_status(user, "per")
|
||||||
aversion = self.last_version
|
aversion = self.last_version
|
||||||
@ -314,7 +310,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def notpermit(self, user=None):
|
def notpermit(self, user=None):
|
||||||
"""
|
"""
|
||||||
Change the status of this application to 'not permitted (rejected)'.
|
Change the status of this motion to 'not permitted (rejected)'.
|
||||||
"""
|
"""
|
||||||
self.set_status(user, "nop")
|
self.set_status(user, "nop")
|
||||||
#TODO: reject last version
|
#TODO: reject last version
|
||||||
@ -327,10 +323,10 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def set_status(self, user, status, force=False):
|
def set_status(self, user, status, force=False):
|
||||||
"""
|
"""
|
||||||
Set the status of the application.
|
Set the status of the motion.
|
||||||
"""
|
"""
|
||||||
error = True
|
error = True
|
||||||
for a, b in Application.STATUS:
|
for a, b in Motion.STATUS:
|
||||||
if status == a:
|
if status == a:
|
||||||
error = False
|
error = False
|
||||||
break
|
break
|
||||||
@ -364,25 +360,25 @@ class Application(models.Model, SlideMixin):
|
|||||||
"""
|
"""
|
||||||
actions = []
|
actions = []
|
||||||
|
|
||||||
# check if user allowed to withdraw an application
|
# check if user allowed to withdraw an motion
|
||||||
if ((self.status == "pub"
|
if ((self.status == "pub"
|
||||||
and self.number
|
and self.number
|
||||||
and user == self.submitter)
|
and user == self.submitter)
|
||||||
or (self.status == "pub"
|
or (self.status == "pub"
|
||||||
and self.number
|
and self.number
|
||||||
and user.has_perm("application.can_manage_application"))
|
and user.has_perm("motion.can_manage_motion"))
|
||||||
or (self.status == "per"
|
or (self.status == "per"
|
||||||
and user == self.submitter)
|
and user == self.submitter)
|
||||||
or (self.status == "per"
|
or (self.status == "per"
|
||||||
and user.has_perm("application.can_manage_application"))):
|
and user.has_perm("motion.can_manage_motion"))):
|
||||||
actions.append("wit")
|
actions.append("wit")
|
||||||
#Check if the user can review the application
|
#Check if the user can review the motion
|
||||||
if (self.status == "rev"
|
if (self.status == "rev"
|
||||||
and (self.submitter == user
|
and (self.submitter == user
|
||||||
or user.has_perm("application.can_manage_application"))):
|
or user.has_perm("motion.can_manage_motion"))):
|
||||||
actions.append("pub")
|
actions.append("pub")
|
||||||
|
|
||||||
# Check if the user can support and unspoort the application
|
# Check if the user can support and unspoort the motion
|
||||||
if (self.status == "pub"
|
if (self.status == "pub"
|
||||||
and user != self.submitter
|
and user != self.submitter
|
||||||
and not self.is_supporter(user)):
|
and not self.is_supporter(user)):
|
||||||
@ -391,22 +387,22 @@ class Application(models.Model, SlideMixin):
|
|||||||
if self.status == "pub" and self.is_supporter(user):
|
if self.status == "pub" and self.is_supporter(user):
|
||||||
actions.append("unsupport")
|
actions.append("unsupport")
|
||||||
|
|
||||||
#Check if the user can edit the application
|
#Check if the user can edit the motion
|
||||||
if (user == self.submitter \
|
if (user == self.submitter \
|
||||||
and (self.status in ('pub', 'per'))) \
|
and (self.status in ('pub', 'per'))) \
|
||||||
or user.has_perm("application.can_manage_application"):
|
or user.has_perm("motion.can_manage_motion"):
|
||||||
actions.append("edit")
|
actions.append("edit")
|
||||||
|
|
||||||
# Check if the user can delete the application (admin, manager, owner)
|
# Check if the user can delete the motion (admin, manager, owner)
|
||||||
# reworked as requiered in #100
|
# reworked as requiered in #100
|
||||||
if (user.has_perm("applicatoin.can_delete_all_applications") or
|
if (user.has_perm("motion.can_delete_all_motions") or
|
||||||
(user.has_perm("application.can_manage_application") and
|
(user.has_perm("motion.can_manage_motion") and
|
||||||
self.number is None) or
|
self.number is None) or
|
||||||
(self.submitter == user and self.number is None)):
|
(self.submitter == user and self.number is None)):
|
||||||
actions.append("delete")
|
actions.append("delete")
|
||||||
|
|
||||||
#For the rest, all actions need the manage permission
|
#For the rest, all actions need the manage permission
|
||||||
if not user.has_perm("application.can_manage_application"):
|
if not user.has_perm("motion.can_manage_motion"):
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
if self.status == "pub":
|
if self.status == "pub":
|
||||||
@ -430,17 +426,17 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def delete(self, force=False):
|
def delete(self, force=False):
|
||||||
"""
|
"""
|
||||||
Delete the application. It is not possible, if the application has
|
Delete the motion. It is not possible, if the motion has
|
||||||
allready a number
|
allready a number
|
||||||
"""
|
"""
|
||||||
if self.number and not force:
|
if self.number and not force:
|
||||||
raise NameError('The application has already a number. ' \
|
raise NameError('The motion has already a number. ' \
|
||||||
'You can not delete it.')
|
'You can not delete it.')
|
||||||
|
|
||||||
|
|
||||||
for item in Item.objects.filter(related_sid=self.sid):
|
for item in Item.objects.filter(related_sid=self.sid):
|
||||||
item.delete()
|
item.delete()
|
||||||
super(Application, self).delete()
|
super(Motion, self).delete()
|
||||||
|
|
||||||
def writelog(self, text, user=None):
|
def writelog(self, text, user=None):
|
||||||
if not self.log:
|
if not self.log:
|
||||||
@ -461,7 +457,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""
|
"""
|
||||||
if name is title, text, reason or time,
|
if name is title, text, reason or time,
|
||||||
Return this attribute from the newest version of the application
|
Return this attribute from the newest version of the motion
|
||||||
"""
|
"""
|
||||||
if name in ('title', 'text', 'reason', 'time', 'aid'):
|
if name in ('title', 'text', 'reason', 'time', 'aid'):
|
||||||
try:
|
try:
|
||||||
@ -476,9 +472,9 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
def gen_poll(self, user=None):
|
def gen_poll(self, user=None):
|
||||||
"""
|
"""
|
||||||
Generates a poll object for the application
|
Generates a poll object for the motion
|
||||||
"""
|
"""
|
||||||
poll = ApplicationPoll(application=self)
|
poll = MotionPoll(motion=self)
|
||||||
poll.save()
|
poll.save()
|
||||||
poll.set_options()
|
poll.set_options()
|
||||||
self.writelog(_("Poll created"), user)
|
self.writelog(_("Poll created"), user)
|
||||||
@ -486,7 +482,7 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def polls(self):
|
def polls(self):
|
||||||
return self.applicationpoll_set.all()
|
return self.motionpoll_set.all()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def results(self):
|
def results(self):
|
||||||
@ -510,19 +506,19 @@ class Application(models.Model, SlideMixin):
|
|||||||
"""
|
"""
|
||||||
return the slide dict
|
return the slide dict
|
||||||
"""
|
"""
|
||||||
data = super(Application, self).slide()
|
data = super(Motion, self).slide()
|
||||||
data['application'] = self
|
data['motion'] = self
|
||||||
data['title'] = self.title
|
data['title'] = self.title
|
||||||
data['template'] = 'projector/Application.html'
|
data['template'] = 'projector/Motion.html'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_absolute_url(self, link='view'):
|
def get_absolute_url(self, link='view'):
|
||||||
if link == 'view':
|
if link == 'view':
|
||||||
return reverse('application_view', args=[str(self.id)])
|
return reverse('motion_view', args=[str(self.id)])
|
||||||
if link == 'edit':
|
if link == 'edit':
|
||||||
return reverse('application_edit', args=[str(self.id)])
|
return reverse('motion_edit', args=[str(self.id)])
|
||||||
if link == 'delete':
|
if link == 'delete':
|
||||||
return reverse('application_delete', args=[str(self.id)])
|
return reverse('motion_delete', args=[str(self.id)])
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
try:
|
try:
|
||||||
@ -532,10 +528,10 @@ class Application(models.Model, SlideMixin):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
('can_see_application', ugettext_noop("Can see motions")),
|
('can_see_motion', ugettext_noop("Can see motions")),
|
||||||
('can_create_application', ugettext_noop("Can create motions")),
|
('can_create_motion', ugettext_noop("Can create motions")),
|
||||||
('can_support_application', ugettext_noop("Can support motions")),
|
('can_support_motion', ugettext_noop("Can support motions")),
|
||||||
('can_manage_application', ugettext_noop("Can manage motions")),
|
('can_manage_motion', ugettext_noop("Can manage motions")),
|
||||||
)
|
)
|
||||||
ordering = ('number',)
|
ordering = ('number',)
|
||||||
|
|
||||||
@ -546,7 +542,7 @@ class AVersion(models.Model):
|
|||||||
reason = models.TextField(null=True, blank=True, verbose_name = _("Reason"))
|
reason = models.TextField(null=True, blank=True, verbose_name = _("Reason"))
|
||||||
rejected = models.BooleanField() # = Not Permitted
|
rejected = models.BooleanField() # = Not Permitted
|
||||||
time = models.DateTimeField(auto_now=True)
|
time = models.DateTimeField(auto_now=True)
|
||||||
application = models.ForeignKey(Application)
|
motion = models.ForeignKey(Motion)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "%s %s" % (self.id, self.title)
|
return "%s %s" % (self.id, self.title)
|
||||||
@ -557,31 +553,31 @@ class AVersion(models.Model):
|
|||||||
return self._aid
|
return self._aid
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self._aid = AVersion.objects \
|
self._aid = AVersion.objects \
|
||||||
.filter(application=self.application) \
|
.filter(motion=self.motion) \
|
||||||
.filter(id__lte=self.id).count()
|
.filter(id__lte=self.id).count()
|
||||||
return self._aid
|
return self._aid
|
||||||
|
|
||||||
register_slidemodel(Application)
|
register_slidemodel(Motion)
|
||||||
|
|
||||||
|
|
||||||
class ApplicationVote(BaseVote):
|
class MotionVote(BaseVote):
|
||||||
option = models.ForeignKey('ApplicationOption')
|
option = models.ForeignKey('MotionOption')
|
||||||
|
|
||||||
|
|
||||||
class ApplicationOption(BaseOption):
|
class MotionOption(BaseOption):
|
||||||
poll = models.ForeignKey('ApplicationPoll')
|
poll = models.ForeignKey('MotionPoll')
|
||||||
vote_class = ApplicationVote
|
vote_class = MotionVote
|
||||||
|
|
||||||
|
|
||||||
class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast):
|
class MotionPoll(BasePoll, CountInvalid, CountVotesCast):
|
||||||
option_class = ApplicationOption
|
option_class = MotionOption
|
||||||
vote_values = [ugettext_noop('Yes'), ugettext_noop('No'),
|
vote_values = [ugettext_noop('Yes'), ugettext_noop('No'),
|
||||||
ugettext_noop('Abstain')]
|
ugettext_noop('Abstain')]
|
||||||
|
|
||||||
application = models.ForeignKey(Application)
|
motion = models.ForeignKey(Motion)
|
||||||
|
|
||||||
def get_application(self):
|
def get_motion(self):
|
||||||
return self.application
|
return self.motion
|
||||||
|
|
||||||
def set_options(self):
|
def set_options(self):
|
||||||
#TODO: maybe it is possible with .create() to call this without poll=self
|
#TODO: maybe it is possible with .create() to call this without poll=self
|
||||||
@ -592,20 +588,20 @@ class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast):
|
|||||||
CountVotesCast.append_pollform_fields(self, fields)
|
CountVotesCast.append_pollform_fields(self, fields)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('application_poll_view', args=[self.id])
|
return reverse('motion_poll_view', args=[self.id])
|
||||||
|
|
||||||
def get_ballot(self):
|
def get_ballot(self):
|
||||||
return self.application.applicationpoll_set.filter(id__lte=self.id).count()
|
return self.motion.motionpoll_set.filter(id__lte=self.id).count()
|
||||||
|
|
||||||
|
|
||||||
@receiver(default_config_value, dispatch_uid="application_default_config")
|
@receiver(default_config_value, dispatch_uid="motion_default_config")
|
||||||
def default_config(sender, key, **kwargs):
|
def default_config(sender, key, **kwargs):
|
||||||
return {
|
return {
|
||||||
'application_min_supporters': 0,
|
'motion_min_supporters': 0,
|
||||||
'application_preamble': _('The assembly may decide,'),
|
'motion_preamble': _('The assembly may decide,'),
|
||||||
'application_pdf_ballot_papers_selection': 'CUSTOM_NUMBER',
|
'motion_pdf_ballot_papers_selection': 'CUSTOM_NUMBER',
|
||||||
'application_pdf_ballot_papers_number': '8',
|
'motion_pdf_ballot_papers_number': '8',
|
||||||
'application_pdf_title': _('Motions'),
|
'motion_pdf_title': _('Motions'),
|
||||||
'application_pdf_preamble': '',
|
'motion_pdf_preamble': '',
|
||||||
'application_allow_trivial_change': False,
|
'motion_allow_trivial_change': False,
|
||||||
}.get(key)
|
}.get(key)
|
66
openslides/motion/templates/motion/base_motion.html
Normal file
66
openslides/motion/templates/motion/base_motion.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load tags %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
|
||||||
|
{% block submenu %}
|
||||||
|
{% url motion_overview as url_motionoverview %}
|
||||||
|
<h4>{% trans "Motions" %}</h4>
|
||||||
|
<ul>
|
||||||
|
<li class="{% if request.path == url_motionoverview %}selected{% endif %}"><a href="{% url motion_overview %}">{% trans "All motions" %}</a></li>
|
||||||
|
{% if perms.motion.can_create_motion or perms.motion.can_manage_motion %}
|
||||||
|
<li class="{% active request '/motion/new' %}"><a href="{% url motion_new %}">{% trans "New motion" %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.motion.can_manage_motion %}
|
||||||
|
<li class="{% active request '/motion/import' %}"><a href="{% url motion_import %}">{% trans 'Import motions' %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><a href="{% url print_motions %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'All motions as PDF' %}</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{# second submenu #}
|
||||||
|
{% if motion %}
|
||||||
|
<br>
|
||||||
|
<h3>{% trans "Motion No." %}
|
||||||
|
{% if motion.number != None %}
|
||||||
|
{{ motion.number }}
|
||||||
|
{% else %}
|
||||||
|
<i>[-]</i>
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{# view motion #}
|
||||||
|
{% url motion_view motion.id as url_motionview %}
|
||||||
|
<li class="{% if request.path == url_motionview %}selected{% endif %}"><a href="{% url motion_view motion.id %}">{% trans 'View motion' %}</a></li>
|
||||||
|
{# edit motion #}
|
||||||
|
{% if "edit" in actions %}
|
||||||
|
{% url motion_edit motion.id as url_motionedit %}
|
||||||
|
<li class="{% if request.path == url_motionedit %}selected{% endif %}"><a href="{% url motion_edit motion.id %}"><img src="{% static 'images/icons/edit.png' %}"> {% trans 'Edit motion' %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{# delete motion #}
|
||||||
|
{% if "delete" in actions %}
|
||||||
|
<li><a href="{% url motion_delete motion.id %}"><img src="{% static 'images/icons/delete.png' %}"> {% trans 'Delete motion' %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{# PDF #}
|
||||||
|
<li><a href="{% url print_motion motion.id %}"><img src="{% static 'images/icons/pdf.png' %}"> {% trans 'Motion as PDF' %}</a></li>
|
||||||
|
{# activate and polls #}
|
||||||
|
{% if perms.projector.can_manage_projector %}
|
||||||
|
<li>
|
||||||
|
<a class="activate_link {% if item.active %}active{% endif %}" href="{% url projector_activate_slide motion.sid %}"><img src="{% static 'images/icons/projector.png' %}"> {% trans 'Show Motion' %}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.motion.can_manage_motion %}
|
||||||
|
{% for poll in motion.polls %}
|
||||||
|
{% url motion_poll_view poll.id as url_motionpollview %}
|
||||||
|
<li class="{% if request.path == url_motionpollview %}selected{% endif %}"><a href="{% url motion_poll_view poll.id %}"><img src="{% static 'images/icons/edit.png' %}"> {{ forloop.counter }}. {% trans "Vote" %}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{# Agenda Item #}
|
||||||
|
{% if perms.agenda.can_manage_agenda %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url motion_create_agenda motion.id %}">{% trans 'New agenda item' %}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
@ -2,18 +2,18 @@
|
|||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}{{ block.super }} – {% trans "Application settings" %}{% endblock %}
|
{% block title %}{{ block.super }} – {% trans "Motion settings" %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "Application settings" %}</h1>
|
<h1>{% trans "Motion settings" %}</h1>
|
||||||
<form action="" method="post">{% csrf_token %}
|
<form action="" method="post">{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
<p>
|
<p>
|
||||||
<button class="button" type="submit">
|
<button class="button" type="submit">
|
||||||
<span class="icon ok">{% trans 'Save' %}</span>
|
<span class="icon ok">{% trans 'Save' %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a href='{% url config_application %}'>
|
<a href='{% url config_motion %}'>
|
||||||
<button class="button" type="button" onclick="window.location='{% url config_application %}'">
|
<button class="button" type="button" onclick="window.location='{% url config_motion %}'">
|
||||||
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
@ -1,10 +1,10 @@
|
|||||||
{% extends "application/base_application.html" %}
|
{% extends "motion/base_motion.html" %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{{ block.super }} –
|
{{ block.super }} –
|
||||||
{% if application %}
|
{% if motion %}
|
||||||
{% trans "Edit motion" %}
|
{% trans "Edit motion" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "New motion" %}
|
{% trans "New motion" %}
|
||||||
@ -12,7 +12,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if application %}
|
{% if motion %}
|
||||||
<h1>{% trans "Edit motion" %}</h1>
|
<h1>{% trans "Edit motion" %}</h1>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>{% trans "New motion" %}</h1>
|
<h1>{% trans "New motion" %}</h1>
|
||||||
@ -28,8 +28,8 @@
|
|||||||
<button class="button" type="submit" name="apply">
|
<button class="button" type="submit" name="apply">
|
||||||
<span class="icon apply">{% trans 'Apply' %}</span>
|
<span class="icon apply">{% trans 'Apply' %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a href='{% url application_overview %}'>
|
<a href='{% url motion_overview %}'>
|
||||||
<button class="button" type="button" onclick="window.location='{% url application_overview %}'">
|
<button class="button" type="button" onclick="window.location='{% url motion_overview %}'">
|
||||||
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "application/base_application.html" %}
|
{% extends "motion/base_motion.html" %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
@ -22,8 +22,8 @@
|
|||||||
<button class="button" type="submit">
|
<button class="button" type="submit">
|
||||||
<span class="icon import">{% trans 'Import' %}</span>
|
<span class="icon import">{% trans 'Import' %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a href="{% url application_overview%}">
|
<a href="{% url motion_overview%}">
|
||||||
<button class="button" type="button" onclick="window.location='{% url application_overview %}'">
|
<button class="button" type="button" onclick="window.location='{% url motion_overview %}'">
|
||||||
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "application/base_application.html" %}
|
{% extends "motion/base_motion.html" %}
|
||||||
|
|
||||||
{% load tags %}
|
{% load tags %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
@ -28,8 +28,8 @@
|
|||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
{{ applications|length }}
|
{{ motions|length }}
|
||||||
{% blocktrans count counter=applications|length %}motion{% plural %}motions{% endblocktrans %}
|
{% blocktrans count counter=motions|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>
|
||||||
@ -42,39 +42,39 @@
|
|||||||
<th><a href="?sort=time{% if 'time' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Creation Time" %}<a></th>
|
<th><a href="?sort=time{% if 'time' in request.GET.sort and 'reverse' not in request.GET %}&reverse{%endif%}">{% trans "Creation Time" %}<a></th>
|
||||||
<th style="width: 1px;">{% trans "Actions" %}</th>
|
<th style="width: 1px;">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for app_info in applications %}
|
{% for app_info in motions %}
|
||||||
{% with application=app_info.application useractions=app_info.actions %}
|
{% with motion=app_info.motion useractions=app_info.actions %}
|
||||||
<tr class="{% cycle '' 'odd' %}
|
<tr class="{% cycle '' 'odd' %}
|
||||||
{% if application.active %}activeline{% endif %}">
|
{% if motion.active %}activeline{% endif %}">
|
||||||
<td>{% if application.number %}{{ application.number }}{% else %}-{% endif %}</td>
|
<td>{% if motion.number %}{{ motion.number }}{% else %}-{% endif %}</td>
|
||||||
<td><a href="{% url application_view application.id %}">{{ application.public_version.title }}</a></td>
|
<td><a href="{% url motion_view motion.id %}">{{ motion.public_version.title }}</a></td>
|
||||||
{% if min_supporters > 0 %}
|
{% if min_supporters > 0 %}
|
||||||
<td>{{ application.count_supporters }}</td>
|
<td>{{ motion.count_supporters }}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>{% if application.status != "pub" %}
|
<td>{% if motion.status != "pub" %}
|
||||||
{{ application.get_status_display }}<br>
|
{{ motion.get_status_display }}<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for note in application.notes %}
|
{% for note in motion.notes %}
|
||||||
{{ note }}
|
{{ note }}
|
||||||
{% if not forloop.last %}<br>{%endif%}
|
{% if not forloop.last %}<br>{%endif%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ application.submitter }}</td>
|
<td>{{ motion.submitter }}</td>
|
||||||
<td>{{ application.creation_time }}</td>
|
<td>{{ motion.creation_time }}</td>
|
||||||
<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 motion' %}">
|
<a class="activate_link {% if motion.active %}active{% endif %}" href="{% url projector_activate_slide motion.sid %}" title="{% trans 'Activate motion' %}">
|
||||||
<span></span>
|
<span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<a href="{% url application_edit application.id %}"><img src="{% static 'images/icons/edit.png' %}" title="{% trans 'Edit motion' %}"></a>
|
<a href="{% url motion_edit motion.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 motion' %}"></a>
|
<a href="{% url motion_delete motion.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 'Motion as PDF' %}"><img src="{% static 'images/icons/pdf.png' %}"></a>
|
<a href="{% url print_motion motion.id %}" title="{% trans 'Motion as PDF' %}"><img src="{% static 'images/icons/pdf.png' %}"></a>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
@ -1,16 +1,16 @@
|
|||||||
{% extends 'application/base_application.html' %}
|
{% extends 'motion/base_motion.html' %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{{ block.super }} – {% trans "Motion" %} "{{ application.public_version.title }}"
|
{{ block.super }} – {% trans "Motion" %} "{{ motion.public_version.title }}"
|
||||||
– {{ ballot }}. {% trans "Vote" %}
|
– {{ ballot }}. {% trans "Vote" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{{ application.public_version.title }} ({% trans "Motion" %}
|
<h1>{{ motion.public_version.title }} ({% trans "Motion" %}
|
||||||
{{ application.number }}) – {{ ballot }}. {% trans "Vote" %}</h1>
|
{{ motion.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 %}
|
||||||
{{ pre_form }}
|
{{ pre_form }}
|
||||||
@ -40,8 +40,8 @@
|
|||||||
{{ post_form }}
|
{{ post_form }}
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href='{% url print_application_poll poll.id %}'>
|
<a href='{% url print_motion_poll poll.id %}'>
|
||||||
<button class="button" type="button" onclick="window.location='{% url print_application_poll poll.id %}'">
|
<button class="button" type="button" onclick="window.location='{% url print_motion_poll poll.id %}'">
|
||||||
<span class="icon pdf">{% trans 'Ballot paper as PDF' %}</span>
|
<span class="icon pdf">{% trans 'Ballot paper as PDF' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
@ -54,8 +54,8 @@
|
|||||||
<button class="button" type="submit" name="apply">
|
<button class="button" type="submit" name="apply">
|
||||||
<span class="icon apply">{% trans 'Apply' %}</span>
|
<span class="icon apply">{% trans 'Apply' %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a href='{% url application_view application.id %}'>
|
<a href='{% url motion_view motion.id %}'>
|
||||||
<button class="button" type="button" onclick="window.location='{% url application_view application.id %}'">
|
<button class="button" type="button" onclick="window.location='{% url motion_view motion.id %}'">
|
||||||
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "application/base_application.html" %}
|
{% extends "motion/base_motion.html" %}
|
||||||
|
|
||||||
{% load tags %}
|
{% load tags %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
@ -16,15 +16,15 @@
|
|||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<h4>{% trans "Submitter" %}:</h4>
|
<h4>{% trans "Submitter" %}:</h4>
|
||||||
{{ application.submitter }}
|
{{ motion.submitter }}
|
||||||
|
|
||||||
{% if min_supporters > 0 %}
|
{% if min_supporters > 0 %}
|
||||||
<h4>{% trans "Supporters" %}: *</h4>
|
<h4>{% trans "Supporters" %}: *</h4>
|
||||||
{% if not application.supporters %}
|
{% if not motion.supporters %}
|
||||||
-
|
-
|
||||||
{% else %}
|
{% else %}
|
||||||
<ol>
|
<ol>
|
||||||
{% for supporter in application.supporters %}
|
{% for supporter in motion.supporters %}
|
||||||
<li> {{ supporter }}</li>
|
<li> {{ supporter }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ol>
|
</ol>
|
||||||
@ -32,21 +32,21 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h4>{% trans "Status" %}:</h4>
|
<h4>{% trans "Status" %}:</h4>
|
||||||
{% if application.status != "pub" %}
|
{% if motion.status != "pub" %}
|
||||||
{% trans application.get_status_display %}
|
{% trans motion.get_status_display %}
|
||||||
<br>
|
<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for note in application.notes %}
|
{% for note in motion.notes %}
|
||||||
{{ note }}
|
{{ note }}
|
||||||
{% if not forloop.last %}<br>{% endif %}
|
{% if not forloop.last %}<br>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<h4>{% trans "Vote results" %}:</h4>
|
<h4>{% trans "Vote results" %}:</h4>
|
||||||
{% with application.polls as polls %}
|
{% with motion.polls as polls %}
|
||||||
{% if not polls.exists %}
|
{% if not polls.exists %}
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
{% if "genpoll" in actions %}
|
{% if "genpoll" in actions %}
|
||||||
<a href='{% url application_gen_poll application.id %}'>
|
<a href='{% url motion_gen_poll motion.id %}'>
|
||||||
<span class="button">
|
<span class="button">
|
||||||
<span class="icon statistics">{% trans 'New vote' %}</span>
|
<span class="icon statistics">{% trans 'New vote' %}</span>
|
||||||
</span>
|
</span>
|
||||||
@ -60,14 +60,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<ul class="results">
|
<ul class="results">
|
||||||
{% for poll in polls %}
|
{% for poll in polls %}
|
||||||
{% if perms.application.can_manage_application or poll.has_votes %}
|
{% if perms.motion.can_manage_motion or poll.has_votes %}
|
||||||
<li>
|
<li>
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<strong>{{ forloop.counter }}. {% trans "Vote" %} </strong>
|
<strong>{{ forloop.counter }}. {% trans "Vote" %} </strong>
|
||||||
<a class="icon edit" href="{% url application_poll_view poll.id %}" title="{% trans 'Edit Vote' %}">
|
<a class="icon edit" href="{% url motion_poll_view poll.id %}" title="{% trans 'Edit Vote' %}">
|
||||||
<span></span>
|
<span></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="icon delete" href="{% url application_poll_delete poll.id %}" title="{% trans 'Delete Vote' %}">
|
<a class="icon delete" href="{% url motion_poll_delete poll.id %}" title="{% trans 'Delete Vote' %}">
|
||||||
<span></span>
|
<span></span>
|
||||||
</a>
|
</a>
|
||||||
{% elif poll.has_votes %}
|
{% elif poll.has_votes %}
|
||||||
@ -84,18 +84,18 @@
|
|||||||
<img src="{% static 'images/icons/voting-total.png' %}" title="{% trans 'Votes cast' %}"> {{ poll.print_votescast }}
|
<img src="{% static 'images/icons/voting-total.png' %}" title="{% trans 'Votes cast' %}"> {{ poll.print_votescast }}
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
{% if forloop.last %}
|
{% if forloop.last %}
|
||||||
{% if "genpoll" in actions %}
|
{% if "genpoll" in actions %}
|
||||||
<a href='{% url application_gen_poll application.id %}'>
|
<a href='{% url motion_gen_poll motion.id %}'>
|
||||||
<span class="button"><span class="icon statistics">{% trans 'New vote' %}</span></span>
|
<span class="button"><span class="icon statistics">{% trans 'New vote' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<a href='{% url application_poll_view poll.id %}'>
|
<a href='{% url motion_poll_view poll.id %}'>
|
||||||
<span class="button"><span class="icon statistics">{% trans 'Enter result' %}</span></span>
|
<span class="button"><span class="icon statistics">{% trans 'Enter result' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -107,26 +107,26 @@
|
|||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
<h4>{% trans "Creation Time" %}:</h4>
|
<h4>{% trans "Creation Time" %}:</h4>
|
||||||
{{ application.creation_time }}
|
{{ motion.creation_time }}
|
||||||
|
|
||||||
<p></p>
|
<p></p>
|
||||||
{% if "wit" in actions and user == application.submitter.user %}
|
{% if "wit" in actions and user == motion.submitter.user %}
|
||||||
<p></p>
|
<p></p>
|
||||||
<a href='{% url application_set_status application.id 'wit' %}'>
|
<a href='{% url motion_set_status motion.id 'wit' %}'>
|
||||||
<span class="button"><span class="icon revert">{% trans 'Withdraw' %}</span></span>
|
<span class="button"><span class="icon revert">{% trans 'Withdraw' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.application.can_support_application and min_supporters > 0 %}
|
{% if perms.motion.can_support_motion and min_supporters > 0 %}
|
||||||
{% if "unsupport" in actions %}
|
{% if "unsupport" in actions %}
|
||||||
<p></p>
|
<p></p>
|
||||||
<a href='{% url application_unsupport application.id %}'>
|
<a href='{% url motion_unsupport motion.id %}'>
|
||||||
<span class="button"><span class="icon remove">{% trans 'Unsupport' %}</span></span>
|
<span class="button"><span class="icon remove">{% trans 'Unsupport' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "support" in actions %}
|
{% if "support" in actions %}
|
||||||
<p></p>
|
<p></p>
|
||||||
<a href='{% url application_support application.id %}'>
|
<a href='{% url motion_support motion.id %}'>
|
||||||
<span class="button"><span class="icon add">{% trans 'Support' %}</span></span>
|
<span class="button"><span class="icon add">{% trans 'Support' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -138,23 +138,23 @@
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<h4><b>{% trans "Manage motion" %}</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>
|
||||||
{% if "pub" in actions %}
|
{% if "pub" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'pub' %}'><span class="button"><span class="icon ok-blue">{% trans 'Publish' %}</span></span></a>
|
<a href='{% url motion_set_status motion.id 'pub' %}'><span class="button"><span class="icon ok-blue">{% trans 'Publish' %}</span></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "per" in actions %}
|
{% if "per" in actions %}
|
||||||
<a href='{% url application_permit application.id %}'><span class="button"><span class="icon ok-blue">{% trans 'Permit' %}</span></span></a>
|
<a href='{% url motion_permit motion.id %}'><span class="button"><span class="icon ok-blue">{% trans 'Permit' %}</span></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "nop" in actions %}
|
{% if "nop" in actions %}
|
||||||
<a href='{% url application_notpermit application.id %}'><span class="button"><span class="icon reject">{% trans 'Not permit (reject)' %}</span></span></a>
|
<a href='{% url motion_notpermit motion.id %}'><span class="button"><span class="icon reject">{% trans 'Not permit (reject)' %}</span></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "setnumber" in actions %}
|
{% if "setnumber" in actions %}
|
||||||
<a href='{% url application_set_number application.id %}'><span class="button"><span class="icon number">{% trans 'Set Number' %}</span></span></a>
|
<a href='{% url motion_set_number motion.id %}'><span class="button"><span class="icon number">{% trans 'Set Number' %}</span></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -163,12 +163,12 @@
|
|||||||
{% if "acc" in actions or "rej" in actions %}
|
{% if "acc" in actions or "rej" in actions %}
|
||||||
<h4>{% trans "Result after vote" %}:</h4>
|
<h4>{% trans "Result after vote" %}:</h4>
|
||||||
{% if "acc" in actions %}
|
{% if "acc" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'acc' %}'>
|
<a href='{% url motion_set_status motion.id 'acc' %}'>
|
||||||
<span class="button"><span class="icon done">{% trans 'Accepted' %}</span></span>
|
<span class="button"><span class="icon done">{% trans 'Accepted' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "rej" in actions %}
|
{% if "rej" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'rej' %}'>
|
<a href='{% url motion_set_status motion.id 'rej' %}'>
|
||||||
<span class="button"><span class="icon reject">{% trans 'Rejected' %}</span></span>
|
<span class="button"><span class="icon reject">{% trans 'Rejected' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -177,26 +177,26 @@
|
|||||||
{% if "adj" in actions or "noc" in actions or "com" in actions or "wit" in actions %}
|
{% if "adj" in actions or "noc" in actions or "com" in actions or "wit" in actions %}
|
||||||
<h4>{% trans 'Result after debate' %}:</h4>
|
<h4>{% trans 'Result after debate' %}:</h4>
|
||||||
{% if "adj" in actions %}
|
{% if "adj" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'adj' %}'><span class="button">{% trans 'Adjourned' %}</span></a><br>
|
<a href='{% url motion_set_status motion.id 'adj' %}'><span class="button">{% trans 'Adjourned' %}</span></a><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "noc" in actions %}
|
{% if "noc" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'noc' %}'><span class="button">{% trans 'Not Concerned' %}</span></a><br>
|
<a href='{% url motion_set_status motion.id 'noc' %}'><span class="button">{% trans 'Not Concerned' %}</span></a><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "com" in actions %}
|
{% if "com" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'com' %}'><span class="button">{% trans 'Commited a bill' %}</span></a><br>
|
<a href='{% url motion_set_status motion.id 'com' %}'><span class="button">{% trans 'Commited a bill' %}</span></a><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "wit" in actions %}
|
{% if "wit" in actions %}
|
||||||
<a href='{% url application_set_status application.id 'wit' %}'><span class="button">{% trans 'Withdrawed by Submitter' %}</span></a>
|
<a href='{% url motion_set_status motion.id 'wit' %}'><span class="button">{% trans 'Withdrawed by Submitter' %}</span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p></p>
|
<p></p>
|
||||||
<hr>
|
<hr>
|
||||||
<h4>{% trans "For Administration only:" %}</h4>
|
<h4>{% trans "For Administration only:" %}</h4>
|
||||||
<a href='{% url application_reset application.id %}'>
|
<a href='{% url motion_reset motion.id %}'>
|
||||||
<span class="button"><span class="icon undo">{% trans 'Reset' %}</span></span>
|
<span class="button"><span class="icon undo">{% trans 'Reset' %}</span></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {# end perms.application.can_support_application #}
|
{% endif %} {# end perms.motion.can_support_motion #}
|
||||||
</div> <!-- end sidebar -->
|
</div> <!-- end sidebar -->
|
||||||
|
|
||||||
|
|
||||||
@ -204,8 +204,8 @@
|
|||||||
<h1>
|
<h1>
|
||||||
{{ version.title }}
|
{{ version.title }}
|
||||||
({% trans "Motion" %}
|
({% trans "Motion" %}
|
||||||
{% if application.number != None %}
|
{% if motion.number != None %}
|
||||||
{{ application.number }})
|
{{ motion.number }})
|
||||||
{% else %}
|
{% else %}
|
||||||
<i>[{% trans "no number" %}]</i>)
|
<i>[{% trans "no number" %}]</i>)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -213,12 +213,12 @@
|
|||||||
|
|
||||||
{% trans "Version" %} {{ version.aid }}
|
{% trans "Version" %} {{ version.aid }}
|
||||||
|
|
||||||
{% if application.public_version != application.last_version %}
|
{% if motion.public_version != motion.last_version %}
|
||||||
⋅
|
⋅
|
||||||
{% if version == application.public_version %}
|
{% if version == motion.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 motion_view_newest motion.id %}">{% trans "Go to version" %} {{ motion.last_version.aid }}.</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "This is not the authorized 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 motion_view motion.id %}">{% trans "Go to version" %} {{ motion.public_version.aid }}.</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if application.versions|length > 1 %}
|
{% if motion.versions|length > 1 %}
|
||||||
<h2>{% trans "Version History" %}:</h2>
|
<h2>{% trans "Version History" %}:</h2>
|
||||||
|
|
||||||
<table class="table valigntop" style="width: auto;">
|
<table class="table valigntop" style="width: auto;">
|
||||||
@ -248,18 +248,18 @@
|
|||||||
|
|
||||||
<th>{% trans "Reason" %}</th>
|
<th>{% trans "Reason" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for revision in application.versions %}
|
{% for revision in motion.versions %}
|
||||||
<tr class="{% cycle 'odd' '' %}">
|
<tr class="{% cycle 'odd' '' %}">
|
||||||
<td style="white-space:nowrap;">
|
<td style="white-space:nowrap;">
|
||||||
{% if application.status != "pub" %}
|
{% if motion.status != "pub" %}
|
||||||
{% if revision == application.permitted %}
|
{% if revision == motion.permitted %}
|
||||||
<img title="{% trans 'Version authorized' %}" 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.motion.can_manage_motion %}
|
||||||
<a href="{% url application_version_permit revision.id %}"><img title="{% trans 'Permit Version' %}" src="{% static 'images/icons/accept-grey.png' %}"></a>
|
<a href="{% url motion_version_permit revision.id %}"><img title="{% trans 'Permit Version' %}" src="{% static 'images/icons/accept-grey.png' %}"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not revision.rejected and revision.id > application.permitted.id and perms.application.can_manage_application %}
|
{% if not revision.rejected and revision.id > motion.permitted.id and perms.motion.can_manage_motion %}
|
||||||
<a href="{% url application_version_reject revision.id %}"><img title="{% trans 'Reject Version' %}" src="{% static 'images/icons/reject-grey.png' %}"></a>
|
<a href="{% url motion_version_reject revision.id %}"><img title="{% trans 'Reject Version' %}" src="{% static 'images/icons/reject-grey.png' %}"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if revision.rejected %}
|
{% if revision.rejected %}
|
||||||
@ -295,9 +295,9 @@
|
|||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.application.can_manage_application %}
|
{% if perms.motion.can_manage_motion %}
|
||||||
<h2>{% trans "Log" %}:</h2>
|
<h2>{% trans "Log" %}:</h2>
|
||||||
{{ application.log|linebreaks }}
|
{{ motion.log|linebreaks }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
34
openslides/motion/templates/motion/widget.html
Normal file
34
openslides/motion/templates/motion/widget.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{% load staticfiles %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load tags %}
|
||||||
|
|
||||||
|
<ul style="line-height: 180%">
|
||||||
|
{% for motion in motions %}
|
||||||
|
<li class="{% if motion.active %}activeline{% endif %}">
|
||||||
|
<a href="{% url projector_activate_slide motion.sid %}" class="activate_link {% if motion.active %}active{% endif %}">
|
||||||
|
<div></div>
|
||||||
|
</a>
|
||||||
|
<a href="{% model_url motion 'delete' %}" title="{% trans 'Delete' %}" class="icon delete right">
|
||||||
|
<span></span>
|
||||||
|
</a>
|
||||||
|
<a href="{% model_url motion 'edit' %}" title="{% trans 'Edit' %}" class="icon edit right">
|
||||||
|
<span></span>
|
||||||
|
</a>
|
||||||
|
<a href="{% url projctor_preview_slide motion.sid %}" title="{% trans 'Preview' %}" class="icon preview right">
|
||||||
|
<span></span>
|
||||||
|
</a>
|
||||||
|
<a href="{% model_url motion 'view' %}">
|
||||||
|
{{ motion.public_version.title }}
|
||||||
|
</a>
|
||||||
|
({% trans "motion" %}
|
||||||
|
{% if motion.number %}
|
||||||
|
{{ motion.number }})
|
||||||
|
{% else %}
|
||||||
|
<i>[{% trans "no number" %}]</i>)
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% empty %}
|
||||||
|
<li>{% trans 'No motion available.' %}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
@ -4,27 +4,27 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block title %}{{ block.super }} - {% trans "Motion" %} {{ application.number }}{% endblock %}
|
{% block title %}{{ block.super }} - {% trans "Motion" %} {{ motion.number }}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p><b>{% trans "Status" %}:</b><br>
|
<p><b>{% trans "Status" %}:</b><br>
|
||||||
{% if application.status != "pub" %}
|
{% if motion.status != "pub" %}
|
||||||
{% if application.status == "acc" %}
|
{% if motion.status == "acc" %}
|
||||||
<img src="{% static 'images/icons/voting-yes.png' %}">
|
<img src="{% static 'images/icons/voting-yes.png' %}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if application.status == "rej" %}
|
{% if motion.status == "rej" %}
|
||||||
<img src="{% static 'images/icons/voting-no.png' %}">
|
<img src="{% static 'images/icons/voting-no.png' %}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% trans application.get_status_display %}
|
{% trans motion.get_status_display %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% for note in application.notes %}
|
{% for note in motion.notes %}
|
||||||
{{ note }}
|
{{ note }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% with application.polls as polls %}
|
{% with motion.polls as polls %}
|
||||||
{% if polls.exists and polls.0.has_votes %}
|
{% if polls.exists and polls.0.has_votes %}
|
||||||
<p><b>{% trans "Poll result" %}:</b>
|
<p><b>{% trans "Poll result" %}:</b>
|
||||||
{% for poll in polls %}
|
{% for poll in polls %}
|
||||||
@ -53,29 +53,29 @@
|
|||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
<p><b>{% trans "Submitter" %}:</b><br>
|
<p><b>{% trans "Submitter" %}:</b><br>
|
||||||
{{ application.submitter }}
|
{{ motion.submitter }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1>
|
<h1>
|
||||||
{% if application.number != None %}
|
{% if motion.number != None %}
|
||||||
{% trans "Motion No." %} {{ application.number }}
|
{% trans "Motion No." %} {{ motion.number }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "Motion" %} <i>[{% trans "no number" %}]</i>
|
{% trans "Motion" %} <i>[{% trans "no number" %}]</i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h1>
|
</h1>
|
||||||
<b>{{ application.public_version.title }}</b>
|
<b>{{ motion.public_version.title }}</b>
|
||||||
<hr>
|
<hr>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scrollcontent %}
|
{% block scrollcontent %}
|
||||||
<p>
|
<p>
|
||||||
<div class="text">{{ application.public_version.text|linebreaks }}</div>
|
<div class="text">{{ motion.public_version.text|linebreaks }}</div>
|
||||||
{% if application.public_version.reason %}
|
{% if motion.public_version.reason %}
|
||||||
<br>
|
<br>
|
||||||
<div class="reason"><p><b>{% trans "Reason" %}:</b></p>
|
<div class="reason"><p><b>{% trans "Reason" %}:</b></p>
|
||||||
{{ application.public_version.reason|linebreaks }}</div>
|
{{ motion.public_version.reason|linebreaks }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,10 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.application.tests
|
openslides.motion.tests
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Unit tests for the application app.
|
Unit tests for the motion app.
|
||||||
|
|
||||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
@ -14,19 +14,19 @@ from django.test import TestCase
|
|||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
|
|
||||||
from openslides.participant.models import User
|
from openslides.participant.models import User
|
||||||
from openslides.application.models import Application, AVersion
|
from openslides.motion.models import Motion, AVersion
|
||||||
|
|
||||||
class ApplicationTest(TestCase):
|
class MotionTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.admin = User(username='testadmin')
|
self.admin = User(username='testadmin')
|
||||||
self.admin.save()
|
self.admin.save()
|
||||||
self.anonym = User(username='testanoym')
|
self.anonym = User(username='testanoym')
|
||||||
self.anonym.save()
|
self.anonym.save()
|
||||||
self.app1 = Application(submitter=self.admin)
|
self.app1 = Motion(submitter=self.admin)
|
||||||
self.app1.save()
|
self.app1.save()
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.app1 = Application.objects.get(pk=self.app1.id)
|
self.app1 = Motion.objects.get(pk=self.app1.id)
|
||||||
|
|
||||||
def testVersion(self):
|
def testVersion(self):
|
||||||
self.assertTrue(self.app1.versions.exists())
|
self.assertTrue(self.app1.versions.exists())
|
141
openslides/motion/urls.py
Normal file
141
openslides/motion/urls.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
openslides.motion.urls
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
URL list for the motion app.
|
||||||
|
|
||||||
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
||||||
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.conf.urls.defaults import url, patterns
|
||||||
|
|
||||||
|
from openslides.motion.views import (MotionDelete, ViewPoll,
|
||||||
|
MotionPDF, MotionPollPDF, CreateAgendaItem, SupportView)
|
||||||
|
|
||||||
|
urlpatterns = patterns('openslides.motion.views',
|
||||||
|
url(r'^$',
|
||||||
|
'overview',
|
||||||
|
name='motion_overview',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/$',
|
||||||
|
'view',
|
||||||
|
name='motion_view',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/agenda/$',
|
||||||
|
CreateAgendaItem.as_view(),
|
||||||
|
name='motion_create_agenda',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/newest/$',
|
||||||
|
'view',
|
||||||
|
{'newest': True},
|
||||||
|
name='motion_view_newest',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^new/$',
|
||||||
|
'edit',
|
||||||
|
name='motion_new',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^import/$',
|
||||||
|
'motion_import',
|
||||||
|
name='motion_import',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/edit/$',
|
||||||
|
'edit',
|
||||||
|
name='motion_edit',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/del/$',
|
||||||
|
MotionDelete.as_view(),
|
||||||
|
name='motion_delete',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^del/$',
|
||||||
|
MotionDelete.as_view(),
|
||||||
|
{ 'motion_id' : None , 'motion_ids' : None },
|
||||||
|
name='motion_delete',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/setnumber/$',
|
||||||
|
'set_number',
|
||||||
|
name='motion_set_number',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/setstatus/(?P<status>[a-z]{3})/$',
|
||||||
|
'set_status',
|
||||||
|
name='motion_set_status',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/permit/$',
|
||||||
|
'permit',
|
||||||
|
name='motion_permit',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^version/(?P<aversion_id>\d+)/permit/$',
|
||||||
|
'permit_version',
|
||||||
|
name='motion_version_permit',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^version/(?P<aversion_id>\d+)/reject/$',
|
||||||
|
'reject_version',
|
||||||
|
name='motion_version_reject',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/notpermit/$',
|
||||||
|
'notpermit',
|
||||||
|
name='motion_notpermit',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/reset/$',
|
||||||
|
'reset',
|
||||||
|
name='motion_reset',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/support/$',
|
||||||
|
SupportView.as_view(support=True),
|
||||||
|
name='motion_support',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/unsupport/$',
|
||||||
|
SupportView.as_view(support=False),
|
||||||
|
name='motion_unsupport',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/gen_poll/$',
|
||||||
|
'gen_poll',
|
||||||
|
name='motion_gen_poll',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^print/$',
|
||||||
|
MotionPDF.as_view(),
|
||||||
|
{'motion_id': None},
|
||||||
|
name='print_motions',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^(?P<motion_id>\d+)/print/$',
|
||||||
|
MotionPDF.as_view(),
|
||||||
|
name='print_motion',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^poll/(?P<poll_id>\d+)/print/$',
|
||||||
|
MotionPollPDF.as_view(),
|
||||||
|
name='print_motion_poll',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^poll/(?P<poll_id>\d+)/$',
|
||||||
|
ViewPoll.as_view(),
|
||||||
|
name='motion_poll_view',
|
||||||
|
),
|
||||||
|
|
||||||
|
url(r'^poll/(?P<poll_id>\d+)/del/$',
|
||||||
|
'delete_poll',
|
||||||
|
name='motion_poll_delete',
|
||||||
|
),
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
@ -119,7 +119,7 @@ INSTALLED_APPS = (
|
|||||||
'openslides.poll',
|
'openslides.poll',
|
||||||
'openslides.projector',
|
'openslides.projector',
|
||||||
'openslides.agenda',
|
'openslides.agenda',
|
||||||
'openslides.application',
|
'openslides.motion',
|
||||||
'openslides.assignment',
|
'openslides.assignment',
|
||||||
'openslides.participant',
|
'openslides.participant',
|
||||||
'openslides.config',
|
'openslides.config',
|
||||||
@ -134,3 +134,10 @@ TEMPLATE_CONTEXT_PROCESSORS = (
|
|||||||
'openslides.utils.utils.revision',
|
'openslides.utils.utils.revision',
|
||||||
'openslides.utils.auth.anonymous_context_additions',
|
'openslides.utils.auth.anonymous_context_additions',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CACHES = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||||
|
'LOCATION': 'openslidecache'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -47,7 +47,7 @@ def gen_username(first_name, last_name):
|
|||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
i += 1
|
i += 1
|
||||||
testname = "%s%s%s" % (first_name, last_name, i)
|
testname = "%s %s %s" % (first_name, last_name, i)
|
||||||
try:
|
try:
|
||||||
User.objects.get(username=testname)
|
User.objects.get(username=testname)
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
|
@ -27,7 +27,7 @@ class UserCreateForm(forms.ModelForm, CssClassMixin):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ('first_name', 'last_name', 'is_active', 'groups', 'category',
|
fields = ('first_name', 'last_name', 'is_active', 'groups', 'detail',
|
||||||
'gender', 'type', 'committee', 'comment', 'default_password')
|
'gender', 'type', 'committee', 'comment', 'default_password')
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class UserUpdateForm(UserCreateForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ('username', 'first_name', 'last_name', 'is_active', 'groups',
|
fields = ('username', 'first_name', 'last_name', 'is_active', 'groups',
|
||||||
'category', 'gender', 'type', 'committee', 'comment',
|
'detail', 'gender', 'type', 'committee', 'comment',
|
||||||
'default_password')
|
'default_password')
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ from django.db.models import signals
|
|||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.translation import ugettext_lazy as _, ugettext_noop
|
from django.utils.translation import ugettext_lazy as _, ugettext_noop
|
||||||
|
|
||||||
from openslides.utils.person import PersonMixin
|
from openslides.utils.person import PersonMixin, Person
|
||||||
from openslides.utils.person.signals import receive_persons
|
from openslides.utils.person.signals import receive_persons
|
||||||
|
|
||||||
from openslides.config.models import config
|
from openslides.config.models import config
|
||||||
from openslides.config.signals import default_config_value
|
from openslides.config.signals import default_config_value
|
||||||
|
|
||||||
|
|
||||||
class User(DjangoUser, PersonMixin):
|
class User(DjangoUser, PersonMixin, Person):
|
||||||
person_prefix = 'user'
|
person_prefix = 'user'
|
||||||
GENDER_CHOICES = (
|
GENDER_CHOICES = (
|
||||||
('male', _('Male')),
|
('male', _('Male')),
|
||||||
@ -37,8 +37,8 @@ class User(DjangoUser, PersonMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True)
|
django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True)
|
||||||
category = models.CharField(
|
detail = models.CharField(
|
||||||
max_length=100, null=True, blank=True, verbose_name=_("Category"),
|
max_length=100, blank=True, default='', verbose_name=_("Detail"),
|
||||||
help_text=_('Will be shown behind the name.'))
|
help_text=_('Will be shown behind the name.'))
|
||||||
gender = models.CharField(
|
gender = models.CharField(
|
||||||
max_length=50, choices=GENDER_CHOICES, blank=True,
|
max_length=50, choices=GENDER_CHOICES, blank=True,
|
||||||
@ -47,20 +47,24 @@ class User(DjangoUser, PersonMixin):
|
|||||||
max_length=100, choices=TYPE_CHOICES, blank=True,
|
max_length=100, choices=TYPE_CHOICES, blank=True,
|
||||||
verbose_name=_("Typ"), help_text=_('Only for filter the userlist.'))
|
verbose_name=_("Typ"), help_text=_('Only for filter the userlist.'))
|
||||||
committee = models.CharField(
|
committee = models.CharField(
|
||||||
max_length=100, null=True, blank=True, verbose_name=_("Committee"),
|
max_length=100, blank=True, default='', verbose_name=_("Committee"),
|
||||||
help_text=_('Only for filter the userlist.'))
|
help_text=_('Only for filter the userlist.'))
|
||||||
comment = models.TextField(
|
comment = models.TextField(
|
||||||
null=True, blank=True, verbose_name=_('Comment'),
|
blank=True, default='', verbose_name=_('Comment'),
|
||||||
help_text=_('Only for notes.'))
|
help_text=_('Only for notes.'))
|
||||||
default_password = models.CharField(
|
default_password = models.CharField(
|
||||||
max_length=100, null=True, blank=True,
|
max_length=100, blank=True, default='',
|
||||||
verbose_name=_("Default password"))
|
verbose_name=_("Default password"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def clean_name(self):
|
||||||
|
return self.get_full_name() or self.username
|
||||||
|
|
||||||
def get_name_suffix(self):
|
def get_name_suffix(self):
|
||||||
return self.category
|
return self.detail
|
||||||
|
|
||||||
def set_name_suffix(self, value):
|
def set_name_suffix(self, value):
|
||||||
self.category = value
|
self.detail = value
|
||||||
|
|
||||||
name_suffix = property(get_name_suffix, set_name_suffix)
|
name_suffix = property(get_name_suffix, set_name_suffix)
|
||||||
|
|
||||||
@ -88,10 +92,9 @@ class User(DjangoUser, PersonMixin):
|
|||||||
return ('user_delete', [str(self.id)])
|
return ('user_delete', [str(self.id)])
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
name = self.get_full_name() or self.username
|
|
||||||
if self.name_suffix:
|
if self.name_suffix:
|
||||||
return u"%s (%s)" % (name, self.name_suffix)
|
return u"%s (%s)" % (self.clean_name, self.name_suffix)
|
||||||
return u"%s" % name
|
return u"%s" % self.clean_name
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
# Rename permissions
|
# Rename permissions
|
||||||
@ -103,7 +106,7 @@ class User(DjangoUser, PersonMixin):
|
|||||||
ordering = ('last_name',)
|
ordering = ('last_name',)
|
||||||
|
|
||||||
|
|
||||||
class Group(DjangoGroup, PersonMixin):
|
class Group(DjangoGroup, PersonMixin, Person):
|
||||||
person_prefix = 'group'
|
person_prefix = 'group'
|
||||||
|
|
||||||
django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True)
|
django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True)
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
<button class="button" type="submit">
|
<button class="button" type="submit">
|
||||||
<span class="icon ok">{% trans 'Save' %}</span>
|
<span class="icon ok">{% trans 'Save' %}</span>
|
||||||
</button>
|
</button>
|
||||||
<a href='{% url config_application %}'>
|
<a href='{% url config_participant %}'>
|
||||||
<button class="button" type="button" onclick="window.location='{% url config_application %}'">
|
<button class="button" type="button" onclick="window.location='{% url config_participant %}'">
|
||||||
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
<span class="icon cancel">{% trans 'Cancel' %}</span>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
@ -26,11 +26,11 @@
|
|||||||
<option value="female"{% if 'female' in sortfilter.gender %} selected{% endif %}>{% trans "Female" %}</option>
|
<option value="female"{% if 'female' in sortfilter.gender %} selected{% endif %}>{% trans "Female" %}</option>
|
||||||
<option value=""{% if '' in sortfilter.gender %} selected{% endif %}>{% trans "Not specified" %}</option>
|
<option value=""{% if '' in sortfilter.gender %} selected{% endif %}>{% trans "Not specified" %}</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="default-input" name="category" onchange="document.forms['filter'].submit()">
|
<select class="default-input" name="detail" onchange="document.forms['filter'].submit()">
|
||||||
<option value="---">-- {% trans "Category" %} --</option>
|
<option value="---">-- {% trans "Detail" %} --</option>
|
||||||
{% for category in categories %}
|
{% for detail in details %}
|
||||||
<option value="{{ category }}"{% if category in sortfilter.category %} selected{% endif %}>
|
<option value="{{ detail }}"{% if detail in sortfilter.detail %} selected{% endif %}>
|
||||||
{{ category }}</option>
|
{{ detail }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<select class="default-input" name="type" onchange="document.forms['filter'].submit()">
|
<select class="default-input" name="type" onchange="document.forms['filter'].submit()">
|
||||||
@ -65,7 +65,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th><a href="?sort=first_name&reverse={% if 'first_name' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "First Name" %}</a></th>
|
<th><a href="?sort=first_name&reverse={% if 'first_name' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "First Name" %}</a></th>
|
||||||
<th><a href="?sort=last_name&reverse={% if 'last_name' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Last Name" %}</a></th>
|
<th><a href="?sort=last_name&reverse={% if 'last_name' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Last Name" %}</a></th>
|
||||||
<th><a href="?sort=category&reverse={% if 'category' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Category" %}</a></th>
|
<th><a href="?sort=detail&reverse={% if 'detail' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Detail" %}</a></th>
|
||||||
<th><a href="?sort=type&reverse={% if 'type' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Type" %}</a></th>
|
<th><a href="?sort=type&reverse={% if 'type' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Type" %}</a></th>
|
||||||
<th><a href="?sort=committee&reverse={% if 'committee' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Committee" %}</a></th>
|
<th><a href="?sort=committee&reverse={% if 'committee' in sortfilter.sort and 'reverse' not in sortfilter %}1{% else %}---{%endif%}">{% trans "Committee" %}</a></th>
|
||||||
{% if perms.participant.can_manage_participant %}
|
{% if perms.participant.can_manage_participant %}
|
||||||
@ -78,7 +78,7 @@
|
|||||||
<tr class="{% cycle '' 'odd' %}">
|
<tr class="{% cycle '' 'odd' %}">
|
||||||
<td>{{ user.first_name }}</td>
|
<td>{{ user.first_name }}</td>
|
||||||
<td>{{ user.last_name }}</td>
|
<td>{{ user.last_name }}</td>
|
||||||
<td>{{ user.category }}</td>
|
<td>{{ user.detail }}</td>
|
||||||
<td>{{ user.get_type_display }}</td>
|
<td>{{ user.get_type_display }}</td>
|
||||||
<td>{{ user.committee }}</td>
|
<td>{{ user.committee }}</td>
|
||||||
{% if perms.participant.can_manage_participant %}
|
{% if perms.participant.can_manage_participant %}
|
||||||
|
@ -35,12 +35,12 @@ class UserTest(TestCase):
|
|||||||
self.assertEqual(self.django_user1, self.user1.django_user)
|
self.assertEqual(self.django_user1, self.user1.django_user)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
self.assertEqual(unicode(self.user1), u'Max Mustermann')
|
self.assertEqual(unicode(self.user1), 'Max Mustermann')
|
||||||
|
|
||||||
def test_name_surfix(self):
|
def test_name_suffix(self):
|
||||||
self.user1.category = u'München'
|
self.user1.detail = 'München'
|
||||||
self.user1.save()
|
self.user1.save()
|
||||||
self.assertEqual(unicode(self.user1), u'Max Mustermann (München)')
|
self.assertEqual(unicode(self.user1), 'Max Mustermann (München)')
|
||||||
|
|
||||||
def test_reset_password(self):
|
def test_reset_password(self):
|
||||||
self.assertIsInstance(self.user1.default_password, basestring)
|
self.assertIsInstance(self.user1.default_password, basestring)
|
||||||
|
@ -66,8 +66,8 @@ class Overview(ListView):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
sortfilter = {}
|
sortfilter = {}
|
||||||
|
|
||||||
for value in [u'gender', u'category', u'type', u'committee', u'status',
|
for value in ['gender', 'detail', 'type', 'committee', 'status',
|
||||||
u'sort', u'reverse']:
|
'sort', 'reverse']:
|
||||||
if value in self.request.REQUEST:
|
if value in self.request.REQUEST:
|
||||||
if self.request.REQUEST[value] == '---':
|
if self.request.REQUEST[value] == '---':
|
||||||
try:
|
try:
|
||||||
@ -80,8 +80,8 @@ class Overview(ListView):
|
|||||||
query = User.objects
|
query = User.objects
|
||||||
if 'gender' in sortfilter:
|
if 'gender' in sortfilter:
|
||||||
query = query.filter(gender__iexact=sortfilter['gender'][0])
|
query = query.filter(gender__iexact=sortfilter['gender'][0])
|
||||||
if 'category' in sortfilter:
|
if 'detail' in sortfilter:
|
||||||
query = query.filter(category__iexact=sortfilter['category'][0])
|
query = query.filter(detail__iexact=sortfilter['detail'][0])
|
||||||
if 'type' in sortfilter:
|
if 'type' in sortfilter:
|
||||||
query = query.filter(type__iexact=sortfilter['type'][0])
|
query = query.filter(type__iexact=sortfilter['type'][0])
|
||||||
if 'committee' in sortfilter:
|
if 'committee' in sortfilter:
|
||||||
@ -92,7 +92,7 @@ class Overview(ListView):
|
|||||||
if sortfilter['sort'][0] in ['first_name', 'last_name', 'last_login']:
|
if sortfilter['sort'][0] in ['first_name', 'last_name', 'last_login']:
|
||||||
query = query.order_by(sortfilter['sort'][0])
|
query = query.order_by(sortfilter['sort'][0])
|
||||||
elif (sortfilter['sort'][0] in
|
elif (sortfilter['sort'][0] in
|
||||||
['category', 'type', 'committee', 'comment']):
|
['detail', 'type', 'committee', 'comment']):
|
||||||
query = query.order_by(
|
query = query.order_by(
|
||||||
'%s' % sortfilter['sort'][0])
|
'%s' % sortfilter['sort'][0])
|
||||||
else:
|
else:
|
||||||
@ -118,8 +118,8 @@ class Overview(ListView):
|
|||||||
percent = 0
|
percent = 0
|
||||||
|
|
||||||
# list of all existing categories
|
# list of all existing categories
|
||||||
categories = [p['category'] for p in User.objects.values('category')
|
details = [p['detail'] for p in User.objects.values('detail')
|
||||||
.exclude(category='').distinct()]
|
.exclude(detail='').distinct()]
|
||||||
|
|
||||||
# list of all existing committees
|
# list of all existing committees
|
||||||
committees = [p['committee'] for p in User.objects.values('committee')
|
committees = [p['committee'] for p in User.objects.values('committee')
|
||||||
@ -127,7 +127,7 @@ class Overview(ListView):
|
|||||||
context.update({
|
context.update({
|
||||||
'allusers': all_users,
|
'allusers': all_users,
|
||||||
'percent': round(percent, 1),
|
'percent': round(percent, 1),
|
||||||
'categories': categories,
|
'details': details,
|
||||||
'committees': committees,
|
'committees': committees,
|
||||||
'cookie': ['participant_sortfilter', urlencode(decodedict(self.sortfilter),
|
'cookie': ['participant_sortfilter', urlencode(decodedict(self.sortfilter),
|
||||||
doseq=True)],
|
doseq=True)],
|
||||||
@ -223,7 +223,7 @@ class ParticipantsListPDF(PDFView):
|
|||||||
counter,
|
counter,
|
||||||
Paragraph(user.last_name, stylesheet['Tablecell']),
|
Paragraph(user.last_name, stylesheet['Tablecell']),
|
||||||
Paragraph(user.first_name, stylesheet['Tablecell']),
|
Paragraph(user.first_name, stylesheet['Tablecell']),
|
||||||
Paragraph(user.category, stylesheet['Tablecell']),
|
Paragraph(user.detail, stylesheet['Tablecell']),
|
||||||
Paragraph(user.type, stylesheet['Tablecell']),
|
Paragraph(user.type, stylesheet['Tablecell']),
|
||||||
Paragraph(user.committee, stylesheet['Tablecell'])])
|
Paragraph(user.committee, stylesheet['Tablecell'])])
|
||||||
t = LongTable(data, style=[
|
t = LongTable(data, style=[
|
||||||
@ -320,7 +320,7 @@ class UserImportView(FormView):
|
|||||||
return super(UserImportView, self).form_valid(form)
|
return super(UserImportView, self).form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class ResetPasswordView(RedirectView, SingleObjectMixin, QuestionMixin):
|
class ResetPasswordView(SingleObjectMixin, QuestionMixin, RedirectView):
|
||||||
"""
|
"""
|
||||||
Set the Passwort for a user to his default password.
|
Set the Passwort for a user to his default password.
|
||||||
"""
|
"""
|
||||||
@ -336,17 +336,11 @@ class ResetPasswordView(RedirectView, SingleObjectMixin, QuestionMixin):
|
|||||||
def get_redirect_url(self, **kwargs):
|
def get_redirect_url(self, **kwargs):
|
||||||
return reverse('user_edit', args=[self.object.id])
|
return reverse('user_edit', args=[self.object.id])
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
def case_yes(self):
|
||||||
self.confirm_form()
|
self.object.reset_password()
|
||||||
|
|
||||||
def pre_post_redirect(self, request, *args, **kwargs):
|
def get_success_message(self):
|
||||||
if self.get_answer().lower() == 'yes':
|
return _('The Password for %s was successfully reset.') % html_strong(self.object)
|
||||||
self.object.reset_password()
|
|
||||||
messages.success(request,
|
|
||||||
_('The Password for %s was successfully reset.') % html_strong(self.object))
|
|
||||||
|
|
||||||
def get_answer_url(self):
|
|
||||||
return reverse('user_reset_password', args=[self.object.id])
|
|
||||||
|
|
||||||
|
|
||||||
class GroupOverviewView(ListView):
|
class GroupOverviewView(ListView):
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
from django.utils.importlib import import_module
|
from django.utils.importlib import import_module
|
||||||
@ -85,6 +86,13 @@ def set_active_slide(sid, argument=None):
|
|||||||
"""
|
"""
|
||||||
config["presentation"] = sid
|
config["presentation"] = sid
|
||||||
config['presentation_argument'] = argument
|
config['presentation_argument'] = argument
|
||||||
|
clear_projector_cache()
|
||||||
|
|
||||||
|
|
||||||
|
def clear_projector_cache():
|
||||||
|
cache.delete('projector_content')
|
||||||
|
cache.delete('projector_scrollcontent')
|
||||||
|
cache.delete('projector_data')
|
||||||
|
|
||||||
|
|
||||||
def register_slidemodel(model, model_name=None, control_template=None,
|
def register_slidemodel(model, model_name=None, control_template=None,
|
||||||
|
@ -58,6 +58,12 @@ class SlideMixin(object):
|
|||||||
"""
|
"""
|
||||||
set_active_slide(self.sid)
|
set_active_slide(self.sid)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if self.active:
|
||||||
|
from api import clear_projector_cache
|
||||||
|
clear_projector_cache()
|
||||||
|
return super(SlideMixin, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Slide(object):
|
class Slide(object):
|
||||||
"""
|
"""
|
||||||
|
@ -15,6 +15,7 @@ from time import time
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.core.cache import cache
|
||||||
from django.core.context_processors import csrf
|
from django.core.context_processors import csrf
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
@ -73,6 +74,7 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
except AttributeError: #TODO: It has to be an Slide.DoesNotExist
|
except AttributeError: #TODO: It has to be an Slide.DoesNotExist
|
||||||
data = None
|
data = None
|
||||||
ajax = 'on'
|
ajax = 'on'
|
||||||
|
active_sid = get_active_slide(True)
|
||||||
else:
|
else:
|
||||||
data = get_slide_from_sid(sid)
|
data = get_slide_from_sid(sid)
|
||||||
ajax = 'off'
|
ajax = 'off'
|
||||||
@ -88,7 +90,7 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
# Projector Overlays
|
# Projector Overlays
|
||||||
if self.kwargs['sid'] is None:
|
if self.kwargs['sid'] is None:
|
||||||
active_defs = ProjectorOverlay.objects.filter(active=True) \
|
active_defs = ProjectorOverlay.objects.filter(active=True) \
|
||||||
.filter(Q(sid=sid) | Q(sid=None)).values_list('def_name',
|
.filter(Q(sid=active_sid) | Q(sid=None)).values_list('def_name',
|
||||||
flat=True)
|
flat=True)
|
||||||
for receiver, response in projector_overlays.send(sender=sid,
|
for receiver, response in projector_overlays.send(sender=sid,
|
||||||
register=False, call=active_defs):
|
register=False, call=active_defs):
|
||||||
@ -106,10 +108,26 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def get_ajax_context(self, **kwargs):
|
def get_ajax_context(self, **kwargs):
|
||||||
content = render_block_to_string(self.get_template_names()[0],
|
content = cache.get('projector_content')
|
||||||
'content', self.data)
|
if not content:
|
||||||
scrollcontent = render_block_to_string(self.get_template_names()[0],
|
content = render_block_to_string(
|
||||||
'scrollcontent', self.data)
|
self.get_template_names()[0],
|
||||||
|
'content', self.data)
|
||||||
|
cache.set('projector_content', content)
|
||||||
|
|
||||||
|
scrollcontent = cache.get('projector_scrollcontent')
|
||||||
|
if not scrollcontent:
|
||||||
|
scrollcontent = render_block_to_string(
|
||||||
|
self.get_template_names()[0],
|
||||||
|
'scrollcontent', self.data)
|
||||||
|
cache.set('projector_scrollcontent', scrollcontent)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: do not call the hole data-methode, if we only need some vars
|
||||||
|
data = cache.get('projector_data')
|
||||||
|
if not data:
|
||||||
|
data = self.data
|
||||||
|
cache.set('projector_data', data)
|
||||||
|
|
||||||
context = super(Projector, self).get_ajax_context(**kwargs)
|
context = super(Projector, self).get_ajax_context(**kwargs)
|
||||||
content_hash = hash(content)
|
content_hash = hash(content)
|
||||||
@ -117,8 +135,8 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
'content': content,
|
'content': content,
|
||||||
'scrollcontent': scrollcontent,
|
'scrollcontent': scrollcontent,
|
||||||
'time': datetime.now().strftime('%H:%M'),
|
'time': datetime.now().strftime('%H:%M'),
|
||||||
'overlays': self.data['overlays'],
|
'overlays': data['overlays'],
|
||||||
'title': self.data['title'],
|
'title': data['title'],
|
||||||
'bigger': config['bigger'],
|
'bigger': config['bigger'],
|
||||||
'up': config['up'],
|
'up': config['up'],
|
||||||
'content_hash': content_hash,
|
'content_hash': content_hash,
|
||||||
|
@ -26,7 +26,7 @@ urlpatterns = patterns('',
|
|||||||
(r'^$', FrontPage.as_view()),
|
(r'^$', FrontPage.as_view()),
|
||||||
|
|
||||||
(r'^agenda/', include('openslides.agenda.urls')),
|
(r'^agenda/', include('openslides.agenda.urls')),
|
||||||
(r'^application/', include('openslides.application.urls')),
|
(r'^motion/', include('openslides.motion.urls')),
|
||||||
(r'^assignment/', include('openslides.assignment.urls')),
|
(r'^assignment/', include('openslides.assignment.urls')),
|
||||||
(r'^participant/', include('openslides.participant.urls')),
|
(r'^participant/', include('openslides.participant.urls')),
|
||||||
(r'^config/', include('openslides.config.urls')),
|
(r'^config/', include('openslides.config.urls')),
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from openslides.utils.person.signals import receive_persons
|
from openslides.utils.person.signals import receive_persons
|
||||||
from openslides.utils.person.api import generate_person_id, get_person, Persons
|
from openslides.utils.person.api import (generate_person_id, get_person,
|
||||||
|
Person, Persons)
|
||||||
from openslides.utils.person.forms import PersonFormField, MultiplePersonFormField
|
from openslides.utils.person.forms import PersonFormField, MultiplePersonFormField
|
||||||
from openslides.utils.person.models import PersonField, PersonMixin
|
from openslides.utils.person.models import PersonField, PersonMixin
|
||||||
|
|
||||||
|
@ -13,6 +13,37 @@
|
|||||||
from openslides.utils.person.signals import receive_persons
|
from openslides.utils.person.signals import receive_persons
|
||||||
|
|
||||||
|
|
||||||
|
class Person(object):
|
||||||
|
"""
|
||||||
|
Meta-class for all person objects
|
||||||
|
"""
|
||||||
|
def person_id(self):
|
||||||
|
"""
|
||||||
|
Return an id for representation of ths person. Has to be unique.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError('Any person object needs a person_id')
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
Return a string for this person.
|
||||||
|
"""
|
||||||
|
return str(self.person_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def clean_name(self):
|
||||||
|
"""
|
||||||
|
Return the name of this person without a suffix
|
||||||
|
"""
|
||||||
|
return unicode(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name_suffix(self):
|
||||||
|
"""
|
||||||
|
Return a suffix for the person-name.
|
||||||
|
"""
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class Persons(object):
|
class Persons(object):
|
||||||
"""
|
"""
|
||||||
A Storage for a multiplicity of different Person-Objects.
|
A Storage for a multiplicity of different Person-Objects.
|
||||||
|
@ -18,7 +18,7 @@ register = template.Library()
|
|||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def get_min_supporters():
|
def get_min_supporters():
|
||||||
return config['application_min_supporters']
|
return config['motion_min_supporters']
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
|
@ -101,13 +101,13 @@ def permission_required(perm, login_url=None):
|
|||||||
if request.user.has_perm(perm):
|
if request.user.has_perm(perm):
|
||||||
return func(request, *args, **kw)
|
return func(request, *args, **kw)
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
return render_to_forbitten(request)
|
return render_to_forbidden(request)
|
||||||
return redirect(reverse('user_login'))
|
return redirect(reverse('user_login'))
|
||||||
return wrapper
|
return wrapper
|
||||||
return renderer
|
return renderer
|
||||||
|
|
||||||
|
|
||||||
def render_to_forbitten(request, error=
|
def render_to_forbidden(request, error=
|
||||||
ugettext_lazy("Sorry, you have no rights to see this page.")):
|
ugettext_lazy("Sorry, you have no rights to see this page.")):
|
||||||
return HttpResponseForbidden(render_to_string('403.html',
|
return HttpResponseForbidden(render_to_string('403.html',
|
||||||
{'error': error}, context_instance=RequestContext(request)))
|
{'error': error}, context_instance=RequestContext(request)))
|
||||||
|
@ -52,7 +52,7 @@ from django.views.generic.list import TemplateResponseMixin
|
|||||||
|
|
||||||
from openslides.config.models import config
|
from openslides.config.models import config
|
||||||
|
|
||||||
from openslides.utils.utils import render_to_forbitten, html_strong
|
from openslides.utils.utils import render_to_forbidden, html_strong
|
||||||
from openslides.utils.signals import template_manipulation
|
from openslides.utils.signals import template_manipulation
|
||||||
from openslides.utils.pdf import firstPage, laterPages
|
from openslides.utils.pdf import firstPage, laterPages
|
||||||
|
|
||||||
@ -80,20 +80,20 @@ class LoginMixin(object):
|
|||||||
class PermissionMixin(object):
|
class PermissionMixin(object):
|
||||||
permission_required = NO_PERMISSION_REQUIRED
|
permission_required = NO_PERMISSION_REQUIRED
|
||||||
|
|
||||||
def has_permission(self, request):
|
def has_permission(self, request, *args, **kwargs):
|
||||||
if self.permission_required == NO_PERMISSION_REQUIRED:
|
if self.permission_required == NO_PERMISSION_REQUIRED:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return request.user.has_perm(self.permission_required)
|
return request.user.has_perm(self.permission_required)
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not self.has_permission(request):
|
if not self.has_permission(request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated():
|
||||||
path = request.get_full_path()
|
path = request.get_full_path()
|
||||||
return HttpResponseRedirect("%s?next=%s" % (settings.LOGIN_URL,
|
return HttpResponseRedirect("%s?next=%s" % (settings.LOGIN_URL,
|
||||||
path))
|
path))
|
||||||
else:
|
else:
|
||||||
return render_to_forbitten(request)
|
return render_to_forbidden(request)
|
||||||
return _View.dispatch(self, request, *args, **kwargs)
|
return _View.dispatch(self, request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -110,20 +110,21 @@ class QuestionMixin(object):
|
|||||||
success_message = ugettext_lazy('Thank you for your answer')
|
success_message = ugettext_lazy('Thank you for your answer')
|
||||||
answer_options = [('yes', ugettext_lazy("Yes")), ('no', ugettext_lazy("No"))]
|
answer_options = [('yes', ugettext_lazy("Yes")), ('no', ugettext_lazy("No"))]
|
||||||
|
|
||||||
def get_answer_options(self):
|
def pre_redirect(self, request, *args, **kwargs):
|
||||||
return self.answer_options
|
# Prints the question in a GET request
|
||||||
|
self.confirm_form()
|
||||||
|
|
||||||
def get_question(self):
|
def get_question(self):
|
||||||
return unicode(self.question)
|
return unicode(self.question)
|
||||||
|
|
||||||
def get_answer(self):
|
def get_answer_options(self):
|
||||||
for option in self.get_answer_options():
|
return self.answer_options
|
||||||
if option[0] in self.request.POST:
|
|
||||||
return option[0]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_answer_url(self):
|
def get_answer_url(self):
|
||||||
return self.answer_url
|
try:
|
||||||
|
return self.answer_url
|
||||||
|
except AttributeError:
|
||||||
|
return self.request.path
|
||||||
|
|
||||||
def confirm_form(self):
|
def confirm_form(self):
|
||||||
option_fields = "\n".join([
|
option_fields = "\n".join([
|
||||||
@ -142,11 +143,25 @@ class QuestionMixin(object):
|
|||||||
'csrf': csrf(self.request)['csrf_token'],
|
'csrf': csrf(self.request)['csrf_token'],
|
||||||
'option_fields': option_fields})
|
'option_fields': option_fields})
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
|
||||||
self.confirm_form(request, self.object)
|
|
||||||
|
|
||||||
def pre_post_redirect(self, request, *args, **kwargs):
|
def pre_post_redirect(self, request, *args, **kwargs):
|
||||||
messages.success(request)
|
# Reacts on the response of the user in a POST-request.
|
||||||
|
# TODO: call the methodes for all possible answers.
|
||||||
|
if self.get_answer() == 'yes':
|
||||||
|
self.case_yes()
|
||||||
|
messages.success(request, self.get_success_message())
|
||||||
|
|
||||||
|
def get_answer(self):
|
||||||
|
for option in self.get_answer_options():
|
||||||
|
if option[0] in self.request.POST:
|
||||||
|
return option[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def case_yes(self):
|
||||||
|
# TODO: raise a warning
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_success_message(self):
|
||||||
|
return self.success_message
|
||||||
|
|
||||||
|
|
||||||
class TemplateView(PermissionMixin, _TemplateView):
|
class TemplateView(PermissionMixin, _TemplateView):
|
||||||
@ -266,27 +281,19 @@ class CreateView(PermissionMixin, _CreateView):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DeleteView(RedirectView, SingleObjectMixin, QuestionMixin):
|
class DeleteView(SingleObjectMixin, QuestionMixin, RedirectView):
|
||||||
def get_question(self):
|
|
||||||
return _('Do you really want to delete %s?') % html_strong(self.object)
|
|
||||||
|
|
||||||
def get_success_message(self):
|
|
||||||
return _('%s was successfully deleted.') % html_strong(self.object)
|
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
|
||||||
self.confirm_form()
|
|
||||||
|
|
||||||
def pre_post_redirect(self, request, *args, **kwargs):
|
|
||||||
if self.get_answer().lower() == 'yes':
|
|
||||||
self.object.delete()
|
|
||||||
messages.success(request, self.get_success_message())
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
return super(DeleteView, self).get(request, *args, **kwargs)
|
return super(DeleteView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_answer_url(self):
|
def get_question(self):
|
||||||
return self.object.get_absolute_url('delete')
|
return _('Do you really want to delete %s?') % html_strong(self.object)
|
||||||
|
|
||||||
|
def case_yes(self):
|
||||||
|
self.object.delete()
|
||||||
|
|
||||||
|
def get_success_message(self):
|
||||||
|
return _('%s was successfully deleted.') % html_strong(self.object)
|
||||||
|
|
||||||
|
|
||||||
class DetailView(TemplateView, SingleObjectMixin):
|
class DetailView(TemplateView, SingleObjectMixin):
|
||||||
|
Loading…
Reference in New Issue
Block a user