Skip to content
Snippets Groups Projects
__init__.py 6.06 KiB
Newer Older
import copy

from django.contrib.auth.mixins import UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.http import JsonResponse
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from django.views.generic import ListView
from django.views.generic.base import ContextMixin
from django.views.generic.detail import BaseDetailView
from django.views.generic.edit import ModelFormMixin
from ..models import (AppSettings, DataFile, DataSet, Lab, Log, Profile,
                      ShareGroup)


class StaffViewMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_staff


class PageViewMixin(ContextMixin):
    page_title = ''

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = self.page_title

        return context


class ActivePageViewMixin(PageViewMixin):
    active_page = ''

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['active_page'] = self.active_page

        return context


class SubmitLabelMixin(ContextMixin):
    submit_label = ''

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['submit_label'] = self.submit_label
        return context


class SuccessUrlMixin(ContextMixin):
    success_url = '#'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['success_url'] = self.success_url
        return context


class CreateViewMixin(SubmitLabelMixin, SuccessMessageMixin, SuccessUrlMixin, ActivePageViewMixin, ContextMixin):
    submit_label = _('Create')
    template_name = 'portal/secure/admin/create_update.html'
    success_message = _('Successfully Created "%(name)s"')


class UpdateViewMixin(SubmitLabelMixin, SuccessMessageMixin, SuccessUrlMixin, ActivePageViewMixin, ContextMixin):
    submit_label = _('Update')
    template_name = 'portal/secure/admin/create_update.html'
    success_message = _('Successfully Updated "%(name)s"')


class DeleteViewMixin(SubmitLabelMixin, SuccessMessageMixin, SuccessUrlMixin, ActivePageViewMixin, ContextMixin):
    submit_label = _('Delete')
    template_name = 'portal/secure/admin/delete.html'
    success_message = _('Successfully Deleted "%(name)s"')


class AppSettingsMixin(ContextMixin):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        app_settings = AppSettings.objects.first()
        if app_settings and app_settings.home_institution:
            context['home_institution'] = app_settings.home_institution.id
        return context


class AjaxDatatableBackboneMixin(ContextMixin):
    """List view to display a Datatable with AJAX datasource"""
    template_name = 'portal/secure/admin/list.html'
    create_url = '#'
    create_label = _('Create New')
    api_url = ''
    dt_struct = {}

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['create_url'] = self.create_url
        context['create_label'] = self.create_label
        context['api_url'] = self.api_url
        context['dt_struct'] = copy.copy(self.dt_struct)
        return context


    """Children must implement get_rows()
    Keep in mind: overriding get_queryset() to add 'select_related' statements might provide nice speed boost
    """
    def get_rows(self):
        pass

    def render_to_response(self, context, **response_kwargs):
        return JsonResponse({'data': self.get_rows()}, **response_kwargs)


class JSONView(BaseDetailView):
    """Children must implement get_rows()
    Keep in mind: overriding get_queryset() to add 'select_related' statements might provide nice speed boost
    """
    def get_data(self):
        pass

    def render_to_response(self, context, **response_kwargs):
        return JsonResponse(self.get_data(), **response_kwargs)
class LogMixin(ModelFormMixin):
    def form_valid(self, form):
        before = self.get_object()

        # m2m fields (Users attached to dataset, Files attached to dataset etc..)
        for d in self.qs_params:
            old = getattr(before, d)
            new = form.cleaned_data[d]

            if old != new:
                removed = set(old.all()) - set(new.all())
                added = set(new.all()) - set(old.all())

                for o in added.union(removed):
                    type = 'remove'
                    if o in added:
                        type = 'add'

                    with translation.override('en'):
                        label_en = str(form.fields[d].label)
                    with translation.override('fr'):
                        label_fr = str(form.fields[d].label) if str(form.fields[d].label) else label_en  # if no translations, save english

                    log = Log(action_type=type, profile=self.request.user.profile, obj_dataset=before, label_fr=label_fr, label_en=label_en)
                    if isinstance(o, Profile):
                        log.action_type += '_share'
                        log.obj_profile = o
                    elif isinstance(o, Lab):
                        log.action_type += '_share'
                        log.obj_lab = o
                    elif isinstance(o, ShareGroup):
                        log.action_type += '_share'
                        log.obj_group = o
                    elif isinstance(o, DataFile):
                        log.obj_datafile = o
                    log.save()

        # Standard fields (text, int etc..)
        for d in form.changed_data:
            if d not in self.qs_params:
                with translation.override('en'):
                    label_en = str(form.fields[d].label)
                with translation.override('fr'):
                    label_fr = str(form.fields[d].label) if str(form.fields[d].label) else label_en

                Log.objects.create(action_type='edit', profile=self.request.user.profile, obj_dataset=before, label_fr=label_fr, label_en=label_en)
        return super().form_valid(form)