All: Apply Black coding rules

This commit is contained in:
2018-10-04 21:29:19 +02:00
parent 0581c667de
commit cb58b00b6e
204 changed files with 13173 additions and 6376 deletions

View File

@ -26,43 +26,69 @@ import types
from django.shortcuts import render
from django.http import HttpResponseForbidden, HttpResponseNotFound
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ImproperlyConfigured
from django.core.exceptions import (
PermissionDenied,
ObjectDoesNotExist,
ImproperlyConfigured,
)
from django.views.generic.base import View
from django.db.models import Count
from core.models import Group
from core.views.forms import LoginForm
def forbidden(request):
try:
return HttpResponseForbidden(render(request, "core/403.jinja", context={'next': request.path, 'form':
LoginForm(), 'popup': request.resolver_match.kwargs['popup'] or ""}))
return HttpResponseForbidden(
render(
request,
"core/403.jinja",
context={
"next": request.path,
"form": LoginForm(),
"popup": request.resolver_match.kwargs["popup"] or "",
},
)
)
except:
return HttpResponseForbidden(render(request, "core/403.jinja", context={'next': request.path, 'form': LoginForm()}))
return HttpResponseForbidden(
render(
request,
"core/403.jinja",
context={"next": request.path, "form": LoginForm()},
)
)
def not_found(request):
return HttpResponseNotFound(render(request, "core/404.jinja"))
def can_edit_prop(obj, user):
if obj is None or user.is_owner(obj):
return True
return False
def can_edit(obj, user):
if obj is None or user.can_edit(obj):
return True
return can_edit_prop(obj, user)
def can_view(obj, user):
if obj is None or user.can_view(obj):
return True
return can_edit(obj, user)
class CanCreateMixin(View):
"""
This view is made to protect any child view that would create an object, and thus, that can not be protected by any
of the following mixin
"""
def dispatch(self, request, *arg, **kwargs):
res = super(CanCreateMixin, self).dispatch(request, *arg, **kwargs)
if not request.user.is_authenticated():
@ -75,6 +101,7 @@ class CanCreateMixin(View):
return super(CanCreateMixin, self).form_valid(form)
raise PermissionDenied
class CanEditPropMixin(View):
"""
This view is made to protect any child view that would be showing some properties of an object that are restricted
@ -82,64 +109,78 @@ class CanEditPropMixin(View):
In other word, you can make a view with this view as parent, and it would be retricted to the users that are in the
object's owner_group
"""
def dispatch(self, request, *arg, **kwargs):
try:
self.object = self.get_object()
if can_edit_prop(self.object, request.user):
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
return forbidden(request)
except: pass
except:
pass
# If we get here, it's a ListView
l_id = [o.id for o in self.get_queryset() if can_edit_prop(o, request.user)]
if not l_id and self.get_queryset().count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
class CanEditMixin(View):
"""
This view makes exactly the same thing as its direct parent, but checks the group on the edit_groups field of the
object
"""
def dispatch(self, request, *arg, **kwargs):
try:
self.object = self.get_object()
if can_edit(self.object, request.user):
return super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
return forbidden(request)
except: pass
except:
pass
# If we get here, it's a ListView
l_id = [o.id for o in self.get_queryset() if can_edit(o, request.user)]
if not l_id and self.get_queryset().count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
class CanViewMixin(View):
"""
This view still makes exactly the same thing as its direct parent, but checks the group on the view_groups field of
the object
"""
def dispatch(self, request, *arg, **kwargs):
try:
self.object = self.get_object()
if can_view(self.object, request.user):
return super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
return forbidden(request)
except: pass
except:
pass
# If we get here, it's a ListView
l_id = [o.id for o in self.get_queryset() if can_view(o, request.user)]
if not l_id and self.get_queryset().count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
@ -148,6 +189,7 @@ class FormerSubscriberMixin(View):
"""
This view check if the user was at least an old subscriber
"""
def dispatch(self, request, *args, **kwargs):
if not request.user.was_subscribed:
raise PermissionDenied
@ -158,6 +200,7 @@ class TabedViewMixin(View):
"""
This view provide the basic functions for displaying tabs in the template
"""
def get_tabs_title(self):
try:
return self.tabs_title
@ -178,38 +221,42 @@ class TabedViewMixin(View):
def get_context_data(self, **kwargs):
kwargs = super(TabedViewMixin, self).get_context_data(**kwargs)
kwargs['tabs_title'] = self.get_tabs_title()
kwargs['current_tab'] = self.get_current_tab()
kwargs['list_of_tabs'] = self.get_list_of_tabs()
kwargs["tabs_title"] = self.get_tabs_title()
kwargs["current_tab"] = self.get_current_tab()
kwargs["list_of_tabs"] = self.get_list_of_tabs()
return kwargs
class QuickNotifMixin:
quick_notif_list = []
def dispatch(self, request, *arg, **kwargs):
self.quick_notif_list = [] # In some cases, the class can stay instanciated, so we need to reset the list
self.quick_notif_list = (
[]
) # In some cases, the class can stay instanciated, so we need to reset the list
return super(QuickNotifMixin, self).dispatch(request, *arg, **kwargs)
def get_success_url(self):
ret = super(QuickNotifMixin, self).get_success_url()
try:
if '?' in ret:
ret += '&' + self.quick_notif_url_arg
if "?" in ret:
ret += "&" + self.quick_notif_url_arg
else:
ret += '?' + self.quick_notif_url_arg
except: pass
ret += "?" + self.quick_notif_url_arg
except:
pass
return ret
def get_context_data(self, **kwargs):
"""Add quick notifications to context"""
kwargs = super(QuickNotifMixin, self).get_context_data(**kwargs)
kwargs['quick_notifs'] = []
kwargs["quick_notifs"] = []
for n in self.quick_notif_list:
kwargs['quick_notifs'].append(settings.SITH_QUICK_NOTIF[n])
for k,v in settings.SITH_QUICK_NOTIF.items():
kwargs["quick_notifs"].append(settings.SITH_QUICK_NOTIF[n])
for k, v in settings.SITH_QUICK_NOTIF.items():
for gk in self.request.GET.keys():
if k == gk:
kwargs['quick_notifs'].append(v)
kwargs["quick_notifs"].append(v)
return kwargs
@ -218,5 +265,3 @@ from .page import *
from .files import *
from .site import *
from .group import *

View File

@ -54,55 +54,93 @@ def send_file(request, file_id, file_class=SithFile, file_attr="file"):
f = file_class.objects.filter(id=file_id).first()
if f is None or not f.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
Counter.objects.filter(token=request.session['counter_token']).exists())
):
if not (
can_view(f, request.user)
or (
"counter_token" in request.session.keys()
and request.session["counter_token"]
and Counter.objects.filter( # check if not null for counters that have no token set
token=request.session["counter_token"]
).exists()
)
):
raise PermissionDenied
name = f.__getattribute__(file_attr).name
filepath = os.path.join(settings.MEDIA_ROOT, name)
with open(filepath.encode('utf-8'), 'rb') as filename:
with open(filepath.encode("utf-8"), "rb") as filename:
wrapper = FileWrapper(filename)
response = HttpResponse(wrapper, content_type=f.mime_type)
response['Content-Length'] = os.path.getsize(filepath.encode('utf-8'))
response['Content-Disposition'] = ('inline; filename="%s"' % f.name).encode('utf-8')
response["Content-Length"] = os.path.getsize(filepath.encode("utf-8"))
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)
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,
)
def process(self, parent, owner, files):
notif = False
try:
if self.cleaned_data['folder_name'] != "":
folder = SithFile(parent=parent, name=self.cleaned_data['folder_name'], owner=owner)
if self.cleaned_data["folder_name"] != "":
folder = SithFile(
parent=parent, name=self.cleaned_data["folder_name"], owner=owner
)
folder.clean()
folder.save()
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)})
self.add_error(
None,
_("Error creating folder %(folder_name)s: %(msg)s")
% {"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)
new_file = SithFile(
parent=parent,
name=f.name,
file=f,
owner=owner,
is_folder=False,
mime_type=f.content_type,
size=f._size,
)
try:
new_file.clean()
new_file.save()
notif = True
except Exception as e:
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
self.add_error(
None,
_("Error uploading file %(file_name)s: %(msg)s")
% {"file_name": f, "msg": repr(e)},
)
if notif:
for u in RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID).first().users.all():
if not u.notifications.filter(type="FILE_MODERATION", viewed=False).exists():
Notification(user=u, url=reverse("core:file_moderation"), type="FILE_MODERATION").save()
for u in (
RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
.first()
.users.all()
):
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'
template_name = "core/file_list.jinja"
context_object_name = "file_list"
def get_queryset(self):
@ -110,81 +148,94 @@ class FileListView(ListView):
def get_context_data(self, **kwargs):
kwargs = super(FileListView, self).get_context_data(**kwargs)
kwargs['popup'] = ""
if self.kwargs['popup']:
kwargs['popup'] = 'popup'
kwargs["popup"] = ""
if self.kwargs["popup"]:
kwargs["popup"] = "popup"
return kwargs
class FileEditView(CanEditMixin, UpdateView):
model = SithFile
pk_url_kwarg = "file_id"
template_name = 'core/file_edit.jinja'
template_name = "core/file_edit.jinja"
context_object_name = "file"
def get_form_class(self):
fields = ['name', 'is_moderated']
fields = ["name", "is_moderated"]
if self.object.is_file:
fields = ['file'] + fields
fields = ["file"] + fields
return modelform_factory(SithFile, fields=fields)
def get_success_url(self):
if self.kwargs['popup']:
return reverse('core:file_detail', kwargs={'file_id': self.object.id, 'popup': "popup"})
return reverse('core:file_detail', kwargs={'file_id': self.object.id, 'popup': ""})
if self.kwargs["popup"]:
return reverse(
"core:file_detail", kwargs={"file_id": self.object.id, "popup": "popup"}
)
return reverse(
"core:file_detail", kwargs={"file_id": self.object.id, "popup": ""}
)
def get_context_data(self, **kwargs):
kwargs = super(FileEditView, self).get_context_data(**kwargs)
kwargs['popup'] = ""
if self.kwargs['popup']:
kwargs['popup'] = 'popup'
kwargs["popup"] = ""
if self.kwargs["popup"]:
kwargs["popup"] = "popup"
return kwargs
class FileEditPropForm(forms.ModelForm):
class Meta:
model = SithFile
fields = ['parent', 'owner', 'edit_groups', 'view_groups']
parent = make_ajax_field(SithFile, 'parent', 'files', help_text="")
edit_groups = make_ajax_field(SithFile, 'edit_groups', 'groups', help_text="", label=_("edit group"))
view_groups = make_ajax_field(SithFile, 'view_groups', 'groups', help_text="", label=_("view group"))
fields = ["parent", "owner", "edit_groups", "view_groups"]
parent = make_ajax_field(SithFile, "parent", "files", help_text="")
edit_groups = make_ajax_field(
SithFile, "edit_groups", "groups", help_text="", label=_("edit group")
)
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"
template_name = 'core/file_edit.jinja'
template_name = "core/file_edit.jinja"
context_object_name = "file"
form_class = FileEditPropForm
def get_form(self, form_class=None):
form = super(FileEditPropView, self).get_form(form_class)
form.fields['parent'].queryset = SithFile.objects.filter(is_folder=True)
form.fields["parent"].queryset = SithFile.objects.filter(is_folder=True)
return form
def form_valid(self, form):
ret = super(FileEditPropView, self).form_valid(form)
if form.cleaned_data['recursive']:
if form.cleaned_data["recursive"]:
self.object.apply_rights_recursively()
return ret
def get_success_url(self):
return reverse('core:file_detail', kwargs={'file_id': self.object.id, 'popup': self.kwargs['popup'] or ""})
return reverse(
"core:file_detail",
kwargs={"file_id": self.object.id, "popup": self.kwargs["popup"] or ""},
)
def get_context_data(self, **kwargs):
kwargs = super(FileEditPropView, self).get_context_data(**kwargs)
kwargs['popup'] = ""
if self.kwargs['popup']:
kwargs['popup'] = 'popup'
kwargs["popup"] = ""
if self.kwargs["popup"]:
kwargs["popup"] = "popup"
return kwargs
class FileView(CanViewMixin, DetailView, FormMixin):
"""This class handle the upload of new files into a folder"""
model = SithFile
pk_url_kwarg = "file_id"
template_name = 'core/file_detail.jinja'
template_name = "core/file_detail.jinja"
context_object_name = "file"
form_class = AddFilesForm
@ -201,79 +252,99 @@ class FileView(CanViewMixin, DetailView, FormMixin):
`object` is the SithFile object you want to put in the clipboard, or
where you want to paste the clipboard
"""
if 'delete' in request.POST.keys():
for f_id in request.POST.getlist('file_list'):
if "delete" in request.POST.keys():
for f_id in request.POST.getlist("file_list"):
sf = SithFile.objects.filter(id=f_id).first()
if sf:
sf.delete()
if 'clear' in request.POST.keys():
request.session['clipboard'] = []
if 'cut' in request.POST.keys():
for f_id in request.POST.getlist('file_list'):
if "clear" in request.POST.keys():
request.session["clipboard"] = []
if "cut" in request.POST.keys():
for f_id in request.POST.getlist("file_list"):
f_id = int(f_id)
if f_id in [c.id for c in object.children.all()] and f_id not in request.session['clipboard']:
request.session['clipboard'].append(f_id)
if 'paste' in request.POST.keys():
for f_id in request.session['clipboard']:
if (
f_id in [c.id for c in object.children.all()]
and f_id not in request.session["clipboard"]
):
request.session["clipboard"].append(f_id)
if "paste" in request.POST.keys():
for f_id in request.session["clipboard"]:
sf = SithFile.objects.filter(id=f_id).first()
if sf:
sf.move_to(object)
request.session['clipboard'] = []
request.session["clipboard"] = []
request.session.modified = True
def get(self, request, *args, **kwargs):
self.form = self.get_form()
if 'clipboard' not in request.session.keys():
request.session['clipboard'] = []
if "clipboard" not in request.session.keys():
request.session["clipboard"] = []
return super(FileView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if 'clipboard' not in request.session.keys():
request.session['clipboard'] = []
if "clipboard" not in request.session.keys():
request.session["clipboard"] = []
if request.user.can_edit(self.object):
# XXX this call can fail!
FileView.handle_clipboard(request, self.object)
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():
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)
if self.form.is_valid():
return super(FileView, self).form_valid(self.form)
return self.form_invalid(self.form)
def get_success_url(self):
return reverse('core:file_detail', kwargs={'file_id': self.object.id, 'popup': self.kwargs['popup'] or ""})
return reverse(
"core:file_detail",
kwargs={"file_id": self.object.id, "popup": self.kwargs["popup"] or ""},
)
def get_context_data(self, **kwargs):
kwargs = super(FileView, self).get_context_data(**kwargs)
kwargs['popup'] = ""
kwargs['form'] = self.form
if self.kwargs['popup']:
kwargs['popup'] = 'popup'
kwargs['clipboard'] = SithFile.objects.filter(id__in=self.request.session['clipboard'])
kwargs["popup"] = ""
kwargs["form"] = self.form
if self.kwargs["popup"]:
kwargs["popup"] = "popup"
kwargs["clipboard"] = SithFile.objects.filter(
id__in=self.request.session["clipboard"]
)
return kwargs
class FileDeleteView(CanEditPropMixin, DeleteView):
model = SithFile
pk_url_kwarg = "file_id"
template_name = 'core/file_delete_confirm.jinja'
template_name = "core/file_delete_confirm.jinja"
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
if 'next' in self.request.GET.keys():
return self.request.GET['next']
if "next" in self.request.GET.keys():
return self.request.GET["next"]
if self.object.parent is None:
return reverse('core:file_list', kwargs={'popup': self.kwargs['popup'] or ""})
return reverse('core:file_detail', kwargs={'file_id': self.object.parent.id, 'popup': self.kwargs['popup'] or ""})
return reverse(
"core:file_list", kwargs={"popup": self.kwargs["popup"] or ""}
)
return reverse(
"core:file_detail",
kwargs={
"file_id": self.object.parent.id,
"popup": self.kwargs["popup"] or "",
},
)
def get_context_data(self, **kwargs):
kwargs = super(FileDeleteView, self).get_context_data(**kwargs)
kwargs['popup'] = ""
if self.kwargs['popup']:
kwargs['popup'] = 'popup'
kwargs["popup"] = ""
if self.kwargs["popup"]:
kwargs["popup"] = "popup"
return kwargs
@ -282,7 +353,7 @@ class FileModerationView(TemplateView):
def get_context_data(self, **kwargs):
kwargs = super(FileModerationView, self).get_context_data(**kwargs)
kwargs['files'] = SithFile.objects.filter(is_moderated=False)[:100]
kwargs["files"] = SithFile.objects.filter(is_moderated=False)[:100]
return kwargs
@ -295,6 +366,6 @@ class FileModerateView(CanEditPropMixin, SingleObjectMixin):
self.object.is_moderated = True
self.object.moderator = request.user
self.object.save()
if 'next' in self.request.GET.keys():
return redirect(self.request.GET['next'])
return redirect('core:file_moderation')
if "next" in self.request.GET.keys():
return redirect(self.request.GET["next"])
return redirect("core:file_moderation")

View File

@ -27,7 +27,14 @@ from django import forms
from django.conf import settings
from django.db import transaction
from django.core.exceptions import ValidationError
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput, DateTimeInput, Textarea
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
@ -45,114 +52,144 @@ from PIL import Image
# Widgets
class SelectSingle(Select):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_single"
attrs["class"] = "select_single"
else:
attrs = {'class': "select_single"}
attrs = {"class": "select_single"}
return super(SelectSingle, self).render(name, value, attrs)
class SelectMultiple(Select):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_multiple"
attrs["class"] = "select_multiple"
else:
attrs = {'class': "select_multiple"}
attrs = {"class": "select_multiple"}
return super(SelectMultiple, self).render(name, value, attrs)
class SelectDateTime(DateTimeInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_datetime"
attrs["class"] = "select_datetime"
else:
attrs = {'class': "select_datetime"}
attrs = {"class": "select_datetime"}
return super(SelectDateTime, self).render(name, value, attrs)
class SelectDate(DateInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_date"
attrs["class"] = "select_date"
else:
attrs = {'class': "select_date"}
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),
}
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),
}
)
return output
class SelectFile(TextInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_file"
attrs["class"] = "select_file"
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,
}
output += '<span name="' + name + '" class="choose_file_button">' + ugettext("Choose file") + '</span>'
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,
}
)
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:
attrs['class'] = "select_user"
attrs["class"] = "select_user"
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,
}
output += '<span name="' + name + '" class="choose_user_button">' + ugettext("Choose user") + '</span>'
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,
}
)
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():
if "data" in kwargs.keys():
from counter.models import Customer
data = kwargs['data'].copy()
data = kwargs["data"].copy()
account_code = re.compile(r"^[0-9]+[A-Za-z]$")
try:
if account_code.match(data['username']):
user = Customer.objects.filter(account_id__iexact=data['username']).first().user
elif '@' in data['username']:
user = User.objects.filter(email__iexact=data['username']).first()
if account_code.match(data["username"]):
user = (
Customer.objects.filter(account_id__iexact=data["username"])
.first()
.user
)
elif "@" in data["username"]:
user = User.objects.filter(email__iexact=data["username"]).first()
else:
user = User.objects.filter(username=data['username']).first()
data['username'] = user.username
user = User.objects.filter(username=data["username"]).first()
data["username"] = user.username
except:
pass
kwargs['data'] = data
kwargs["data"] = data
super(LoginForm, self).__init__(*arg, **kwargs)
self.fields['username'].label = _("Username, email, or account number")
self.fields["username"].label = _("Username, email, or account number")
class RegisteringForm(UserCreationForm):
error_css_class = 'error'
required_css_class = 'required'
error_css_class = "error"
required_css_class = "required"
captcha = CaptchaField()
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
fields = ("first_name", "last_name", "email")
def save(self, commit=True):
user = super(RegisteringForm, self).save(commit=False)
@ -169,24 +206,49 @@ class UserProfileForm(forms.ModelForm):
This form is actually pretty bad and was made in the rush before the migration. It should be refactored.
TODO: refactor this form
"""
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']
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",
]
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):
@ -197,27 +259,36 @@ class UserProfileForm(forms.ModelForm):
def generate_name(self, field_name, f):
field_name = field_name[:-4]
return field_name + str(self.instance.id) + "." + f.content_type.split('/')[-1]
return field_name + str(self.instance.id) + "." + f.content_type.split("/")[-1]
def process(self, files):
avatar = self.instance.avatar_pict
profile = self.instance.profile_pict
scrub = self.instance.scrub_pict
self.full_clean()
self.cleaned_data['avatar_pict'] = avatar
self.cleaned_data['profile_pict'] = profile
self.cleaned_data['scrub_pict'] = scrub
self.cleaned_data["avatar_pict"] = avatar
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:
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)
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,
)
new_file.file.name = new_file.name
old = SithFile.objects.filter(parent=parent, name=new_file.name).first()
old = SithFile.objects.filter(
parent=parent, name=new_file.name
).first()
if old:
old.delete()
new_file.clean()
@ -226,73 +297,101 @@ class UserProfileForm(forms.ModelForm):
self._errors.pop(field, None)
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)})
self.add_error(
field,
_("Error uploading file %(file_name)s: %(msg)s")
% {"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")})
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"
),
},
)
self._post_clean()
class UserPropForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
error_css_class = "error"
required_css_class = "required"
class Meta:
model = User
fields = ['groups']
help_texts = {
'groups': "Which groups this user belongs to",
}
widgets = {
'groups': CheckboxSelectMultiple,
}
fields = ["groups"]
help_texts = {"groups": "Which groups this user belongs to"}
widgets = {"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)
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'
error_css_class = "error"
required_css_class = "required"
class Meta:
model = Page
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ]
edit_groups = make_ajax_field(Page, 'edit_groups', 'groups', help_text="", label=_("edit groups"))
view_groups = make_ajax_field(Page, 'view_groups', 'groups', help_text="", label=_("view groups"))
fields = ["parent", "name", "owner_group", "edit_groups", "view_groups"]
edit_groups = make_ajax_field(
Page, "edit_groups", "groups", help_text="", label=_("edit groups")
)
view_groups = make_ajax_field(
Page, "view_groups", "groups", help_text="", label=_("view groups")
)
def __init__(self, *arg, **kwargs):
super(PagePropForm, self).__init__(*arg, **kwargs)
self.fields['edit_groups'].required = False
self.fields['view_groups'].required = False
self.fields["edit_groups"].required = False
self.fields["view_groups"].required = False
class PageForm(forms.ModelForm):
class Meta:
model = Page
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups']
edit_groups = make_ajax_field(Page, 'edit_groups', 'groups', help_text="", label=_("edit groups"))
view_groups = make_ajax_field(Page, 'view_groups', 'groups', help_text="", label=_("view groups"))
fields = ["parent", "name", "owner_group", "edit_groups", "view_groups"]
edit_groups = make_ajax_field(
Page, "edit_groups", "groups", help_text="", label=_("edit groups")
)
view_groups = make_ajax_field(
Page, "view_groups", "groups", help_text="", label=_("view groups")
)
def __init__(self, *args, **kwargs):
super(PageForm, self).__init__(*args, **kwargs)
self.fields['parent'].queryset = self.fields['parent'].queryset.exclude(name=settings.SITH_CLUB_ROOT_PAGE).filter(club=None)
self.fields["parent"].queryset = (
self.fields["parent"]
.queryset.exclude(name=settings.SITH_CLUB_ROOT_PAGE)
.filter(club=None)
)
class GiftForm(forms.ModelForm):
class Meta:
model = Gift
fields = ['label', 'user']
fields = ["label", "user"]
label = forms.ChoiceField(choices=settings.SITH_GIFT_LIST)
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id', None)
user_id = kwargs.pop("user_id", None)
super(GiftForm, self).__init__(*args, **kwargs)
if user_id:
self.fields['user'].queryset = self.fields['user'].queryset.filter(id=user_id)
self.fields['user'].widget = forms.HiddenInput()
self.fields["user"].queryset = self.fields["user"].queryset.filter(
id=user_id
)
self.fields["user"].widget = forms.HiddenInput()

View File

@ -34,6 +34,7 @@ class GroupListView(CanEditMixin, ListView):
"""
Displays the group list
"""
model = RealGroup
template_name = "core/group_list.jinja"
@ -42,17 +43,17 @@ class GroupEditView(CanEditMixin, UpdateView):
model = RealGroup
pk_url_kwarg = "group_id"
template_name = "core/group_edit.jinja"
fields = ['name', 'description']
fields = ["name", "description"]
class GroupCreateView(CanEditMixin, CreateView):
model = RealGroup
template_name = "core/group_edit.jinja"
fields = ['name', 'description']
fields = ["name", "description"]
class GroupDeleteView(CanEditMixin, DeleteView):
model = RealGroup
pk_url_kwarg = "group_id"
template_name = "core/delete_confirm.jinja"
success_url = reverse_lazy('core:group_list')
success_url = reverse_lazy("core:group_list")

View File

@ -36,7 +36,6 @@ from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMi
class CanEditPagePropMixin(CanEditPropMixin):
def dispatch(self, request, *args, **kwargs):
res = super(CanEditPagePropMixin, self).dispatch(request, *args, **kwargs)
if self.object.is_club_page:
@ -46,93 +45,95 @@ class CanEditPagePropMixin(CanEditPropMixin):
class PageListView(CanViewMixin, ListView):
model = Page
template_name = 'core/page_list.jinja'
template_name = "core/page_list.jinja"
class PageView(CanViewMixin, DetailView):
model = Page
template_name = 'core/page_detail.jinja'
template_name = "core/page_detail.jinja"
def dispatch(self, request, *args, **kwargs):
res = super(PageView, self).dispatch(request, *args, **kwargs)
if self.object and self.object.need_club_redirection:
return redirect('club:club_view', club_id=self.object.club.id)
return redirect("club:club_view", club_id=self.object.club.id)
return res
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
self.page = Page.get_page_by_full_name(self.kwargs["page_name"])
return self.page
def get_context_data(self, **kwargs):
context = super(PageView, self).get_context_data(**kwargs)
if "page" not in context.keys():
context['new_page'] = self.kwargs['page_name']
context["new_page"] = self.kwargs["page_name"]
return context
class PageHistView(CanViewMixin, DetailView):
model = Page
template_name = 'core/page_hist.jinja'
template_name = "core/page_hist.jinja"
def dispatch(self, request, *args, **kwargs):
res = super(PageHistView, self).dispatch(request, *args, **kwargs)
if self.object.need_club_redirection:
return redirect('club:club_hist', club_id=self.object.club.id)
return redirect("club:club_hist", club_id=self.object.club.id)
return res
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
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'
template_name = "core/page_detail.jinja"
def dispatch(self, request, *args, **kwargs):
res = super(PageRevView, self).dispatch(request, *args, **kwargs)
if self.object.need_club_redirection:
return redirect('club:club_view_rev', club_id=self.object.club.id, rev_id=kwargs['rev'])
return redirect(
"club:club_view_rev", club_id=self.object.club.id, rev_id=kwargs["rev"]
)
return res
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
self.page = Page.get_page_by_full_name(self.kwargs["page_name"])
return self.page
def get_context_data(self, **kwargs):
context = super(PageRevView, self).get_context_data(**kwargs)
if self.page is not None:
context['page'] = self.page
context["page"] = self.page
try:
rev = self.page.revisions.get(id=self.kwargs['rev'])
context['rev'] = rev
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
pass
else:
context['new_page'] = self.kwargs['page_name']
context["new_page"] = self.kwargs["page_name"]
return context
class PageCreateView(CanCreateMixin, CreateView):
model = Page
form_class = PageForm
template_name = 'core/page_prop.jinja'
template_name = "core/page_prop.jinja"
def get_initial(self):
init = {}
if 'page' in self.request.GET.keys():
page_name = self.request.GET['page']
parent_name = '/'.join(page_name.split('/')[:-1])
if "page" in self.request.GET.keys():
page_name = self.request.GET["page"]
parent_name = "/".join(page_name.split("/")[:-1])
parent = Page.get_page_by_full_name(parent_name)
if parent is not None:
init['parent'] = parent.id
init['name'] = page_name.split('/')[-1]
init["parent"] = parent.id
init["name"] = page_name.split("/")[-1]
return init
def get_context_data(self, **kwargs):
context = super(PageCreateView, self).get_context_data(**kwargs)
context['new_page'] = True
context["new_page"] = True
return context
def form_valid(self, form):
@ -144,9 +145,9 @@ class PageCreateView(CanCreateMixin, CreateView):
class PagePropView(CanEditPagePropMixin, UpdateView):
model = Page
form_class = PagePropForm
template_name = 'core/page_prop.jinja'
slug_field = '_full_name'
slug_url_kwarg = 'page_name'
template_name = "core/page_prop.jinja"
slug_field = "_full_name"
slug_url_kwarg = "page_name"
def get_object(self):
o = super(PagePropView, self).get_object()
@ -169,11 +170,13 @@ class PagePropView(CanEditPagePropMixin, UpdateView):
class PageEditViewBase(CanEditMixin, UpdateView):
model = PageRev
form_class = modelform_factory(model=PageRev, fields=['title', 'content', ], widgets={'content': MarkdownInput})
template_name = 'core/pagerev_edit.jinja'
form_class = modelform_factory(
model=PageRev, fields=["title", "content"], widgets={"content": MarkdownInput}
)
template_name = "core/pagerev_edit.jinja"
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
self.page = Page.get_page_by_full_name(self.kwargs["page_name"])
return self._get_revision()
def _get_revision(self):
@ -193,17 +196,15 @@ class PageEditViewBase(CanEditMixin, UpdateView):
def get_context_data(self, **kwargs):
context = super(PageEditViewBase, self).get_context_data(**kwargs)
if self.page is not None:
context['page'] = self.page
context["page"] = self.page
else:
context['new_page'] = self.kwargs['page_name']
context["new_page"] = self.kwargs["page_name"]
return context
def form_valid(self, form):
# TODO : factor that, but first make some tests
rev = form.instance
new_rev = PageRev(title=rev.title,
content=rev.content,
)
new_rev = PageRev(title=rev.title, content=rev.content)
new_rev.author = self.request.user
new_rev.page = self.page
form.instance = new_rev
@ -211,18 +212,17 @@ class PageEditViewBase(CanEditMixin, UpdateView):
class PageEditView(PageEditViewBase):
def dispatch(self, request, *args, **kwargs):
res = super(PageEditView, self).dispatch(request, *args, **kwargs)
if self.object and self.object.page.need_club_redirection:
return redirect('club:club_edit_page', club_id=self.object.page.club.id)
return redirect("club:club_edit_page", club_id=self.object.page.club.id)
return res
class PageDeleteView(CanEditPagePropMixin, DeleteView):
model = Page
template_name = 'core/delete_confirm.jinja'
pk_url_kwarg = 'page_id'
template_name = "core/delete_confirm.jinja"
pk_url_kwarg = "page_id"
def get_success_url(self, **kwargs):
return reverse_lazy('core:page_list')
return reverse_lazy("core:page_list")

View File

@ -41,6 +41,7 @@ from club.models import Club
def index(request, context=None):
if request.user.is_authenticated():
from com.views import NewsListView
return NewsListView.as_view()(request)
return render(request, "core/index.jinja")
@ -50,11 +51,11 @@ class NotificationList(ListView):
template_name = "core/notification_list.jinja"
def get_queryset(self):
if 'see_all' in self.request.GET.keys():
if "see_all" in self.request.GET.keys():
for n in self.request.user.notifications.all():
n.viewed = True
n.save()
return self.request.user.notifications.order_by('-date')[:20]
return self.request.user.notifications.order_by("-date")[:20]
def notification(request, notif_id):
@ -70,7 +71,12 @@ def notification(request, notif_id):
def search_user(query, as_json=False):
res = SearchQuerySet().models(User).filter(text=query).filter_or(text__contains=query)[:20]
res = (
SearchQuerySet()
.models(User)
.filter(text=query)
.filter_or(text__contains=query)[:20]
)
return [r.object for r in res]
@ -79,8 +85,10 @@ def search_club(query, as_json=False):
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
clubs = json.loads(serializers.serialize('json', clubs, fields=('name')))
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
@ -89,25 +97,23 @@ def search_club(query, as_json=False):
@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})
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),
}
result = {"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)
@ -116,8 +122,8 @@ class ToMarkdownView(TemplateView):
template_name = "core/to_markdown.jinja"
def post(self, request, *args, **kwargs):
self.text = request.POST['text']
if request.POST['syntax'] == "doku":
self.text = request.POST["text"]
if request.POST["syntax"] == "doku":
self.text_md = doku_to_markdown(self.text)
else:
self.text_md = bbcode_to_markdown(self.text)
@ -127,9 +133,9 @@ class ToMarkdownView(TemplateView):
def get_context_data(self, **kwargs):
kwargs = super(ToMarkdownView, self).get_context_data(**kwargs)
try:
kwargs['text'] = self.text
kwargs['text_md'] = self.text_md
kwargs["text"] = self.text
kwargs["text_md"] = self.text_md
except:
kwargs['text'] = ""
kwargs['text_md'] = ""
kwargs["text"] = ""
kwargs["text_md"] = ""
return kwargs

View File

@ -31,7 +31,13 @@ from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied, ValidationError
from django.http import Http404, HttpResponse
from django.views.generic.edit import UpdateView
from django.views.generic import ListView, DetailView, TemplateView, CreateView, DeleteView
from django.views.generic import (
ListView,
DetailView,
TemplateView,
CreateView,
DeleteView,
)
from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple
from django.core.urlresolvers import reverse_lazy
@ -42,8 +48,20 @@ from django.views.generic.dates import YearMixin, MonthMixin
from datetime import timedelta, date
import logging
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, QuickNotifMixin
from core.views.forms import RegisteringForm, UserProfileForm, LoginForm, UserGodfathersForm, GiftForm
from core.views import (
CanViewMixin,
CanEditMixin,
CanEditPropMixin,
TabedViewMixin,
QuickNotifMixin,
)
from core.views.forms import (
RegisteringForm,
UserProfileForm,
LoginForm,
UserGodfathersForm,
GiftForm,
)
from core.models import User, SithFile, Preferences, Gift
from subscription.models import Subscription
from trombi.views import UserTrombiForm
@ -55,7 +73,9 @@ def login(request):
Needs to be improve with correct handling of form exceptions
"""
return views.login(request, template_name="core/login.jinja", authentication_form=LoginForm)
return views.login(
request, template_name="core/login.jinja", authentication_form=LoginForm
)
def logout(request):
@ -69,14 +89,20 @@ 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"))
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")
return views.password_change_done(
request, template_name="core/password_change_done.jinja"
)
def password_root_change(request, user_id):
@ -95,62 +121,74 @@ def password_root_change(request, user_id):
return redirect("core:password_change_done")
else:
form = views.SetPasswordForm(user=user)
return TemplateResponse(request, "core/password_change.jinja", {'form': form, 'target': 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
"""
return views.password_reset(request,
template_name="core/password_reset.jinja",
email_template_name="core/password_reset_email.jinja",
post_reset_redirect="core:password_reset_done",
)
return views.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):
"""
Confirm that the reset email has been sent
"""
return views.password_reset_done(request, template_name="core/password_reset_done.jinja")
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
"""
return views.password_reset_confirm(request, uidb64=uidb64, token=token,
post_reset_redirect="core:password_reset_complete",
template_name="core/password_reset_confirm.jinja",
)
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):
"""
Confirm the password has sucessfully been reset
"""
return views.password_reset_complete(request,
template_name="core/password_reset_complete.jinja",
)
return views.password_reset_complete(
request, template_name="core/password_reset_complete.jinja"
)
def register(request):
context = {}
if request.method == 'POST':
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'
context["user_registered"] = u
context["tests"] = "TEST_REGISTER_USER_FORM_OK"
form = RegisteringForm()
else:
context['error'] = 'Erreur'
context['tests'] = 'TEST_REGISTER_USER_FORM_FAIL'
context["error"] = "Erreur"
context["tests"] = "TEST_REGISTER_USER_FORM_FAIL"
else:
form = RegisteringForm()
context['form'] = form.as_p()
context["form"] = form.as_p()
return render(request, "core/register.jinja", context)
@ -160,65 +198,103 @@ 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',
'name': _("Infos"),
})
tab_list.append({
'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',
'name': _("Pictures"),
})
tab_list.append(
{
"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",
"name": _("Godfathers"),
}
)
tab_list.append(
{
"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',
'name': _("Tools"),
})
tab_list.append(
{"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',
'name': _("Edit"),
})
tab_list.append({
'url': reverse('core:user_prefs', kwargs={'user_id': self.object.id}),
'slug': 'prefs',
'name': _("Preferences"),
})
tab_list.append(
{
"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",
"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',
'name': _("Clubs"),
})
tab_list.append(
{
"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',
'name': _("Groups"),
})
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_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',
'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,
})
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
):
tab_list.append(
{
"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
return tab_list
@ -228,15 +304,18 @@ class UserView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's profile
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
template_name = "core/user_detail.jinja"
current_tab = 'infos'
current_tab = "infos"
def get_context_data(self, **kwargs):
kwargs = super(UserView, self).get_context_data(**kwargs)
kwargs['gift_form'] = GiftForm(user_id=self.object.id, initial={'user': self.object})
kwargs["gift_form"] = GiftForm(
user_id=self.object.id, initial={"user": self.object}
)
return kwargs
@ -244,33 +323,36 @@ class UserPicturesView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's pictures
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
template_name = "core/user_pictures.jinja"
current_tab = 'pictures'
current_tab = "pictures"
def get_context_data(self, **kwargs):
kwargs = super(UserPicturesView, self).get_context_data(**kwargs)
kwargs['albums'] = []
kwargs['pictures'] = {}
picture_qs = self.object.pictures.exclude(picture=None).order_by('-picture__parent__date', 'id').select_related('picture__parent')
kwargs["albums"] = []
kwargs["pictures"] = {}
picture_qs = (
self.object.pictures.exclude(picture=None)
.order_by("-picture__parent__date", "id")
.select_related("picture__parent")
)
last_album = None
for pict_relation in picture_qs:
album = pict_relation.picture.parent
if album.id != last_album:
kwargs['albums'].append(album)
kwargs['pictures'][album.id] = []
kwargs["albums"].append(album)
kwargs["pictures"][album.id] = []
last_album = album.id
kwargs['pictures'][album.id].append(pict_relation.picture)
kwargs["pictures"][album.id].append(pict_relation.picture)
return kwargs
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):
if (user == request.user) or 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)
@ -278,28 +360,29 @@ def DeleteUserGodfathers(request, user_id, godfather_id, is_father):
user.godchildren.remove(ud)
else:
raise PermissionDenied
return redirect('core:user_godfathers', user_id=user_id)
return redirect("core:user_godfathers", user_id=user_id)
class UserGodfathersView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's godfathers
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
template_name = "core/user_godfathers.jinja"
current_tab = 'godfathers'
current_tab = "godfathers"
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.form = UserGodfathersForm(request.POST)
if self.form.is_valid() and self.form.cleaned_data['user'] != self.object:
if self.form.cleaned_data['type'] == 'godfather':
self.object.godfathers.add(self.form.cleaned_data['user'])
if self.form.is_valid() and self.form.cleaned_data["user"] != self.object:
if self.form.cleaned_data["type"] == "godfather":
self.object.godfathers.add(self.form.cleaned_data["user"])
self.object.save()
else:
self.object.godchildren.add(self.form.cleaned_data['user'])
self.object.godchildren.add(self.form.cleaned_data["user"])
self.object.save()
self.form = UserGodfathersForm()
return super(UserGodfathersView, self).get(request, *args, **kwargs)
@ -307,39 +390,44 @@ class UserGodfathersView(UserTabsMixin, CanViewMixin, DetailView):
def get_context_data(self, **kwargs):
kwargs = super(UserGodfathersView, self).get_context_data(**kwargs)
try:
kwargs['form'] = self.form
kwargs["form"] = self.form
except:
kwargs['form'] = UserGodfathersForm()
kwargs["form"] = UserGodfathersForm()
return kwargs
class UserGodfathersTreeView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's family tree
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
template_name = "core/user_godfathers_tree.jinja"
current_tab = 'godfathers'
current_tab = "godfathers"
def get_context_data(self, **kwargs):
kwargs = super(UserGodfathersTreeView, self).get_context_data(**kwargs)
if "descent" in self.request.GET:
kwargs['param'] = "godchildren"
kwargs["param"] = "godchildren"
else:
kwargs['param'] = "godfathers"
kwargs['members_set'] = set()
kwargs["param"] = "godfathers"
kwargs["members_set"] = set()
return kwargs
class UserGodfathersTreePictureView(CanViewMixin, DetailView):
"""
Display a user's tree as a picture
"""
model = User
pk_url_kwarg = "user_id"
def build_complex_graph(self):
import pygraphviz as pgv
self.depth = int(self.request.GET.get("depth", 4))
if self.param == "godfathers":
self.graph = pgv.AGraph(strict=False, directed=True, rankdir="BT")
@ -349,7 +437,8 @@ class UserGodfathersTreePictureView(CanViewMixin, DetailView):
self.level = 1
# Since the tree isn't very deep, we can build it recursively
def crawl_family(user):
if self.level > self.depth: return
if self.level > self.depth:
return
self.level += 1
for u in user.__getattribute__(self.param).all():
self.graph.add_edge(user.get_short_name(), u.get_short_name())
@ -357,12 +446,14 @@ class UserGodfathersTreePictureView(CanViewMixin, DetailView):
family.add(u)
crawl_family(u)
self.level -= 1
self.graph.add_node(self.object.get_short_name())
family.add(self.object)
crawl_family(self.object)
def build_family_graph(self):
import pygraphviz as pgv
self.graph = pgv.AGraph(strict=False, directed=True)
self.graph.add_node(self.object.get_short_name())
for u in self.object.godfathers.all():
@ -384,29 +475,31 @@ class UserGodfathersTreePictureView(CanViewMixin, DetailView):
else:
self.build_complex_graph()
# Pimp the graph before display
self.graph.node_attr['color'] = "lightblue"
self.graph.node_attr['style'] = "filled"
self.graph.node_attr["color"] = "lightblue"
self.graph.node_attr["style"] = "filled"
main_node = self.graph.get_node(self.object.get_short_name())
main_node.attr['color'] = "sandybrown"
main_node.attr['shape'] = "rect"
main_node.attr["color"] = "sandybrown"
main_node.attr["shape"] = "rect"
if self.param == "godchildren":
self.graph.graph_attr['label'] = _("Godchildren")
self.graph.graph_attr["label"] = _("Godchildren")
elif self.param == "godfathers":
self.graph.graph_attr['label'] = _("Godfathers")
self.graph.graph_attr["label"] = _("Godfathers")
else:
self.graph.graph_attr['label'] = _("Family")
self.graph.graph_attr["label"] = _("Family")
img = self.graph.draw(format="png", prog="dot")
return HttpResponse(img, content_type="image/png")
class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's stats
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
template_name = "core/user_stats.jinja"
current_tab = 'stats'
current_tab = "stats"
def dispatch(self, request, *arg, **kwargs):
profile = self.get_object()
@ -414,10 +507,14 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
if not hasattr(profile, "customer"):
raise Http404
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_root):
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_root
):
raise PermissionDenied
return super(UserStatsView, self).dispatch(request, *arg, **kwargs)
@ -426,22 +523,71 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
kwargs = super(UserStatsView, self).get_context_data(**kwargs)
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)])
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]
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]
)
return kwargs
@ -449,6 +595,7 @@ class UserMiniView(CanViewMixin, DetailView):
"""
Display a user's profile
"""
model = User
pk_url_kwarg = "user_id"
context_object_name = "profile"
@ -459,6 +606,7 @@ class UserListView(ListView, CanEditPropMixin):
"""
Displays the user list
"""
model = User
template_name = "core/user_list.jinja"
@ -467,6 +615,7 @@ 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"
@ -475,16 +624,23 @@ class UserUploadProfilePictView(CanEditMixin, DetailView):
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"))
f = 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 = 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
@ -496,12 +652,13 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
"""
Edit a user's profile
"""
model = User
pk_url_kwarg = "user_id"
template_name = "core/user_edit.jinja"
form_class = UserProfileForm
current_tab = "edit"
edit_once = ['profile_pict', 'date_of_birth', 'first_name', 'last_name']
edit_once = ["profile_pict", "date_of_birth", "first_name", "last_name"]
board_only = []
def remove_restricted_fields(self, request):
@ -509,7 +666,9 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
Removes edit_once and board_only fields
"""
for i in self.edit_once:
if getattr(self.form.instance, i) and not (request.user.is_board_member or request.user.is_root):
if getattr(self.form.instance, i) and not (
request.user.is_board_member or request.user.is_root
):
self.form.fields.pop(i, None)
for i in self.board_only:
if not (request.user.is_board_member or request.user.is_root):
@ -527,14 +686,18 @@ class UserUpdateProfileView(UserTabsMixin, CanEditMixin, UpdateView):
self.remove_restricted_fields(request)
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():
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
kwargs["profile"] = self.form.instance
kwargs["form"] = self.form
return kwargs
@ -542,6 +705,7 @@ class UserClubView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display the user's club(s)
"""
model = User
context_object_name = "profile"
pk_url_kwarg = "user_id"
@ -553,28 +717,30 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
"""
Edit a user's preferences
"""
model = User
pk_url_kwarg = "user_id"
template_name = "core/user_preferences.jinja"
form_class = modelform_factory(Preferences, fields=['receive_weekmail',
'notify_on_click', 'notify_on_refill'])
form_class = modelform_factory(
Preferences, fields=["receive_weekmail", "notify_on_click", "notify_on_refill"]
)
context_object_name = "profile"
current_tab = "prefs"
def get_object(self, queryset=None):
user = get_object_or_404(User, pk=self.kwargs['user_id'])
user = get_object_or_404(User, pk=self.kwargs["user_id"])
return user
def get_form_kwargs(self):
kwargs = super(UserPreferencesView, self).get_form_kwargs()
pref = self.object.preferences
kwargs.update({'instance': pref})
kwargs.update({"instance": pref})
return kwargs
def get_context_data(self, **kwargs):
kwargs = super(UserPreferencesView, self).get_context_data(**kwargs)
if not hasattr(self.object, 'trombi_user'):
kwargs['trombi_form'] = UserTrombiForm()
if not hasattr(self.object, "trombi_user"):
kwargs["trombi_form"] = UserTrombiForm()
return kwargs
@ -582,11 +748,13 @@ class UserUpdateGroupView(UserTabsMixin, CanEditPropMixin, UpdateView):
"""
Edit a user's groups
"""
model = User
pk_url_kwarg = "user_id"
template_name = "core/user_group.jinja"
form_class = modelform_factory(User, fields=['groups'],
widgets={'groups': CheckboxSelectMultiple})
form_class = modelform_factory(
User, fields=["groups"], widgets={"groups": CheckboxSelectMultiple}
)
context_object_name = "profile"
current_tab = "groups"
@ -595,16 +763,18 @@ class UserToolsView(QuickNotifMixin, UserTabsMixin, TemplateView):
"""
Displays the logged user's tools
"""
template_name = "core/user_tools.jinja"
current_tab = "tools"
def get_context_data(self, **kwargs):
self.object = self.request.user
from launderette.models import Launderette
kwargs = super(UserToolsView, self).get_context_data(**kwargs)
kwargs['launderettes'] = Launderette.objects.all()
kwargs['profile'] = self.request.user
kwargs['object'] = self.request.user
kwargs["launderettes"] = Launderette.objects.all()
kwargs["profile"] = self.request.user
kwargs["object"] = self.request.user
return kwargs
@ -612,16 +782,21 @@ class UserAccountBase(UserTabsMixin, DetailView):
"""
Base class for UserAccount
"""
model = User
pk_url_kwarg = "user_id"
current_tab = "account"
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_root):
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_root
):
return res
raise PermissionDenied
@ -630,24 +805,20 @@ class UserAccountView(UserAccountBase):
"""
Display a user's account
"""
template_name = "core/user_account.jinja"
def expense_by_month(self, obj, calc):
stats = []
for year in obj.datetimes('date', 'year', order='DESC'):
for year in obj.datetimes("date", "year", order="DESC"):
stats.append([])
i = 0
for month in obj.filter(date__year=year.year).datetimes(
'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
})
"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})
i += 1
return stats
@ -659,22 +830,21 @@ class UserAccountView(UserAccountBase):
def get_context_data(self, **kwargs):
kwargs = super(UserAccountView, self).get_context_data(**kwargs)
kwargs['profile'] = self.object
kwargs["profile"] = self.object
try:
kwargs['customer'] = self.object.customer
kwargs['buyings_month'] = self.expense_by_month(
self.object.customer.buyings,
(lambda q: q.unit_price * q.quantity)
kwargs["customer"] = self.object.customer
kwargs["buyings_month"] = self.expense_by_month(
self.object.customer.buyings, (lambda q: q.unit_price * q.quantity)
)
kwargs['invoices_month'] = self.expense_by_month(
self.object.customer.user.invoices,
self.invoices_calc
kwargs["invoices_month"] = self.expense_by_month(
self.object.customer.user.invoices, self.invoices_calc
)
kwargs['refilling_month'] = self.expense_by_month(
self.object.customer.refillings,
(lambda q: q.amount)
kwargs["refilling_month"] = self.expense_by_month(
self.object.customer.refillings, (lambda q: q.amount)
)
kwargs['etickets'] = self.object.customer.buyings.exclude(product__eticket=None).all()
kwargs["etickets"] = self.object.customer.buyings.exclude(
product__eticket=None
).all()
except Exception as e:
print(repr(e))
return kwargs
@ -684,51 +854,52 @@ class UserAccountDetailView(UserAccountBase, YearMixin, MonthMixin):
"""
Display a user's account for month
"""
template_name = "core/user_account_detail.jinja"
def get_context_data(self, **kwargs):
kwargs = super(UserAccountDetailView, self).get_context_data(**kwargs)
kwargs['profile'] = self.object
kwargs['year'] = self.get_year()
kwargs['month'] = self.get_month()
kwargs["profile"] = self.object
kwargs["year"] = self.get_year()
kwargs["month"] = self.get_month()
try:
kwargs['customer'] = self.object.customer
kwargs["customer"] = self.object.customer
except:
pass
kwargs['tab'] = "account"
kwargs["tab"] = "account"
return kwargs
class GiftCreateView(CreateView):
form_class = GiftForm
template_name = 'core/create.jinja'
template_name = "core/create.jinja"
def dispatch(self, request, *args, **kwargs):
if not (request.user.is_board_member or request.user.is_root):
raise PermissionDenied
self.user = get_object_or_404(User, pk=kwargs['user_id'])
self.user = get_object_or_404(User, pk=kwargs["user_id"])
return super(GiftCreateView, self).dispatch(request, *args, **kwargs)
def get_initial(self):
return {'user': self.user}
return {"user": self.user}
def get_form_kwargs(self):
kwargs = super(GiftCreateView, self).get_form_kwargs()
kwargs['user_id'] = self.user.id
kwargs["user_id"] = self.user.id
return kwargs
def get_success_url(self):
return reverse_lazy('core:user_profile', kwargs={'user_id': self.user.id})
return reverse_lazy("core:user_profile", kwargs={"user_id": self.user.id})
class GiftDeleteView(CanEditPropMixin, DeleteView):
model = Gift
pk_url_kwarg = "gift_id"
template_name = 'core/delete_confirm.jinja'
template_name = "core/delete_confirm.jinja"
def dispatch(self, request, *args, **kwargs):
self.user = get_object_or_404(User, pk=kwargs['user_id'])
self.user = get_object_or_404(User, pk=kwargs["user_id"])
return super(GiftDeleteView, self).dispatch(request, *args, **kwargs)
def get_success_url(self):
return reverse_lazy('core:user_profile', kwargs={'user_id': self.user.id})
return reverse_lazy("core:user_profile", kwargs={"user_id": self.user.id})