mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-09 19:40:19 +00:00
Format core
This commit is contained in:
@ -23,29 +23,28 @@
|
||||
#
|
||||
|
||||
# This file contains all the views that concern the page model
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic import ListView, DetailView, TemplateView
|
||||
from django.views.generic.edit import UpdateView, CreateView, FormMixin, DeleteView
|
||||
from django.views.generic.edit import UpdateView, FormMixin, DeleteView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.forms.models import modelform_factory
|
||||
from django.forms import CheckboxSelectMultiple
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponse
|
||||
from django.core.servers.basehttp import FileWrapper
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django import forms
|
||||
|
||||
import os
|
||||
|
||||
from ajax_select import make_ajax_form, make_ajax_field
|
||||
from ajax_select import make_ajax_field
|
||||
|
||||
from core.models import SithFile, RealGroup, Notification
|
||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, can_view, not_found
|
||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, can_view, not_found
|
||||
from counter.models import Counter
|
||||
|
||||
|
||||
def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
||||
"""
|
||||
Send a file through Django without loading the whole file into
|
||||
@ -57,7 +56,7 @@ def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
||||
return not_found(request)
|
||||
if not (can_view(f, request.user) or
|
||||
('counter_token' in request.session.keys() and
|
||||
request.session['counter_token'] and # check if not null for counters that have no token set
|
||||
request.session['counter_token'] and # check if not null for counters that have no token set
|
||||
Counter.objects.filter(token=request.session['counter_token']).exists())
|
||||
):
|
||||
raise PermissionDenied
|
||||
@ -70,10 +69,11 @@ def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
||||
response['Content-Disposition'] = ('inline; filename="%s"' % f.name).encode('utf-8')
|
||||
return response
|
||||
|
||||
|
||||
class AddFilesForm(forms.Form):
|
||||
folder_name = forms.CharField(label=_("Add a new folder"), max_length=30, required=False)
|
||||
file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}), label=_("Files"),
|
||||
required=False)
|
||||
required=False)
|
||||
|
||||
def process(self, parent, owner, files):
|
||||
notif = False
|
||||
@ -85,10 +85,10 @@ class AddFilesForm(forms.Form):
|
||||
notif = True
|
||||
except Exception as e:
|
||||
self.add_error(None, _("Error creating folder %(folder_name)s: %(msg)s") %
|
||||
{'folder_name': self.cleaned_data['folder_name'], 'msg': repr(e)})
|
||||
{'folder_name': self.cleaned_data['folder_name'], 'msg': repr(e)})
|
||||
for f in files:
|
||||
new_file = SithFile(parent=parent, name=f.name, file=f, owner=owner, is_folder=False,
|
||||
mime_type=f.content_type, size=f._size)
|
||||
mime_type=f.content_type, size=f._size)
|
||||
try:
|
||||
new_file.clean()
|
||||
new_file.save()
|
||||
@ -100,6 +100,7 @@ class AddFilesForm(forms.Form):
|
||||
if not u.notifications.filter(type="FILE_MODERATION", viewed=False).exists():
|
||||
Notification(user=u, url=reverse("core:file_moderation"), type="FILE_MODERATION").save()
|
||||
|
||||
|
||||
class FileListView(ListView):
|
||||
template_name = 'core/file_list.jinja'
|
||||
context_object_name = "file_list"
|
||||
@ -114,6 +115,7 @@ class FileListView(ListView):
|
||||
kwargs['popup'] = 'popup'
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileEditView(CanEditMixin, UpdateView):
|
||||
model = SithFile
|
||||
pk_url_kwarg = "file_id"
|
||||
@ -138,6 +140,7 @@ class FileEditView(CanEditMixin, UpdateView):
|
||||
kwargs['popup'] = 'popup'
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileEditPropForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = SithFile
|
||||
@ -147,6 +150,7 @@ class FileEditPropForm(forms.ModelForm):
|
||||
view_groups = make_ajax_field(SithFile, 'view_groups', 'groups', help_text="", label=_("view group"))
|
||||
recursive = forms.BooleanField(label=_("Apply rights recursively"), required=False)
|
||||
|
||||
|
||||
class FileEditPropView(CanEditPropMixin, UpdateView):
|
||||
model = SithFile
|
||||
pk_url_kwarg = "file_id"
|
||||
@ -175,6 +179,7 @@ class FileEditPropView(CanEditPropMixin, UpdateView):
|
||||
kwargs['popup'] = 'popup'
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileView(CanViewMixin, DetailView, FormMixin):
|
||||
"""This class handle the upload of new files into a folder"""
|
||||
model = SithFile
|
||||
@ -217,7 +222,7 @@ class FileView(CanViewMixin, DetailView, FormMixin):
|
||||
request.session['clipboard'] = []
|
||||
if request.user.can_edit(self.object):
|
||||
FileView.handle_clipboard(request, self.object)
|
||||
self.form = self.get_form() # The form handle only the file upload
|
||||
self.form = self.get_form() # The form handle only the file upload
|
||||
files = request.FILES.getlist('file_field')
|
||||
if request.user.is_authenticated() and request.user.can_edit(self.object) and self.form.is_valid():
|
||||
self.form.process(parent=self.object, owner=request.user, files=files)
|
||||
@ -237,6 +242,7 @@ class FileView(CanViewMixin, DetailView, FormMixin):
|
||||
kwargs['clipboard'] = SithFile.objects.filter(id__in=self.request.session['clipboard'])
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileDeleteView(CanEditPropMixin, DeleteView):
|
||||
model = SithFile
|
||||
pk_url_kwarg = "file_id"
|
||||
@ -244,7 +250,7 @@ class FileDeleteView(CanEditPropMixin, DeleteView):
|
||||
context_object_name = "file"
|
||||
|
||||
def get_success_url(self):
|
||||
self.object.file.delete() # Doing it here or overloading delete() is the same, so let's do it here
|
||||
self.object.file.delete() # Doing it here or overloading delete() is the same, so let's do it here
|
||||
if 'next' in self.request.GET.keys():
|
||||
return self.request.GET['next']
|
||||
if self.object.parent is None:
|
||||
@ -258,6 +264,7 @@ class FileDeleteView(CanEditPropMixin, DeleteView):
|
||||
kwargs['popup'] = 'popup'
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileModerationView(TemplateView):
|
||||
template_name = "core/file_moderation.jinja"
|
||||
|
||||
@ -266,6 +273,7 @@ class FileModerationView(TemplateView):
|
||||
kwargs['files'] = SithFile.objects.filter(is_moderated=False)[:100]
|
||||
return kwargs
|
||||
|
||||
|
||||
class FileModerateView(CanEditPropMixin, SingleObjectMixin):
|
||||
model = SithFile
|
||||
pk_url_kwarg = "file_id"
|
||||
@ -278,4 +286,3 @@ class FileModerateView(CanEditPropMixin, SingleObjectMixin):
|
||||
if 'next' in self.request.GET.keys():
|
||||
return redirect(self.request.GET['next'])
|
||||
return redirect('core:file_moderation')
|
||||
|
||||
|
@ -22,22 +22,24 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, UserChangeForm
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.contrib.auth import logout, login, authenticate
|
||||
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput, DateTimeInput, Textarea
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext
|
||||
from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget
|
||||
from ajax_select.fields import AutoCompleteSelectField
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from core.models import User, Page, RealGroup, SithFile
|
||||
from core.models import User, Page, SithFile
|
||||
|
||||
from core.utils import resize_image
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
|
||||
|
||||
# Widgets
|
||||
@ -50,6 +52,7 @@ class SelectSingle(Select):
|
||||
attrs = {'class': "select_single"}
|
||||
return super(SelectSingle, self).render(name, value, attrs)
|
||||
|
||||
|
||||
class SelectMultiple(Select):
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs:
|
||||
@ -58,6 +61,7 @@ class SelectMultiple(Select):
|
||||
attrs = {'class': "select_multiple"}
|
||||
return super(SelectMultiple, self).render(name, value, attrs)
|
||||
|
||||
|
||||
class SelectDateTime(DateTimeInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs:
|
||||
@ -66,6 +70,7 @@ class SelectDateTime(DateTimeInput):
|
||||
attrs = {'class': "select_datetime"}
|
||||
return super(SelectDateTime, self).render(name, value, attrs)
|
||||
|
||||
|
||||
class SelectDate(DateInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs:
|
||||
@ -74,16 +79,18 @@ class SelectDate(DateInput):
|
||||
attrs = {'class': "select_date"}
|
||||
return super(SelectDate, self).render(name, value, attrs)
|
||||
|
||||
|
||||
class MarkdownInput(Textarea):
|
||||
def render(self, name, value, attrs=None):
|
||||
output = '<p><a href="%(syntax_url)s">%(help_text)s</a></p>'\
|
||||
'<div class="markdown_editor">%(content)s</div>' % {
|
||||
'syntax_url': Page.get_page_by_full_name(settings.SITH_CORE_PAGE_SYNTAX).get_absolute_url(),
|
||||
'help_text': _("Help on the syntax"),
|
||||
'content': super(MarkdownInput, self).render(name, value, attrs),
|
||||
}
|
||||
'syntax_url': Page.get_page_by_full_name(settings.SITH_CORE_PAGE_SYNTAX).get_absolute_url(),
|
||||
'help_text': _("Help on the syntax"),
|
||||
'content': super(MarkdownInput, self).render(name, value, attrs),
|
||||
}
|
||||
return output
|
||||
|
||||
|
||||
class SelectFile(TextInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs:
|
||||
@ -91,13 +98,14 @@ class SelectFile(TextInput):
|
||||
else:
|
||||
attrs = {'class': "select_file"}
|
||||
output = '%(content)s<div name="%(name)s" class="choose_file_widget" title="%(title)s"></div>' % {
|
||||
'content': super(SelectFile, self).render(name, value, attrs),
|
||||
'title': _("Choose file"),
|
||||
'name': name,
|
||||
}
|
||||
'content': super(SelectFile, self).render(name, value, attrs),
|
||||
'title': _("Choose file"),
|
||||
'name': name,
|
||||
}
|
||||
output += '<span name="' + name + '" class="choose_file_button">' + ugettext("Choose file") + '</span>'
|
||||
return output
|
||||
|
||||
|
||||
class SelectUser(TextInput):
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs:
|
||||
@ -105,15 +113,16 @@ class SelectUser(TextInput):
|
||||
else:
|
||||
attrs = {'class': "select_user"}
|
||||
output = '%(content)s<div name="%(name)s" class="choose_user_widget" title="%(title)s"></div>' % {
|
||||
'content': super(SelectUser, self).render(name, value, attrs),
|
||||
'title': _("Choose user"),
|
||||
'name': name,
|
||||
}
|
||||
'content': super(SelectUser, self).render(name, value, attrs),
|
||||
'title': _("Choose user"),
|
||||
'name': name,
|
||||
}
|
||||
output += '<span name="' + name + '" class="choose_user_button">' + ugettext("Choose user") + '</span>'
|
||||
return output
|
||||
|
||||
# Forms
|
||||
|
||||
|
||||
class LoginForm(AuthenticationForm):
|
||||
def __init__(self, *arg, **kwargs):
|
||||
if 'data' in kwargs.keys():
|
||||
@ -128,14 +137,17 @@ class LoginForm(AuthenticationForm):
|
||||
else:
|
||||
user = User.objects.filter(username=data['username']).first()
|
||||
data['username'] = user.username
|
||||
except: pass
|
||||
except:
|
||||
pass
|
||||
kwargs['data'] = data
|
||||
super(LoginForm, self).__init__(*arg, **kwargs)
|
||||
self.fields['username'].label = _("Username, email, or account number")
|
||||
|
||||
|
||||
class RegisteringForm(UserCreationForm):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name', 'email')
|
||||
@ -148,9 +160,6 @@ class RegisteringForm(UserCreationForm):
|
||||
user.save()
|
||||
return user
|
||||
|
||||
from core.utils import resize_image
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
"""
|
||||
@ -161,22 +170,22 @@ class UserProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['first_name', 'last_name', 'nick_name', 'email', 'date_of_birth', 'profile_pict', 'avatar_pict',
|
||||
'scrub_pict', 'sex', 'second_email', 'address', 'parent_address', 'phone', 'parent_phone',
|
||||
'tshirt_size', 'role', 'department', 'dpt_option', 'semester', 'quote', 'school', 'promo',
|
||||
'forum_signature', 'is_subscriber_viewable']
|
||||
'scrub_pict', 'sex', 'second_email', 'address', 'parent_address', 'phone', 'parent_phone',
|
||||
'tshirt_size', 'role', 'department', 'dpt_option', 'semester', 'quote', 'school', 'promo',
|
||||
'forum_signature', 'is_subscriber_viewable']
|
||||
widgets = {
|
||||
'date_of_birth': SelectDate,
|
||||
'profile_pict': forms.ClearableFileInput,
|
||||
'avatar_pict': forms.ClearableFileInput,
|
||||
'scrub_pict': forms.ClearableFileInput,
|
||||
'phone': PhoneNumberInternationalFallbackWidget,
|
||||
'parent_phone': PhoneNumberInternationalFallbackWidget,
|
||||
}
|
||||
'date_of_birth': SelectDate,
|
||||
'profile_pict': forms.ClearableFileInput,
|
||||
'avatar_pict': forms.ClearableFileInput,
|
||||
'scrub_pict': forms.ClearableFileInput,
|
||||
'phone': PhoneNumberInternationalFallbackWidget,
|
||||
'parent_phone': PhoneNumberInternationalFallbackWidget,
|
||||
}
|
||||
labels = {
|
||||
'profile_pict': _("Profile: you need to be visible on the picture, in order to be recognized (e.g. by the barmen)"),
|
||||
'avatar_pict': _("Avatar: used on the forum"),
|
||||
'scrub_pict': _("Scrub: let other know how your scrub looks like!"),
|
||||
}
|
||||
'profile_pict': _("Profile: you need to be visible on the picture, in order to be recognized (e.g. by the barmen)"),
|
||||
'avatar_pict': _("Avatar: used on the forum"),
|
||||
'scrub_pict': _("Scrub: let other know how your scrub looks like!"),
|
||||
}
|
||||
|
||||
def __init__(self, *arg, **kwargs):
|
||||
super(UserProfileForm, self).__init__(*arg, **kwargs)
|
||||
@ -197,14 +206,14 @@ class UserProfileForm(forms.ModelForm):
|
||||
self.cleaned_data['profile_pict'] = profile
|
||||
self.cleaned_data['scrub_pict'] = scrub
|
||||
parent = SithFile.objects.filter(parent=None, name="profiles").first()
|
||||
for field,f in files:
|
||||
for field, f in files:
|
||||
with transaction.atomic():
|
||||
try:
|
||||
im = Image.open(BytesIO(f.read()))
|
||||
new_file = SithFile(parent=parent, name=self.generate_name(field, f),
|
||||
file=resize_image(im, 400, f.content_type.split('/')[-1]),
|
||||
owner=self.instance, is_folder=False, mime_type=f.content_type, size=f._size,
|
||||
moderator=self.instance, is_moderated=True)
|
||||
file=resize_image(im, 400, f.content_type.split('/')[-1]),
|
||||
owner=self.instance, is_folder=False, mime_type=f.content_type, size=f._size,
|
||||
moderator=self.instance, is_moderated=True)
|
||||
new_file.file.name = new_file.name
|
||||
old = SithFile.objects.filter(parent=parent, name=new_file.name).first()
|
||||
if old:
|
||||
@ -216,16 +225,18 @@ class UserProfileForm(forms.ModelForm):
|
||||
except ValidationError as e:
|
||||
self._errors.pop(field, None)
|
||||
self.add_error(field, _("Error uploading file %(file_name)s: %(msg)s") %
|
||||
{'file_name': f, 'msg': str(e.message)})
|
||||
{'file_name': f, 'msg': str(e.message)})
|
||||
except IOError:
|
||||
self._errors.pop(field, None)
|
||||
self.add_error(field, _("Error uploading file %(file_name)s: %(msg)s") %
|
||||
{'file_name': f, 'msg': _("Bad image format, only jpeg, png, and gif are accepted")})
|
||||
{'file_name': f, 'msg': _("Bad image format, only jpeg, png, and gif are accepted")})
|
||||
self._post_clean()
|
||||
|
||||
|
||||
class UserPropForm(forms.ModelForm):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['groups']
|
||||
@ -236,13 +247,16 @@ class UserPropForm(forms.ModelForm):
|
||||
'groups': CheckboxSelectMultiple,
|
||||
}
|
||||
|
||||
|
||||
class UserGodfathersForm(forms.Form):
|
||||
type = forms.ChoiceField(choices=[('godfather', _("Godfather")), ('godchild', _("Godchild"))], label=_("Add"))
|
||||
user = AutoCompleteSelectField('users', required=True, label=_("Select user"), help_text=None)
|
||||
|
||||
|
||||
class PagePropForm(forms.ModelForm):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
||||
class Meta:
|
||||
model = Page
|
||||
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ]
|
||||
@ -255,4 +269,3 @@ class PagePropForm(forms.ModelForm):
|
||||
super(PagePropForm, self).__init__(*arg, **kwargs)
|
||||
self.fields['edit_groups'].required = False
|
||||
self.fields['view_groups'].required = False
|
||||
|
||||
|
@ -29,6 +29,7 @@ from django.core.urlresolvers import reverse_lazy
|
||||
from core.models import RealGroup
|
||||
from core.views import CanEditMixin
|
||||
|
||||
|
||||
class GroupListView(CanEditMixin, ListView):
|
||||
"""
|
||||
Displays the group list
|
||||
@ -36,17 +37,20 @@ class GroupListView(CanEditMixin, ListView):
|
||||
model = RealGroup
|
||||
template_name = "core/group_list.jinja"
|
||||
|
||||
|
||||
class GroupEditView(CanEditMixin, UpdateView):
|
||||
model = RealGroup
|
||||
pk_url_kwarg = "group_id"
|
||||
template_name = "core/group_edit.jinja"
|
||||
fields = ['name', 'description']
|
||||
|
||||
|
||||
class GroupCreateView(CanEditMixin, CreateView):
|
||||
model = RealGroup
|
||||
template_name = "core/group_edit.jinja"
|
||||
fields = ['name', 'description']
|
||||
|
||||
|
||||
class GroupDeleteView(CanEditMixin, DeleteView):
|
||||
model = RealGroup
|
||||
pk_url_kwarg = "group_id"
|
||||
|
@ -23,23 +23,22 @@
|
||||
#
|
||||
|
||||
# This file contains all the views that concern the page model
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.views.generic import ListView, DetailView
|
||||
from django.views.generic.edit import UpdateView, CreateView, DeleteView
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.forms.models import modelform_factory
|
||||
from django.forms import CheckboxSelectMultiple, modelform_factory
|
||||
from django.forms import CheckboxSelectMultiple
|
||||
|
||||
from core.models import Page, PageRev, LockError
|
||||
from core.views.forms import PagePropForm, MarkdownInput
|
||||
from core.views.forms import MarkdownInput
|
||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
|
||||
|
||||
|
||||
class PageListView(CanViewMixin, ListView):
|
||||
model = Page
|
||||
template_name = 'core/page_list.jinja'
|
||||
|
||||
|
||||
class PageView(CanViewMixin, DetailView):
|
||||
model = Page
|
||||
template_name = 'core/page_detail.jinja'
|
||||
@ -54,6 +53,7 @@ class PageView(CanViewMixin, DetailView):
|
||||
context['new_page'] = self.kwargs['page_name']
|
||||
return context
|
||||
|
||||
|
||||
class PageHistView(CanViewMixin, DetailView):
|
||||
model = Page
|
||||
template_name = 'core/page_hist.jinja'
|
||||
@ -62,6 +62,7 @@ class PageHistView(CanViewMixin, DetailView):
|
||||
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
|
||||
return self.page
|
||||
|
||||
|
||||
class PageRevView(CanViewMixin, DetailView):
|
||||
model = Page
|
||||
template_name = 'core/page_detail.jinja'
|
||||
@ -78,20 +79,21 @@ class PageRevView(CanViewMixin, DetailView):
|
||||
rev = self.page.revisions.get(id=self.kwargs['rev'])
|
||||
context['rev'] = rev
|
||||
except:
|
||||
# By passing, the template will just display the normal page without taking revision into account
|
||||
# By passing, the template will just display the normal page without taking revision into account
|
||||
pass
|
||||
else:
|
||||
context['new_page'] = self.kwargs['page_name']
|
||||
return context
|
||||
|
||||
|
||||
class PageCreateView(CanCreateMixin, CreateView):
|
||||
model = Page
|
||||
form_class = modelform_factory(Page,
|
||||
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ],
|
||||
widgets={
|
||||
'edit_groups':CheckboxSelectMultiple,
|
||||
'view_groups':CheckboxSelectMultiple,
|
||||
})
|
||||
fields=['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ],
|
||||
widgets={
|
||||
'edit_groups': CheckboxSelectMultiple,
|
||||
'view_groups': CheckboxSelectMultiple,
|
||||
})
|
||||
template_name = 'core/page_prop.jinja'
|
||||
|
||||
def get_initial(self):
|
||||
@ -115,14 +117,15 @@ class PageCreateView(CanCreateMixin, CreateView):
|
||||
ret = super(PageCreateView, self).form_valid(form)
|
||||
return ret
|
||||
|
||||
|
||||
class PagePropView(CanEditPropMixin, UpdateView):
|
||||
model = Page
|
||||
form_class = modelform_factory(Page,
|
||||
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ],
|
||||
widgets={
|
||||
'edit_groups':CheckboxSelectMultiple,
|
||||
'view_groups':CheckboxSelectMultiple,
|
||||
})
|
||||
fields=['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ],
|
||||
widgets={
|
||||
'edit_groups': CheckboxSelectMultiple,
|
||||
'view_groups': CheckboxSelectMultiple,
|
||||
})
|
||||
template_name = 'core/page_prop.jinja'
|
||||
slug_field = '_full_name'
|
||||
slug_url_kwarg = 'page_name'
|
||||
@ -130,7 +133,7 @@ class PagePropView(CanEditPropMixin, UpdateView):
|
||||
def get_object(self):
|
||||
o = super(PagePropView, self).get_object()
|
||||
# Create the page if it does not exists
|
||||
#if p == None:
|
||||
# if p == None:
|
||||
# parent_name = '/'.join(page_name.split('/')[:-1])
|
||||
# name = page_name.split('/')[-1]
|
||||
# if parent_name == "":
|
||||
@ -145,9 +148,10 @@ class PagePropView(CanEditPropMixin, UpdateView):
|
||||
raise e
|
||||
return self.page
|
||||
|
||||
|
||||
class PageEditView(CanEditMixin, UpdateView):
|
||||
model = PageRev
|
||||
form_class = modelform_factory(model=PageRev, fields=['title', 'content',], widgets={'content': MarkdownInput})
|
||||
form_class = modelform_factory(model=PageRev, fields=['title', 'content', ], widgets={'content': MarkdownInput})
|
||||
template_name = 'core/pagerev_edit.jinja'
|
||||
|
||||
def get_object(self):
|
||||
|
@ -22,17 +22,13 @@
|
||||
#
|
||||
#
|
||||
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.db import models
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import JsonResponse
|
||||
from django.core import serializers
|
||||
from django.db.models import Q
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.generic import ListView, TemplateView
|
||||
|
||||
import os
|
||||
import json
|
||||
from itertools import chain
|
||||
|
||||
from haystack.query import SearchQuerySet
|
||||
|
||||
@ -40,9 +36,11 @@ from core.models import User, Notification
|
||||
from core.utils import doku_to_markdown, bbcode_to_markdown
|
||||
from club.models import Club
|
||||
|
||||
|
||||
def index(request, context=None):
|
||||
return render(request, "core/index.jinja")
|
||||
|
||||
|
||||
class NotificationList(ListView):
|
||||
model = Notification
|
||||
template_name = "core/notification_list.jinja"
|
||||
@ -52,6 +50,7 @@ class NotificationList(ListView):
|
||||
self.request.user.notifications.update(viewed=True)
|
||||
return self.request.user.notifications.order_by('-id')[:20]
|
||||
|
||||
|
||||
def notification(request, notif_id):
|
||||
notif = Notification.objects.filter(id=notif_id).first()
|
||||
if notif:
|
||||
@ -60,44 +59,50 @@ def notification(request, notif_id):
|
||||
return redirect(notif.url)
|
||||
return redirect("/")
|
||||
|
||||
|
||||
def search_user(query, as_json=False):
|
||||
res = SearchQuerySet().models(User).filter(text=query).filter_or(text__contains=query)[:20]
|
||||
return [r.object for r in res]
|
||||
|
||||
|
||||
def search_club(query, as_json=False):
|
||||
clubs = []
|
||||
if query:
|
||||
clubs = Club.objects.filter(name__icontains=query).all()
|
||||
clubs = clubs[:5]
|
||||
if as_json: # Re-loads json to avoid double encoding by JsonResponse, but still benefit from serializers
|
||||
if as_json: # Re-loads json to avoid double encoding by JsonResponse, but still benefit from serializers
|
||||
clubs = json.loads(serializers.serialize('json', clubs, fields=('name')))
|
||||
else:
|
||||
clubs = list(clubs)
|
||||
return clubs
|
||||
|
||||
|
||||
@login_required
|
||||
def search_view(request):
|
||||
result = {
|
||||
'users': search_user(request.GET.get('query', '')),
|
||||
'clubs': search_club(request.GET.get('query', '')),
|
||||
}
|
||||
'users': search_user(request.GET.get('query', '')),
|
||||
'clubs': search_club(request.GET.get('query', '')),
|
||||
}
|
||||
return render(request, "core/search.jinja", context={'result': result})
|
||||
|
||||
|
||||
@login_required
|
||||
def search_user_json(request):
|
||||
result = {
|
||||
'users': search_user(request.GET.get('query', ''), True),
|
||||
}
|
||||
'users': search_user(request.GET.get('query', ''), True),
|
||||
}
|
||||
return JsonResponse(result)
|
||||
|
||||
|
||||
@login_required
|
||||
def search_json(request):
|
||||
result = {
|
||||
'users': search_user(request.GET.get('query', ''), True),
|
||||
'clubs': search_club(request.GET.get('query', ''), True),
|
||||
}
|
||||
'users': search_user(request.GET.get('query', ''), True),
|
||||
'clubs': search_club(request.GET.get('query', ''), True),
|
||||
}
|
||||
return JsonResponse(result)
|
||||
|
||||
|
||||
class ToMarkdownView(TemplateView):
|
||||
template_name = "core/to_markdown.jinja"
|
||||
|
||||
@ -119,4 +124,3 @@ class ToMarkdownView(TemplateView):
|
||||
kwargs['text'] = ""
|
||||
kwargs['text_md'] = ""
|
||||
return kwargs
|
||||
|
||||
|
@ -24,30 +24,29 @@
|
||||
|
||||
# This file contains all the views that concern the user model
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth import logout as auth_logout, views
|
||||
from django.contrib.auth import views
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
from django.http import Http404
|
||||
from django.views.generic.edit import UpdateView
|
||||
from django.views.generic import ListView, DetailView, TemplateView, DeleteView
|
||||
from django.views.generic import ListView, DetailView, TemplateView
|
||||
from django.forms.models import modelform_factory
|
||||
from django.forms import CheckboxSelectMultiple
|
||||
from django.template.response import TemplateResponse
|
||||
from django.conf import settings
|
||||
from django.views.generic.dates import YearMixin, MonthMixin
|
||||
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta, datetime, date
|
||||
from datetime import timedelta, date
|
||||
import logging
|
||||
|
||||
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, QuickNotifMixin
|
||||
from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm, LoginForm, UserGodfathersForm
|
||||
from core.views.forms import RegisteringForm, UserProfileForm, LoginForm, UserGodfathersForm
|
||||
from core.models import User, SithFile, Preferences
|
||||
from club.models import Club
|
||||
from subscription.models import Subscription
|
||||
from trombi.views import UserTrombiForm
|
||||
|
||||
|
||||
def login(request):
|
||||
"""
|
||||
The login view
|
||||
@ -56,24 +55,28 @@ def login(request):
|
||||
"""
|
||||
return views.login(request, template_name="core/login.jinja", authentication_form=LoginForm)
|
||||
|
||||
|
||||
def logout(request):
|
||||
"""
|
||||
The logout view
|
||||
"""
|
||||
return views.logout_then_login(request)
|
||||
|
||||
|
||||
def password_change(request):
|
||||
"""
|
||||
Allows a user to change its password
|
||||
"""
|
||||
return views.password_change(request, template_name="core/password_change.jinja", post_change_redirect=reverse("core:password_change_done"))
|
||||
|
||||
|
||||
def password_change_done(request):
|
||||
"""
|
||||
Allows a user to change its password
|
||||
"""
|
||||
return views.password_change_done(request, template_name="core/password_change_done.jinja")
|
||||
|
||||
|
||||
def password_root_change(request, user_id):
|
||||
"""
|
||||
Allows a root user to change someone's password
|
||||
@ -92,6 +95,7 @@ def password_root_change(request, user_id):
|
||||
form = views.SetPasswordForm(user=user)
|
||||
return TemplateResponse(request, "core/password_change.jinja", {'form': form, 'target': user})
|
||||
|
||||
|
||||
def password_reset(request):
|
||||
"""
|
||||
Allows someone to enter an email adresse for resetting password
|
||||
@ -100,7 +104,8 @@ def password_reset(request):
|
||||
template_name="core/password_reset.jinja",
|
||||
email_template_name="core/password_reset_email.jinja",
|
||||
post_reset_redirect="core:password_reset_done",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def password_reset_done(request):
|
||||
"""
|
||||
@ -108,6 +113,7 @@ def password_reset_done(request):
|
||||
"""
|
||||
return views.password_reset_done(request, template_name="core/password_reset_done.jinja")
|
||||
|
||||
|
||||
def password_reset_confirm(request, uidb64=None, token=None):
|
||||
"""
|
||||
Provide a reset password formular
|
||||
@ -115,7 +121,8 @@ def password_reset_confirm(request, uidb64=None, token=None):
|
||||
return views.password_reset_confirm(request, uidb64=uidb64, token=token,
|
||||
post_reset_redirect="core:password_reset_complete",
|
||||
template_name="core/password_reset_confirm.jinja",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def password_reset_complete(request):
|
||||
"""
|
||||
@ -123,14 +130,15 @@ def password_reset_complete(request):
|
||||
"""
|
||||
return views.password_reset_complete(request,
|
||||
template_name="core/password_reset_complete.jinja",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def register(request):
|
||||
context = {}
|
||||
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'])
|
||||
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'
|
||||
@ -143,6 +151,7 @@ def register(request):
|
||||
context['form'] = form.as_p()
|
||||
return render(request, "core/register.jinja", context)
|
||||
|
||||
|
||||
class UserTabsMixin(TabedViewMixin):
|
||||
def get_tabs_title(self):
|
||||
return self.object.get_display_name()
|
||||
@ -150,67 +159,69 @@ class UserTabsMixin(TabedViewMixin):
|
||||
def get_list_of_tabs(self):
|
||||
tab_list = []
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_profile', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'infos',
|
||||
'url': reverse('core:user_profile', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'infos',
|
||||
'name': _("Infos"),
|
||||
})
|
||||
})
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_godfathers', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'godfathers',
|
||||
'url': reverse('core:user_godfathers', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'godfathers',
|
||||
'name': _("Godfathers"),
|
||||
})
|
||||
})
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_pictures', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'pictures',
|
||||
'url': reverse('core:user_pictures', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'pictures',
|
||||
'name': _("Pictures"),
|
||||
})
|
||||
})
|
||||
if self.request.user == self.object:
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_tools'),
|
||||
'slug': 'tools',
|
||||
'url': reverse('core:user_tools'),
|
||||
'slug': 'tools',
|
||||
'name': _("Tools"),
|
||||
})
|
||||
})
|
||||
if self.request.user.can_edit(self.object):
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_edit', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'edit',
|
||||
'url': reverse('core:user_edit', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'edit',
|
||||
'name': _("Edit"),
|
||||
})
|
||||
})
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_prefs', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'prefs',
|
||||
'url': reverse('core:user_prefs', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'prefs',
|
||||
'name': _("Preferences"),
|
||||
})
|
||||
})
|
||||
if self.request.user.can_view(self.object):
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_clubs', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'clubs',
|
||||
'url': reverse('core:user_clubs', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'clubs',
|
||||
'name': _("Clubs"),
|
||||
})
|
||||
})
|
||||
if self.request.user.is_owner(self.object):
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_groups', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'groups',
|
||||
'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_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
or self.request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name']+settings.SITH_BOARD_SUFFIX)
|
||||
or self.request.user.is_root)):
|
||||
or self.request.user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
or self.request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name'] + settings.SITH_BOARD_SUFFIX)
|
||||
or self.request.user.is_root)):
|
||||
tab_list.append({
|
||||
'url': reverse('core:user_stats', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'stats',
|
||||
'url': reverse('core:user_stats', kwargs={'user_id': self.object.id}),
|
||||
'slug': 'stats',
|
||||
'name': _("Stats"),
|
||||
})
|
||||
})
|
||||
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
|
||||
'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):
|
||||
"""
|
||||
Display a user's profile
|
||||
@ -225,8 +236,8 @@ class UserView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
def DeleteUserGodfathers(request, user_id, godfather_id, is_father):
|
||||
user = User.objects.get(id=user_id)
|
||||
if ((user == request.user) or
|
||||
request.user.is_root or
|
||||
request.user.is_board_member):
|
||||
request.user.is_root or
|
||||
request.user.is_board_member):
|
||||
ud = get_object_or_404(User, id=godfather_id)
|
||||
if is_father == "True":
|
||||
user.godfathers.remove(ud)
|
||||
@ -236,6 +247,7 @@ def DeleteUserGodfathers(request, user_id, godfather_id, is_father):
|
||||
raise PermissionDenied
|
||||
return redirect('core:user_godfathers', user_id=user_id)
|
||||
|
||||
|
||||
class UserPicturesView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
"""
|
||||
Display a user's pictures
|
||||
@ -246,6 +258,7 @@ class UserPicturesView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
template_name = "core/user_pictures.jinja"
|
||||
current_tab = 'pictures'
|
||||
|
||||
|
||||
class UserGodfathersView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
"""
|
||||
Display a user's godfathers
|
||||
@ -277,6 +290,7 @@ class UserGodfathersView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
kwargs['form'] = UserGodfathersForm()
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
"""
|
||||
Display a user's stats
|
||||
@ -295,7 +309,7 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
|
||||
if not (profile == request.user
|
||||
or request.user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name']+settings.SITH_BOARD_SUFFIX)
|
||||
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name'] + settings.SITH_BOARD_SUFFIX)
|
||||
or request.user.is_root):
|
||||
raise PermissionDenied
|
||||
|
||||
@ -303,26 +317,27 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs = super(UserStatsView, self).get_context_data(**kwargs)
|
||||
from counter.models import Counter, Product, Selling
|
||||
from counter.models import Counter
|
||||
from django.db.models import Sum
|
||||
foyer = Counter.objects.filter(name="Foyer").first()
|
||||
mde = Counter.objects.filter(name="MDE").first()
|
||||
gommette = Counter.objects.filter(name="La Gommette").first()
|
||||
semester_start=Subscription.compute_start(d=date.today(), duration=3)
|
||||
kwargs['total_perm_time'] = sum([p.end-p.start for p in self.object.permanencies.exclude(end=None)], timedelta())
|
||||
kwargs['total_foyer_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=foyer).exclude(end=None)], timedelta())
|
||||
kwargs['total_mde_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=mde).exclude(end=None)], timedelta())
|
||||
kwargs['total_gommette_time'] = sum([p.end-p.start for p in self.object.permanencies.filter(counter=gommette).exclude(end=None)], timedelta())
|
||||
kwargs['total_foyer_buyings'] = sum([b.unit_price*b.quantity for b in
|
||||
self.object.customer.buyings.filter(counter=foyer, date__gte=semester_start)])
|
||||
kwargs['total_mde_buyings'] = sum([b.unit_price*b.quantity for b in self.object.customer.buyings.filter(counter=mde,
|
||||
date__gte=semester_start)])
|
||||
kwargs['total_gommette_buyings'] = sum([b.unit_price*b.quantity for b in
|
||||
self.object.customer.buyings.filter(counter=gommette, date__gte=semester_start)])
|
||||
semester_start = Subscription.compute_start(d=date.today(), duration=3)
|
||||
kwargs['total_perm_time'] = sum([p.end - p.start for p in self.object.permanencies.exclude(end=None)], timedelta())
|
||||
kwargs['total_foyer_time'] = sum([p.end - p.start for p in self.object.permanencies.filter(counter=foyer).exclude(end=None)], timedelta())
|
||||
kwargs['total_mde_time'] = sum([p.end - p.start for p in self.object.permanencies.filter(counter=mde).exclude(end=None)], timedelta())
|
||||
kwargs['total_gommette_time'] = sum([p.end - p.start for p in self.object.permanencies.filter(counter=gommette).exclude(end=None)], timedelta())
|
||||
kwargs['total_foyer_buyings'] = sum([b.unit_price * b.quantity for b in
|
||||
self.object.customer.buyings.filter(counter=foyer, date__gte=semester_start)])
|
||||
kwargs['total_mde_buyings'] = sum([b.unit_price * b.quantity for b in self.object.customer.buyings.filter(counter=mde,
|
||||
date__gte=semester_start)])
|
||||
kwargs['total_gommette_buyings'] = sum([b.unit_price * b.quantity for b in
|
||||
self.object.customer.buyings.filter(counter=gommette, date__gte=semester_start)])
|
||||
kwargs['top_product'] = self.object.customer.buyings.values('product__name').annotate(
|
||||
product_sum=Sum('quantity')).exclude(product_sum=None).order_by('-product_sum').all()[:10]
|
||||
product_sum=Sum('quantity')).exclude(product_sum=None).order_by('-product_sum').all()[:10]
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserMiniView(CanViewMixin, DetailView):
|
||||
"""
|
||||
Display a user's profile
|
||||
@ -332,6 +347,7 @@ class UserMiniView(CanViewMixin, DetailView):
|
||||
context_object_name = "profile"
|
||||
template_name = "core/user_mini.jinja"
|
||||
|
||||
|
||||
class UserListView(ListView, CanEditPropMixin):
|
||||
"""
|
||||
Displays the user list
|
||||
@ -339,6 +355,7 @@ class UserListView(ListView, CanEditPropMixin):
|
||||
model = User
|
||||
template_name = "core/user_list.jinja"
|
||||
|
||||
|
||||
class UserUploadProfilePictView(CanEditMixin, DetailView):
|
||||
"""
|
||||
Handle the upload of the profile picture taken with webcam in navigator
|
||||
@ -356,17 +373,18 @@ class UserUploadProfilePictView(CanEditMixin, DetailView):
|
||||
raise ValidationError(_("User already has a profile picture"))
|
||||
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
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
"""
|
||||
Edit a user's profile
|
||||
@ -412,6 +430,7 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
kwargs['form'] = self.form
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserClubView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
"""
|
||||
Display the user's club(s)
|
||||
@ -422,6 +441,7 @@ class UserClubView(UserTabsMixin, CanViewMixin, DetailView):
|
||||
template_name = "core/user_clubs.jinja"
|
||||
current_tab = "clubs"
|
||||
|
||||
|
||||
class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
"""
|
||||
Edit a user's preferences
|
||||
@ -453,6 +473,7 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
|
||||
kwargs['trombi_form'] = UserTrombiForm()
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserUpdateGroupView(UserTabsMixin, CanEditPropMixin, UpdateView):
|
||||
"""
|
||||
Edit a user's groups
|
||||
@ -461,10 +482,11 @@ class UserUpdateGroupView(UserTabsMixin, CanEditPropMixin, UpdateView):
|
||||
pk_url_kwarg = "user_id"
|
||||
template_name = "core/user_group.jinja"
|
||||
form_class = modelform_factory(User, fields=['groups'],
|
||||
widgets={'groups':CheckboxSelectMultiple})
|
||||
widgets={'groups': CheckboxSelectMultiple})
|
||||
context_object_name = "profile"
|
||||
current_tab = "groups"
|
||||
|
||||
|
||||
class UserToolsView(QuickNotifMixin, UserTabsMixin, TemplateView):
|
||||
"""
|
||||
Displays the logged user's tools
|
||||
@ -481,6 +503,7 @@ class UserToolsView(QuickNotifMixin, UserTabsMixin, TemplateView):
|
||||
kwargs['object'] = self.request.user
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserAccountBase(UserTabsMixin, DetailView):
|
||||
"""
|
||||
Base class for UserAccount
|
||||
@ -489,15 +512,16 @@ class UserAccountBase(UserTabsMixin, DetailView):
|
||||
pk_url_kwarg = "user_id"
|
||||
current_tab = "account"
|
||||
|
||||
def dispatch(self, request, *arg, **kwargs): # Manually validates the rights
|
||||
def dispatch(self, request, *arg, **kwargs): # Manually validates the rights
|
||||
res = super(UserAccountBase, self).dispatch(request, *arg, **kwargs)
|
||||
if (self.object == request.user
|
||||
or request.user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name']+settings.SITH_BOARD_SUFFIX)
|
||||
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name'] + settings.SITH_BOARD_SUFFIX)
|
||||
or request.user.is_root):
|
||||
return res
|
||||
raise PermissionDenied
|
||||
|
||||
|
||||
class UserAccountView(UserAccountBase):
|
||||
"""
|
||||
Display a user's account
|
||||
@ -511,14 +535,14 @@ class UserAccountView(UserAccountBase):
|
||||
stats.append([])
|
||||
i = 0
|
||||
for month in obj.filter(date__year=year.year).datetimes(
|
||||
'date', 'month', order='DESC'):
|
||||
'date', 'month', order='DESC'):
|
||||
q = obj.filter(
|
||||
date__year=month.year,
|
||||
date__month=month.month
|
||||
)
|
||||
stats[i].append({
|
||||
'sum':sum([calc(p) for p in q]),
|
||||
'date':month
|
||||
'sum': sum([calc(p) for p in q]),
|
||||
'date': month
|
||||
})
|
||||
i += 1
|
||||
return stats
|
||||
@ -551,6 +575,7 @@ class UserAccountView(UserAccountBase):
|
||||
print(repr(e))
|
||||
return kwargs
|
||||
|
||||
|
||||
class UserAccountDetailView(UserAccountBase, YearMixin, MonthMixin):
|
||||
"""
|
||||
Display a user's account for month
|
||||
@ -568,4 +593,3 @@ class UserAccountDetailView(UserAccountBase, YearMixin, MonthMixin):
|
||||
pass
|
||||
kwargs['tab'] = "account"
|
||||
return kwargs
|
||||
|
||||
|
Reference in New Issue
Block a user