2015-11-24 15:09:46 +00:00
|
|
|
# This file contains all the views that concern the user model
|
|
|
|
from django.shortcuts import render, redirect, get_object_or_404
|
2015-11-25 16:03:18 +00:00
|
|
|
from django.contrib.auth import logout as auth_logout, views
|
2016-08-22 00:56:27 +00:00
|
|
|
from django.utils.translation import ugettext as _
|
2015-11-25 15:20:28 +00:00
|
|
|
from django.core.urlresolvers import reverse
|
2016-08-22 00:56:27 +00:00
|
|
|
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
|
2016-08-13 15:15:45 +00:00
|
|
|
from django.http import Http404
|
2015-11-26 15:32:56 +00:00
|
|
|
from django.views.generic.edit import UpdateView
|
2015-12-08 16:22:50 +00:00
|
|
|
from django.views.generic import ListView, DetailView, TemplateView
|
2016-07-17 22:47:56 +00:00
|
|
|
from django.forms.models import modelform_factory
|
|
|
|
from django.forms import CheckboxSelectMultiple
|
2016-08-13 15:15:45 +00:00
|
|
|
from django.template.response import TemplateResponse
|
2016-08-05 07:52:19 +00:00
|
|
|
from django.conf import settings
|
2016-08-18 19:32:18 +00:00
|
|
|
|
2016-09-06 16:43:39 +00:00
|
|
|
from django.utils import timezone
|
|
|
|
from datetime import timedelta, datetime, date
|
2015-11-24 15:09:46 +00:00
|
|
|
import logging
|
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin
|
2016-08-31 00:43:49 +00:00
|
|
|
from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm, LoginForm
|
2016-08-22 00:56:27 +00:00
|
|
|
from core.models import User, SithFile
|
2015-11-24 15:09:46 +00:00
|
|
|
|
2015-11-25 16:03:18 +00:00
|
|
|
def login(request):
|
|
|
|
"""
|
|
|
|
The login view
|
|
|
|
|
|
|
|
Needs to be improve with correct handling of form exceptions
|
|
|
|
"""
|
2016-08-31 00:43:49 +00:00
|
|
|
return views.login(request, template_name="core/login.jinja", authentication_form=LoginForm)
|
2015-11-25 16:03:18 +00:00
|
|
|
|
|
|
|
def logout(request):
|
|
|
|
"""
|
|
|
|
The logout view
|
|
|
|
"""
|
|
|
|
return views.logout_then_login(request)
|
|
|
|
|
|
|
|
def password_change(request):
|
|
|
|
"""
|
|
|
|
Allows a user to change its password
|
|
|
|
"""
|
2016-02-01 16:35:55 +00:00
|
|
|
return views.password_change(request, template_name="core/password_change.jinja", post_change_redirect=reverse("core:password_change_done"))
|
2015-11-25 16:03:18 +00:00
|
|
|
|
|
|
|
def password_change_done(request):
|
|
|
|
"""
|
|
|
|
Allows a user to change its password
|
|
|
|
"""
|
2016-02-01 16:35:55 +00:00
|
|
|
return views.password_change_done(request, template_name="core/password_change_done.jinja")
|
2015-11-25 16:03:18 +00:00
|
|
|
|
2016-08-13 15:15:45 +00:00
|
|
|
def password_root_change(request, user_id):
|
|
|
|
"""
|
|
|
|
Allows a root user to change someone's password
|
|
|
|
"""
|
2016-08-14 02:35:08 +00:00
|
|
|
if not request.user.is_root:
|
2016-08-13 15:15:45 +00:00
|
|
|
raise PermissionDenied
|
|
|
|
user = User.objects.filter(id=user_id).first()
|
|
|
|
if not user:
|
|
|
|
raise Http404("User not found")
|
|
|
|
if request.method == "POST":
|
|
|
|
form = views.SetPasswordForm(user=user, data=request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
form.save()
|
|
|
|
return redirect("core:password_change_done")
|
|
|
|
else:
|
|
|
|
form = views.SetPasswordForm(user=user)
|
|
|
|
return TemplateResponse(request, "core/password_change.jinja", {'form': form, 'target': user})
|
|
|
|
|
2015-11-26 09:57:26 +00:00
|
|
|
def password_reset(request):
|
2015-11-26 10:27:52 +00:00
|
|
|
"""
|
|
|
|
Allows someone to enter an email adresse for resetting password
|
|
|
|
"""
|
2015-11-26 09:57:26 +00:00
|
|
|
return views.password_reset(request,
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name="core/password_reset.jinja",
|
|
|
|
email_template_name="core/password_reset_email.jinja",
|
2015-11-26 10:27:52 +00:00
|
|
|
post_reset_redirect="core:password_reset_done",
|
2015-11-26 09:57:26 +00:00
|
|
|
)
|
2015-11-25 16:03:18 +00:00
|
|
|
|
|
|
|
def password_reset_done(request):
|
2015-11-26 10:27:52 +00:00
|
|
|
"""
|
|
|
|
Confirm that the reset email has been sent
|
|
|
|
"""
|
2016-02-01 16:35:55 +00:00
|
|
|
return views.password_reset_done(request, template_name="core/password_reset_done.jinja")
|
2015-11-25 16:03:18 +00:00
|
|
|
|
2015-11-26 09:57:26 +00:00
|
|
|
def password_reset_confirm(request, uidb64=None, token=None):
|
2015-11-26 10:27:52 +00:00
|
|
|
"""
|
|
|
|
Provide a reset password formular
|
|
|
|
"""
|
2015-11-26 09:57:26 +00:00
|
|
|
return views.password_reset_confirm(request, uidb64=uidb64, token=token,
|
|
|
|
post_reset_redirect="core:password_reset_complete",
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name="core/password_reset_confirm.jinja",
|
2015-11-26 09:57:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def password_reset_complete(request):
|
2015-11-26 10:27:52 +00:00
|
|
|
"""
|
|
|
|
Confirm the password has sucessfully been reset
|
|
|
|
"""
|
2015-11-26 09:57:26 +00:00
|
|
|
return views.password_reset_complete(request,
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name="core/password_reset_complete.jinja",
|
2015-11-26 09:57:26 +00:00
|
|
|
)
|
2015-11-25 16:03:18 +00:00
|
|
|
|
2015-11-24 15:09:46 +00:00
|
|
|
def register(request):
|
2016-07-19 17:03:16 +00:00
|
|
|
context = {}
|
2015-11-24 15:09:46 +00:00
|
|
|
if request.method == 'POST':
|
|
|
|
form = RegisteringForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
logging.debug("Registering "+form.cleaned_data['first_name']+form.cleaned_data['last_name'])
|
|
|
|
u = form.save()
|
|
|
|
context['user_registered'] = u
|
|
|
|
context['tests'] = 'TEST_REGISTER_USER_FORM_OK'
|
|
|
|
form = RegisteringForm()
|
|
|
|
else:
|
|
|
|
context['error'] = 'Erreur'
|
|
|
|
context['tests'] = 'TEST_REGISTER_USER_FORM_FAIL'
|
|
|
|
else:
|
|
|
|
form = RegisteringForm()
|
|
|
|
context['form'] = form.as_p()
|
2016-02-01 16:35:55 +00:00
|
|
|
return render(request, "core/register.jinja", context)
|
2015-11-24 15:09:46 +00:00
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserTabsMixin(TabedViewMixin):
|
|
|
|
def get_tabs_title(self):
|
|
|
|
return self.object.get_display_name()
|
|
|
|
|
|
|
|
def get_list_of_tabs(self):
|
|
|
|
tab_list = []
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_profile', kwargs={'user_id': self.object.id}),
|
|
|
|
'slug': 'infos',
|
|
|
|
'name': _("Infos"),
|
|
|
|
})
|
|
|
|
if self.request.user == self.object:
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_tools'),
|
|
|
|
'slug': 'tools',
|
|
|
|
'name': _("Tools"),
|
|
|
|
})
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_stats', kwargs={'user_id': self.object.id}),
|
|
|
|
'slug': 'stats',
|
|
|
|
'name': _("Stats"),
|
|
|
|
})
|
|
|
|
if self.request.user.can_edit(self.object):
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_edit', kwargs={'user_id': self.object.id}),
|
|
|
|
'slug': 'edit',
|
|
|
|
'name': _("Edit"),
|
|
|
|
})
|
|
|
|
if self.request.user.is_owner(self.object):
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_groups', kwargs={'user_id': self.object.id}),
|
|
|
|
'slug': 'groups',
|
|
|
|
'name': _("Groups"),
|
|
|
|
})
|
|
|
|
try:
|
|
|
|
if (self.object.customer and (self.object == self.request.user
|
|
|
|
or self.request.user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name'])
|
|
|
|
or self.request.user.is_root)):
|
|
|
|
tab_list.append({
|
|
|
|
'url': reverse('core:user_account', kwargs={'user_id': self.object.id}),
|
|
|
|
'slug': 'account',
|
|
|
|
'name': _("Account")+" (%s €)" % self.object.customer.amount,
|
|
|
|
})
|
|
|
|
except: pass
|
|
|
|
return tab_list
|
|
|
|
|
|
|
|
class UserView(UserTabsMixin, CanViewMixin, DetailView):
|
2015-11-24 15:09:46 +00:00
|
|
|
"""
|
|
|
|
Display a user's profile
|
|
|
|
"""
|
2015-11-26 15:32:56 +00:00
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
|
|
|
context_object_name = "profile"
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name = "core/user_detail.jinja"
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = 'infos'
|
2015-11-26 15:32:56 +00:00
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
|
2016-08-18 19:32:18 +00:00
|
|
|
"""
|
|
|
|
Display a user's stats
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
|
|
|
context_object_name = "profile"
|
|
|
|
template_name = "core/user_stats.jinja"
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = 'stats'
|
2016-08-18 19:32:18 +00:00
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
kwargs = super(UserStatsView, self).get_context_data(**kwargs)
|
2016-08-19 00:53:44 +00:00
|
|
|
from counter.models import Counter
|
|
|
|
foyer = Counter.objects.filter(name="Foyer").first()
|
|
|
|
mde = Counter.objects.filter(name="MDE").first()
|
|
|
|
gommette = Counter.objects.filter(name="La Gommette").first()
|
|
|
|
kwargs['total_perm_time'] = sum([p.end-p.start for p in self.object.permanencies.all()], timedelta())
|
|
|
|
kwargs['total_foyer_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=foyer)], timedelta())
|
|
|
|
kwargs['total_mde_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=mde)], timedelta())
|
|
|
|
kwargs['total_gommette_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=gommette)], timedelta())
|
2016-08-18 19:32:18 +00:00
|
|
|
return kwargs
|
|
|
|
|
2016-08-14 17:28:14 +00:00
|
|
|
class UserMiniView(CanViewMixin, DetailView):
|
|
|
|
"""
|
|
|
|
Display a user's profile
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
|
|
|
context_object_name = "profile"
|
|
|
|
template_name = "core/user_mini.jinja"
|
|
|
|
|
2015-11-26 15:32:56 +00:00
|
|
|
class UserListView(ListView):
|
|
|
|
"""
|
|
|
|
Displays the user list
|
|
|
|
"""
|
|
|
|
model = User
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name = "core/user_list.jinja"
|
2015-11-26 15:32:56 +00:00
|
|
|
|
2016-08-22 00:56:27 +00:00
|
|
|
class UserUploadProfilePictView(CanEditMixin, DetailView):
|
|
|
|
"""
|
|
|
|
Handle the upload of the profile picture taken with webcam in navigator
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
|
|
|
template_name = "core/user_edit.jinja"
|
|
|
|
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
|
|
from core.utils import resize_image
|
|
|
|
from io import BytesIO
|
|
|
|
from PIL import Image
|
|
|
|
self.object = self.get_object()
|
|
|
|
if self.object.profile_pict:
|
|
|
|
raise ValidationError(_("User already has a profile picture"))
|
|
|
|
print(request.FILES['new_profile_pict'])
|
|
|
|
f = request.FILES['new_profile_pict']
|
|
|
|
parent = SithFile.objects.filter(parent=None, name="profiles").first()
|
|
|
|
name = str(self.object.id) + "_profile.jpg" # Webcamejs uploads JPGs
|
|
|
|
im = Image.open(BytesIO(f.read()))
|
|
|
|
new_file = SithFile(parent=parent, name=name,
|
|
|
|
file=resize_image(im, 400, f.content_type.split('/')[-1]),
|
|
|
|
owner=self.object, is_folder=False, mime_type=f.content_type, size=f._size)
|
|
|
|
new_file.file.name = name
|
|
|
|
new_file.save()
|
|
|
|
self.object.profile_pict = new_file
|
|
|
|
self.object.save()
|
|
|
|
return redirect("core:user_edit", user_id=self.object.id)
|
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
|
2015-11-26 15:32:56 +00:00
|
|
|
"""
|
|
|
|
Edit a user's profile
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name = "core/user_edit.jinja"
|
2016-08-11 02:24:32 +00:00
|
|
|
form_class = UserProfileForm
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = "edit"
|
2016-08-11 02:24:32 +00:00
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
self.object = self.get_object()
|
|
|
|
self.form = self.get_form()
|
|
|
|
if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
|
|
|
|
self.form.fields.pop('profile_pict', None)
|
|
|
|
return self.render_to_response(self.get_context_data(form=self.form))
|
|
|
|
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
|
|
self.object = self.get_object()
|
|
|
|
self.form = self.get_form()
|
|
|
|
if self.form.instance.profile_pict and not request.user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
|
|
|
|
self.form.fields.pop('profile_pict', None)
|
|
|
|
files = request.FILES.items()
|
|
|
|
self.form.process(files)
|
|
|
|
if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid():
|
|
|
|
return super(UserUpdateProfileView, self).form_valid(self.form)
|
|
|
|
return self.form_invalid(self.form)
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
kwargs = super(UserUpdateProfileView, self).get_context_data(**kwargs)
|
|
|
|
kwargs['profile'] = self.form.instance
|
|
|
|
kwargs['form'] = self.form
|
|
|
|
return kwargs
|
2015-11-26 15:32:56 +00:00
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserUpdateGroupView(UserTabsMixin, CanEditPropMixin, UpdateView):
|
2015-11-26 15:32:56 +00:00
|
|
|
"""
|
|
|
|
Edit a user's groups
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
2016-07-17 22:47:56 +00:00
|
|
|
template_name = "core/user_group.jinja"
|
|
|
|
form_class = modelform_factory(User, fields=['groups'],
|
|
|
|
widgets={'groups':CheckboxSelectMultiple})
|
2016-02-01 16:35:55 +00:00
|
|
|
context_object_name = "profile"
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = "groups"
|
2015-11-26 15:32:56 +00:00
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserToolsView(UserTabsMixin, TemplateView):
|
2015-12-08 16:22:50 +00:00
|
|
|
"""
|
|
|
|
Displays the logged user's tools
|
|
|
|
"""
|
2016-02-01 16:35:55 +00:00
|
|
|
template_name = "core/user_tools.jinja"
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = "tools"
|
2016-08-05 07:52:19 +00:00
|
|
|
|
2016-08-13 14:39:09 +00:00
|
|
|
def get_context_data(self, **kwargs):
|
2016-09-04 17:24:53 +00:00
|
|
|
self.object = self.request.user
|
2016-08-13 14:39:09 +00:00
|
|
|
from launderette.models import Launderette
|
|
|
|
kwargs = super(UserToolsView, self).get_context_data(**kwargs)
|
|
|
|
kwargs['launderettes'] = Launderette.objects.all()
|
2016-08-31 02:04:28 +00:00
|
|
|
kwargs['profile'] = self.request.user
|
2016-09-04 17:24:53 +00:00
|
|
|
kwargs['object'] = self.request.user
|
2016-08-13 14:39:09 +00:00
|
|
|
return kwargs
|
|
|
|
|
2016-09-04 17:24:53 +00:00
|
|
|
class UserAccountView(UserTabsMixin, DetailView):
|
2016-08-05 07:52:19 +00:00
|
|
|
"""
|
|
|
|
Display a user's account
|
|
|
|
"""
|
|
|
|
model = User
|
|
|
|
pk_url_kwarg = "user_id"
|
|
|
|
template_name = "core/user_account.jinja"
|
2016-09-04 17:24:53 +00:00
|
|
|
current_tab = "account"
|
2016-08-05 07:52:19 +00:00
|
|
|
|
|
|
|
def dispatch(self, request, *arg, **kwargs): # Manually validates the rights
|
|
|
|
res = super(UserAccountView, self).dispatch(request, *arg, **kwargs)
|
|
|
|
if (self.object == request.user
|
|
|
|
or request.user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name'])
|
2016-08-14 02:35:08 +00:00
|
|
|
or request.user.is_root):
|
2016-08-05 07:52:19 +00:00
|
|
|
return res
|
|
|
|
raise PermissionDenied
|
|
|
|
|
2016-09-06 16:43:39 +00:00
|
|
|
def expense_by_month(self):
|
|
|
|
stats = []
|
|
|
|
joined = self.object.date_joined.year
|
|
|
|
|
|
|
|
years = datetime.now().year - joined
|
|
|
|
|
|
|
|
years = range(0, years + 1)
|
|
|
|
months = range(1, 12)
|
|
|
|
|
|
|
|
for y in years:
|
|
|
|
stats.append([])
|
|
|
|
for m in months:
|
|
|
|
q = self.object.customer.buyings.filter(
|
|
|
|
date__year=joined + y,
|
|
|
|
date__month=m,
|
|
|
|
)
|
|
|
|
stats[y].append(
|
|
|
|
(
|
|
|
|
sum([p.unit_price * p.quantity for p in q]),
|
|
|
|
date(joined + y, m, 17)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
print(stats)
|
|
|
|
return stats
|
|
|
|
|
2016-08-05 07:52:19 +00:00
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
kwargs = super(UserAccountView, self).get_context_data(**kwargs)
|
|
|
|
kwargs['profile'] = self.object
|
|
|
|
try:
|
|
|
|
kwargs['customer'] = self.object.customer
|
2016-09-06 16:43:39 +00:00
|
|
|
kwargs['selling_months'] = self.expense_by_month()
|
2016-08-05 07:52:19 +00:00
|
|
|
except:
|
|
|
|
pass
|
|
|
|
# TODO: add list of month where account has activity
|
|
|
|
return kwargs
|
|
|
|
|
|
|
|
|