user-api: updated the application-supporter system to new user-api

This commit is contained in:
Oskar Hahn 2012-08-04 12:19:31 +02:00
parent 2bc2dad7a5
commit 14bf6d0a35
8 changed files with 152 additions and 103 deletions

View File

@ -15,7 +15,7 @@ from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _, ugettext_noop
from openslides.utils.forms import CssClassMixin
from openslides.utils.user import UserFormField
from openslides.utils.user import UserFormField, MultipleUserFormField
from openslides.application.models import Application
@ -59,11 +59,8 @@ class ApplicationManagerForm(forms.ModelForm, CssClassMixin):
class ApplicationManagerFormSupporter(ApplicationManagerForm):
supporter = UserModelMultipleChoiceField(
queryset=User.objects.all().exclude(profile=None).
order_by("first_name"),
required=False, label=_("Supporters"),
)
# TODO: Do not show the submitter in the user-list
supporter = MultipleUserFormField(required=False, label=_("Supporters"))
class ApplicationImportForm(forms.Form, CssClassMixin):

View File

@ -37,6 +37,11 @@ from openslides.projector.models import SlideMixin
from openslides.agenda.models import Item
class ApplicationSupporter(models.Model):
application = models.ForeignKey("Application")
user = UserField()
class Application(models.Model, SlideMixin):
prefix = "application"
STATUS = (
@ -62,8 +67,6 @@ class Application(models.Model, SlideMixin):
)
submitter = UserField(verbose_name=_("Submitter"))
supporter = models.ManyToManyField(User, related_name='supporter', \
null=True, blank=True, verbose_name=_("Supporters"))
number = models.PositiveSmallIntegerField(blank=True, null=True,
unique=True)
status = models.CharField(max_length=3, choices=STATUS, default='pub')
@ -158,6 +161,13 @@ class Application(models.Model, SlideMixin):
else:
return False
@property
def supporters(self):
return [object.user for object in self.applicationsupporter_set.all()]
def is_supporter(self, user):
return self.applicationsupporter_set.filter(user=user).exists()
@property
def enough_supporters(self):
"""
@ -165,17 +175,20 @@ class Application(models.Model, SlideMixin):
"""
min_supporters = int(config['application_min_supporters'])
if self.status == "pub":
return self.supporter.count() >= min_supporters
return self.count_supporters() >= min_supporters
else:
return True
def count_supporters(self):
return self.applicationsupporter_set.count()
@property
def missing_supporters(self):
"""
Return number of missing supporters
"""
min_supporters = int(config['application_min_supporters'])
delta = min_supporters - self.supporter.count()
delta = min_supporters - self.count_supporters()
if delta > 0:
return delta
else:
@ -222,10 +235,11 @@ class Application(models.Model, SlideMixin):
except AttributeError:
is_manager = False
supporters = self.applicationsupporter_set.all()
if (self.status == "pub"
and self.supporter.exists()
and supporters
and not is_manager):
self.supporter.clear()
supporters.delete()
self.writelog(_("Supporters removed"), user)
def reset(self, user):
@ -242,29 +256,36 @@ class Application(models.Model, SlideMixin):
Add a Supporter to the list of supporters of the application.
"""
if user == self.submitter:
# TODO: Use own Exception
raise NameError('Supporter can not be the submitter of a ' \
'application.')
if self.permitted is not None:
# TODO: Use own Exception
raise NameError('This application is already permitted.')
if user not in self.supporter.all():
self.supporter.add(user)
self.writelog(_("Supporter: +%s") % (user))
if not self.is_supporter(user):
ApplicationSupporter(application=self, user=user).save()
self.writelog(_("Supporter: +%s") % (user))
def unsupport(self, user):
"""
remove a supporter from the list of supporters of the application
"""
if self.permitted is not None:
# TODO: Use own Exception
raise NameError('This application is already permitted.')
if user in self.supporter.all():
self.supporter.remove(user)
self.writelog(_("Supporter: -%s") % (user))
try:
object = self.applicationsupporter_set.get(user=user).delete()
except ApplicationSupporter.DoesNotExist:
pass
else:
self.writelog(_("Supporter: -%s") % (user))
def set_number(self, number=None, user=None):
"""
Set a number for ths application.
"""
if self.number is not None:
# TODO: Use own Exception
raise NameError('This application has already a number.')
if number is None:
try:
@ -333,7 +354,7 @@ class Application(models.Model, SlideMixin):
self.writelog(_("Status modified")+": %s -> %s" \
% (oldstatus, self.get_status_display()), user)
def get_allowed_actions(self, user=None):
def get_allowed_actions(self, user):
"""
Return a list of all the allowed status.
"""
@ -367,16 +388,12 @@ class Application(models.Model, SlideMixin):
actions.append("pub")
# Check if the user can support and unspoort the application
try:
if (self.status == "pub"
and user != self.submitter
and user not in self.supporter.all()
and getattr(user, 'profile', None)):
actions.append("support")
except Profile.DoesNotExist:
pass
if (self.status == "pub"
and user != self.submitter
and not self.is_supporter(user)):
actions.append("support")
if self.status == "pub" and user in self.supporter.all():
if self.status == "pub" and self.is_supporter(user):
actions.append("unsupport")
#Check if the user can edit the application

View File

@ -22,16 +22,16 @@
{% endif %}
{% if min_supporters > 0 %}
<h4>{% trans "Supporters" %}: *</h4>
{% if application.supporter.count == 0 %}
-
{% else %}
<ol>
{% for supporter in application.supporter.all %}
<li> {{ supporter.profile }}</li>
{% endfor %}
</ol>
{% endif %}
<h4>{% trans "Supporters" %}: *</h4>
{% if not application.supporters %}
-
{% else %}
<ol>
{% for supporter in application.supporters %}
<li> {{ supporter }}</li>
{% endfor %}
</ol>
{% endif %}
{% endif %}
<h4>{% trans "Status" %}:</h4>

View File

@ -42,6 +42,7 @@ from openslides.utils.template import Tab
from openslides.utils.utils import (template, permission_required,
del_confirm_form, gen_confirm_form)
from openslides.utils.views import PDFView, RedirectView, DeleteView, FormView
from openslides.utils.user import get_user
from openslides.config.models import config
@ -49,7 +50,7 @@ from openslides.projector.projector import Widget
from openslides.poll.views import PollFormView
from openslides.participant.api import gen_username, gen_password
from openslides.participant.api import gen_username, gen_password, user2djangouser
from openslides.participant.models import Profile
from openslides.agenda.models import Item
@ -123,7 +124,7 @@ def overview(request):
for (i, application) in enumerate(applications):
try:
applications[i] = {
'actions' : application.get_allowed_actions(request.user),
'actions' : application.get_allowed_actions(user2djangouser(request.user)),
'application' : application
}
except:
@ -151,7 +152,8 @@ def view(request, application_id, newest=False):
else:
version = application.public_version
revisions = application.versions
actions = application.get_allowed_actions(user=request.user)
user = user2djangouser(request.user)
actions = application.get_allowed_actions(user=user)
return {
'application': application,
@ -181,11 +183,11 @@ def edit(request, application_id=None):
if application_id is not None:
application = Application.objects.get(id=application_id)
if (not hasattr(application.submitter, 'user') or
not request.user == application.submitter.user) \
not user2djangouser(request.user) == application.submitter.user) \
and not is_manager:
messages.error(request, _("You can not edit this application. You are not the submitter."))
return redirect(reverse('application_view', args=[application.id]))
actions = application.get_allowed_actions(user=request.user)
actions = application.get_allowed_actions(user=user2djangouser(request.user))
else:
application = None
actions = None
@ -212,14 +214,14 @@ def edit(request, application_id=None):
if valid:
del_supporters = True
original_supporters = []
if is_manager:
if application: # Edit application
for s in application.supporter.all():
original_supporters.append(s)
original_supporters = list(application.supporters)
else:
original_supporters = []
application = managerform.save(commit=False)
elif application_id is None:
application = Application(submitter=request.user.profile)
application = Application(submitter=user2djangouser(request.user))
application.title = dataform.cleaned_data['title']
application.text = dataform.cleaned_data['text']
application.reason = dataform.cleaned_data['reason']
@ -229,30 +231,17 @@ def edit(request, application_id=None):
and dataform.cleaned_data['trivial_change']
except KeyError:
trivial_change = False
application.save(request.user, trivial_change=trivial_change)
application.save(user2djangouser(request.user), trivial_change=trivial_change)
if is_manager:
# log added supporters
supporters_added = []
for s in application.supporter.all():
if s not in original_supporters:
try:
supporters_added.append(unicode(s.profile))
except Profile.DoesNotExist:
pass
if len(supporters_added) > 0:
log_added = ", ".join(supporters_added)
application.writelog(_("Supporter: +%s") % log_added, request.user)
# log removed supporters
supporters_removed = []
for s in original_supporters:
if s not in application.supporter.all():
try:
supporters_removed.append(unicode(s.profile))
except Profile.DoesNotExist:
pass
if len(supporters_removed) > 0:
log_removed = ", ".join(supporters_removed)
application.writelog(_("Supporter: -%s") % log_removed, request.user)
# TODO: Deal with the case, that the form has no field 'supporters'
old_supporters = set(application.supporters)
new_supporters = set(managerform.cleaned_data['supporter'])
# add new supporters
for supporter in new_supporters.difference(old_supporters):
application.support(supporter)
# remove old supporters
for supporter in old_supporters.difference(new_supporters):
application.unsupport(supporter)
if application_id is None:
messages.success(request, _('New application was successfully created.'))
else:
@ -268,11 +257,11 @@ def edit(request, application_id=None):
if application_id is None:
initial = {'text': config['application_preamble']}
else:
if application.status == "pub" and application.supporter.exists():
if application.status == "pub" and application.supporters:
if request.user.has_perm('application.can_manage_application'):
messages.warning(request, _("Attention: Do you really want to edit this application? The supporters will <b>not</b> be removed automatically because you can manage applications. Please check if the supports are valid after your changing!"))
else:
messages.warning(request, _("Attention: Do you really want to edit this application? All <b>%s</b> supporters will be removed! Try to convince the supporters again.") % application.supporter.count() )
messages.warning(request, _("Attention: Do you really want to edit this application? All <b>%s</b> supporters will be removed! Try to convince the supporters again.") % len(application.supporters) )
initial = {'title': application.title,
'text': application.text,
'reason': application.reason}
@ -280,12 +269,10 @@ def edit(request, application_id=None):
dataform = formclass(initial=initial, prefix="data")
if is_manager:
if application_id is None:
try:
initial = {'submitter': request.user.profile.uid}
except Profile.DoesNotExist:
initial = {}
initial = {'submitter': user2djangouser(request.user).uid}
else:
initial = {'submitter': application.submitter.uid}
initial['supporter'] = [supporter.uid for supporter in application.supporters]
managerform = managerformclass(initial=initial,
instance=application, prefix="manager")
else:
@ -305,7 +292,7 @@ def set_number(request, application_id):
set a number for an application.
"""
try:
Application.objects.get(pk=application_id).set_number(user=request.user)
Application.objects.get(pk=application_id).set_number(user=user2djangouser(request.user))
messages.success(request, _("Application number was successfully set."))
except Application.DoesNotExist:
pass
@ -321,7 +308,7 @@ def permit(request, application_id):
permit an application.
"""
try:
Application.objects.get(pk=application_id).permit(user=request.user)
Application.objects.get(pk=application_id).permit(user=user2djangouser(request.user))
messages.success(request, _("Application was successfully permitted."))
except Application.DoesNotExist:
pass
@ -336,7 +323,7 @@ def notpermit(request, application_id):
reject (not permit) an application.
"""
try:
Application.objects.get(pk=application_id).notpermit(user=request.user)
Application.objects.get(pk=application_id).notpermit(user=user2djangouser(request.user))
messages.success(request, _("Application was successfully rejected."))
except Application.DoesNotExist:
pass
@ -352,7 +339,7 @@ def set_status(request, application_id=None, status=None):
try:
if status is not None:
application = Application.objects.get(pk=application_id)
application.set_status(user=request.user, status=status)
application.set_status(user=user2djangouser(request.user), status=status)
messages.success(request, _("Application status was set to: <b>%s</b>.") % application.get_status_display())
except Application.DoesNotExist:
pass
@ -368,7 +355,7 @@ def reset(request, application_id):
reset an application.
"""
try:
Application.objects.get(pk=application_id).reset(user=request.user)
Application.objects.get(pk=application_id).reset(user=user2djangouser(request.user))
messages.success(request, _("Application status was reset.") )
except Application.DoesNotExist:
pass
@ -382,7 +369,7 @@ def support(request, application_id):
support an application.
"""
try:
Application.objects.get(pk=application_id).support(user=request.user)
Application.objects.get(pk=application_id).support(user=user2djangouser(request.user))
messages.success(request, _("You have support the application successfully.") )
except Application.DoesNotExist:
pass
@ -396,7 +383,7 @@ def unsupport(request, application_id):
unsupport an application.
"""
try:
Application.objects.get(pk=application_id).unsupport(user=request.user)
Application.objects.get(pk=application_id).unsupport(user=user2djangouser(request.user))
messages.success(request, _("You have unsupport the application successfully.") )
except Application.DoesNotExist:
pass
@ -410,7 +397,7 @@ def gen_poll(request, application_id):
gen a poll for this application.
"""
try:
poll = Application.objects.get(pk=application_id).gen_poll(user=request.user)
poll = Application.objects.get(pk=application_id).gen_poll(user=user2djangouser(request.user))
messages.success(request, _("New vote was successfully created.") )
except Application.DoesNotExist:
pass # TODO: do not call poll after this excaption
@ -427,7 +414,7 @@ def delete_poll(request, poll_id):
count = application.polls.filter(id__lte=poll_id).count()
if request.method == 'POST':
poll.delete()
application.writelog(_("Poll deleted"), request.user)
application.writelog(_("Poll deleted"), user2djangouser(request.user))
messages.success(request, _('Poll was successfully deleted.'))
else:
del_confirm_form(request, poll, name=_("the %s. poll") % count, delete_link=reverse('application_poll_delete', args=[poll_id]))
@ -467,7 +454,7 @@ class ApplicationDelete(DeleteView):
if len(self.applications):
for application in self.applications:
if not 'delete' in application.get_allowed_actions(user=request.user):
if not 'delete' in application.get_allowed_actions(user=user2djangouser(request.user)):
messages.error(request, _("You can not delete application <b>%s</b>.") % application)
continue
@ -476,12 +463,12 @@ class ApplicationDelete(DeleteView):
messages.success(request, _("Application <b>%s</b> was successfully deleted.") % title)
elif self.object:
if not 'delete' in self.object.get_allowed_actions(user=request.user):
messages.error(request, _("You can not delete application <b>%s</b>.") % self.object)
else:
title = self.object.title
self.object.delete(force=True)
messages.success(request, _("Application <b>%s</b> was successfully deleted.") % title)
if not 'delete' in self.object.get_allowed_actions(user=user2djangouser(request.user)):
messages.error(request, _("You can not delete application <b>%s</b>.") % self.object)
else:
title = self.object.title
self.object.delete(force=True)
messages.success(request, _("Application <b>%s</b> was successfully deleted.") % title)
else:
messages.error(request, _("Invalid request"))
@ -517,12 +504,12 @@ class ViewPoll(PollFormView):
self.application = self.poll.get_application()
context['application'] = self.application
context['ballot'] = self.poll.get_ballot()
context['actions'] = self.application.get_allowed_actions(user=self.request.user)
context['actions'] = self.application.get_allowed_actions(user=user2djangouser(self.request.user))
return context
def get_modelform_class(self):
cls = super(ViewPoll, self).get_modelform_class()
user = self.request.user
user = user2djangouser(self.request.user)
class ViewPollFormClass(cls):
def save(self, commit = True):
@ -544,7 +531,7 @@ def permit_version(request, aversion_id):
aversion = AVersion.objects.get(pk=aversion_id)
application = aversion.application
if request.method == 'POST':
application.accept_version(aversion, user = request.user)
application.accept_version(aversion, user=user2djangouser(request.user))
messages.success(request, _("Version <b>%s</b> accepted.") % (aversion.aid))
else:
gen_confirm_form(request, _('Do you really want to permit version <b>%s</b>?') % aversion.aid, reverse('application_version_permit', args=[aversion.id]))
@ -556,7 +543,7 @@ def reject_version(request, aversion_id):
aversion = AVersion.objects.get(pk=aversion_id)
application = aversion.application
if request.method == 'POST':
if application.reject_version(aversion, user = request.user):
if application.reject_version(aversion, user=user2djangouser(request.user)):
messages.success(request, _("Version <b>%s</b> rejected.") % (aversion.aid))
else:
messages.error(request, _("ERROR by rejecting the version.") )
@ -570,13 +557,14 @@ def reject_version(request, aversion_id):
def application_import(request):
try:
request.user.profile
messages.error(request, _('The import function is available for the admin (without user profile) only.'))
return redirect(reverse('application_overview'))
except Profile.DoesNotExist:
pass
except AttributeError:
# AnonymousUser
pass
else:
messages.error(request, _('The import function is available for the admin (without user profile) only.'))
return redirect(reverse('application_overview'))
if request.method == 'POST':
form = ApplicationImportForm(request.POST, request.FILES)
@ -771,7 +759,7 @@ class ApplicationPDF(PDFView):
cell2a.append(Paragraph("<font name='Ubuntu-Bold'>%s:</font><seqreset id='counter'>" % _("Supporters"), stylesheet['Heading4']))
for s in application.supporter.all():
for supporter in application.supporters:
cell2b.append(Paragraph("<seq id='counter'/>.&nbsp; %s" % unicode(s.profile), stylesheet['Signaturefield']))
if application.status == "pub":
for x in range(0,application.missing_supporters):

View File

@ -15,6 +15,9 @@ import string
from django.contrib.auth.models import User
from openslides.utils.user import get_user
from openslides.participant.models import Profile
def gen_password():
"""
@ -44,3 +47,11 @@ def gen_username(first_name, last_name):
User.objects.get(username=testname)
except User.DoesNotExist:
return testname
def user2djangouser(user):
u = get_user('djangouser:%d' % user.id)
try:
return u.profile
except Profile.DoesNotExist:
return u

View File

@ -90,6 +90,7 @@ class UsersettingsForm(forms.ModelForm, CssClassMixin):
model = User
fields = ('username', 'first_name', 'last_name', 'email')
class UserImportForm(forms.Form, CssClassMixin):
csvfile = forms.FileField(widget=forms.FileInput(attrs={'size':'50'}),
label=_("CSV File"))

View File

@ -21,8 +21,6 @@ from openslides.utils.user.signals import receiv_users
from openslides.config.signals import default_config_value
from openslides.participant.api import gen_password
class Profile(models.Model, UserMixin):
user_prefix = 'participant'
@ -53,7 +51,6 @@ class Profile(models.Model, UserMixin):
firstpassword = models.CharField(max_length=100, null=True, blank=True,
verbose_name = _("First Password"))
def reset_password(self):
"""
Reset the password for the user to his default-password.
@ -61,7 +58,6 @@ class Profile(models.Model, UserMixin):
self.user.set_password(self.firstpassword)
self.user.save()
@models.permalink
def get_absolute_url(self, link='edit'):
"""
@ -98,6 +94,17 @@ class DjangoGroup(models.Model, UserMixin):
return unicode(self.group)
class DjangoUser(User, UserMixin):
user_prefix = 'djangouser'
def has_no_profile(self):
# TODO: Make ths with a Manager, so it does manipulate the sql query
return not hasattr(self, 'profile')
class Meta:
proxy = True
class ParticipantUsers(object):
def __init__(self, user_prefix=None, id=None):
self.user_prefix = user_prefix
@ -118,6 +125,17 @@ class ParticipantUsers(object):
for group in DjangoGroup.objects.all():
yield group
if not self.user_prefix or self.user_prefix == DjangoUser.user_prefix:
if self.id:
yield DjangoUser.objects.get(pk=self.id)
else:
for user in DjangoUser.objects.all():
if user.has_no_profile():
yield user
elif self.user_prefix:
# If only users where requested, return the profile object.
yield user.profile
def __getitem__(self, key):
return Profile.objects.get(pk=key)

View File

@ -57,6 +57,23 @@ class UserFormField(forms.fields.ChoiceField):
return super(UserFormField, self).valid_value(value.uid)
class MultipleUserFormField(UserFormField):
widget = forms.widgets.SelectMultiple
def __init__(self, *args, **kwargs):
super(MultipleUserFormField, self).__init__(empty_label=None, *args, **kwargs)
def to_python(self, value):
if hasattr(value, '__iter__'):
return [super(MultipleUserFormField, self).to_python(v) for v in value]
return super(MultipleUserFormField, self).to_python(value)
def valid_value(self, value):
if hasattr(value, '__iter__'):
return [super(MultipleUserFormField, self).valid_value(v) for v in value]
return super(MultipleUserFormField, self).valid_value(value)
class UserField(models.fields.Field):
__metaclass__ = models.SubfieldBase