docbow/docbow_project/docbow/profile_views.py

279 lines
11 KiB
Python

from django.shortcuts import redirect
from django.views.generic.edit import UpdateView, FormView
from django.views.generic.base import TemplateResponseMixin, View
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.http import HttpResponseRedirect
import django_journal
from . import models
from . import forms
from . import cbv
from . import utils
class ProfileView(cbv.FormWithPrefixMixin, cbv.FormWithRequestMixin, cbv.FormWithPostTarget, UpdateView):
form_class = forms.ProfileForm
template_name = 'docbow/profile.html'
prefix = 'profile'
success_url = '#profile'
def get_object(self):
try:
return models.DocbowProfile.objects.get(user=self.request.user)
except models.DocbowProfile.DoesNotExist:
return None
def is_post_target(self):
return 'profile-clear_mobile_phone' in self.request.POST or \
'profile-validate' in self.request.POST
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if 'profile-clear_mobile_phone' in self.request.POST:
if self.object:
self.object.mobile_phone = ''
self.object.save()
return redirect('profile')
return super(ProfileView, self).post(request, *args, **kwargs)
def form_valid(self, form):
self.request.record('update-profile', 'modified its profile',
**form.cleaned_data)
return super(ProfileView, self).form_valid(form)
class DelegateView(cbv.FormWithPrefixMixin, cbv.FormWithPostTarget, FormView):
form_class = forms.DelegationForm
template_name = 'docbow/delegate.html'
success_url = '#delegate'
prefix = 'delegate'
def __init__(self, *args, **kwargs):
super(DelegateView, self).__init__(*args, **kwargs)
def add_journal_to_delegations(self, delegations):
delegations__to = [ delegation.to for delegation in delegations ]
journals = django_journal.Journal.objects \
.for_objects(delegations__to) \
.filter(tag__name='login') \
.order_by('-time')[:len(delegations__to)*5]
journal_by_users = dict()
for journal in journals:
for objectdata in journal.objectdata_set.all():
if objectdata.tag.name == 'delegate':
journal_by_users.setdefault(objectdata.object_id, []) \
.append(journal.time)
for delegation in delegations:
delegation.journals = journal_by_users.get(delegation.to.id, [])[:5]
@property
def delegations(self):
qs = models.Delegation.objects.all()
qs = qs.filter(by=self.request.user)
qs = qs.select_related()
qs = qs.prefetch_related('to__docbowprofile')
self.add_journal_to_delegations(qs)
return qs
def get_form_kwargs(self, **kwargs):
kwargs = super(DelegateView, self).get_form_kwargs(**kwargs)
kwargs['user'] = self.request.user
kwargs['delegatees'] = [ delegation.to for delegation in self.delegations ]
return kwargs
def delete(self, delegation):
request = self.request
delegation.delete()
delegate_user = delegation.to
request.record('delete-delegation', 'deleted delegation '
'{delegation} to user {delegated}',
delegation=delegation.id,
delegated=delegate_user)
user = request.user
# notify delegate
ctx = {
'user': utils.clean_ldap_user(user),
'delegate': delegate_user,
'to': [delegate_user.email],
'reply_to': user.email,
}
models.Notification.objects.create(kind='delete-delegation', ctx=ctx)
messages.info(request, _('Delegation %s supressed') %
delegate_user)
messages.info(request, _('%s has been notified.') %
delegate_user.email)
request.record('notify', 'notified {email} of '
'the deletion of its delegate user',
email=delegate_user.email)
# delete guest accounts
if delegation.guest_delegate:
delegate_user.delete()
request.record('delete-delegate', 'deleted delegate '
'user {username}, {first_name} {last_name}, '
'({email})',
username=delegate_user.username,
first_name=delegate_user.first_name,
last_name=delegate_user.last_name,
email=delegate_user.email)
return HttpResponseRedirect(self.success_url)
def is_post_target(self):
if 'delegate-create' in self.request.POST:
return True
for delegation in self.delegations:
username = delegation.to.username
if 'delegate-delete-{username}.x'.format(username=username) in \
self.request.POST:
return True
return False
def post(self, request, *args, **kwargs):
if 'delegate-create' in request.POST:
return super(DelegateView, self).post(request, *args, **kwargs)
for delegation in self.delegations:
username = delegation.to.username
if 'delegate-delete-{username}.x'.format(username=username) in \
self.request.POST:
return self.delete(delegation)
return self.get(request, *args, **kwargs)
def form_valid(self, form):
request = self.request
is_guest = not form.cleaned_data.get('existing_user')
ctx = {
'user': utils.clean_ldap_user(request.user),
'reply_to' :request.user.email,
'is_guest': is_guest,
}
if is_guest:
delegate_username = utils.get_free_delegation_number(request.user)
delegate_user = User(username=delegate_username,
first_name=form.cleaned_data.get('first_name', ''),
last_name=form.cleaned_data.get('last_name', ''),
email=form.cleaned_data.get('email', ''))
delegate_user.set_unusable_password()
delegate_user.save()
models.DocbowProfile.objects.create(user=delegate_user, is_guest=True)
delegation, created = models.Delegation.objects.get_or_create(by=request.user,
to=delegate_user)
request.record('create-delegate', 'created delegate with '
'parameters {first_name} {last_name} <{email}>',
**form.cleaned_data)
ctx.update({
'password_reset_link':
utils.make_password_reset_url(request, delegate_user),
'to': [form.cleaned_data['email']],
'delegate': delegate_user,
'delegation': delegation,
})
messages.info(request,
_('New delegation to user %s created.') % delegate_user.username)
messages.info(request,
_('A notification was sent to %s about this new delegation') % delegate_user.email)
else:
delegate_user = form.cleaned_data.get('existing_user')
delegate_username = delegate_user.username
delegation, created = models.Delegation.objects.get_or_create(by=request.user,
to=delegate_user)
ctx.update({
'to': models.all_emails(delegate_user),
'delegate': delegate_user,
'delegation': delegation,
})
messages.info(request,
_('New delegation to user %s created.') %
delegate_user.username)
messages.info(request,
_('A notification was sent to %s about this new delegation') % delegate_user.get_full_name())
models.Notification.objects.create(kind='new-delegation', ctx=ctx)
request.record('create-delegation', 'created delegation to '
'user {delegated}', delegated=delegate_user)
return super(DelegateView, self).form_valid(form)
def get_context_data(self, **kwargs):
ctx = super(DelegateView, self).get_context_data(**kwargs)
ctx['delegations'] = self.delegations
ctx['received_delegations'] = self.request.user.delegations_by.all()
return ctx
class PasswordChangeView(cbv.FormWithPrefixMixin, cbv.FormWithPostTarget, FormView):
template_name = 'registration/password_change_form.html'
form_class = forms.PasswordChangeFormWithLogging
prefix = 'password-change'
success_url = '#password-change'
def is_post_target(self):
return 'password-change-validate' in self.request.POST
def form_valid(self, form):
messages.info(self.request, _('Password changed'))
return super(PasswordChangeView, self).form_valid(form)
def get_form_kwargs(self, **kwargs):
kwargs = super(PasswordChangeView, self).get_form_kwargs(**kwargs)
kwargs['user'] = self.request.user
return kwargs
class FullProfileView(TemplateResponseMixin, View):
# multiplex all profile views
template_name = 'docbow/full-profile.html'
subviews = (
('profile_form', ProfileView),
('delegate_form', DelegateView),
('password_change_form', PasswordChangeView),
)
def dispatch(self, request, *args, **kwargs):
if models.is_guest(request.user):
self.subviews = filter(lambda s: s[0] != 'delegate_form', self.subviews)
print self.subviews
return super(FullProfileView, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
ctx = {}
for var_name, view_class in self.subviews:
res = self.get_view(var_name, view_class)
if isinstance(res, dict):
ctx.update(res)
else:
return res
return self.render_to_response(ctx)
def get_view(self, var_name, view_class):
view = view_class()
view.request, view.args, view.kwargs = \
self.request, self.args, self.kwargs
if hasattr(view, 'get_object'):
view.object = view.get_object()
if self.request.method == 'POST' and view.is_post_target():
res = view.post(self.request, *self.args, **self.kwargs)
if isinstance(res, HttpResponseRedirect):
return res
else:
ctx = res.context_data
ctx[var_name] = ctx.pop('form')
return ctx
else:
form_class = view.get_form_class()
form = view.get_form(form_class)
return view.get_context_data(**{var_name: form})
def get(self, request, *args, **kwargs):
ctx = {}
for var_name, view_class in self.subviews:
ctx.update(self.get_view(var_name, view_class))
return self.render_to_response(ctx)