#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2017-2026 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. from django.apps import AppConfig, apps from django.contrib.admin import AdminSite from django.http import Http404 from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse from django.utils.text import capfirst from django.utils.translation import gettext_lazy as _ class IshtarAdminSite(AdminSite): site_header = _("Ishtar administration") site_title = _("Ishtar administration") MODEL_OVERLOAD = { # (app, model) -> (new app, section) ("ishtar_common", "OperationType"): ("archaeological_operations", ""), ("authtoken", "Token"): ("ishtar_common", _("API")), } def _build_app_dict(self, request, label=None): # copied from contrib/admin/sites.py # overload to get add "admin_section" in models and use MODEL_OVERLOAD app_dict = {} if label: models = { m: m_a for m, m_a in self._registry.items() if m._meta.app_label == label or self.MODEL_OVERLOAD.get( (m._meta.app_label, m._meta.object_name), None ) } else: models = self._registry for model, model_admin in models.items(): app_label = model._meta.app_label # Ishtar object_name = model._meta.object_name admin_section = getattr(model, "ADMIN_SECTION", "") if (app_label, object_name) in self.MODEL_OVERLOAD: app_label_for_dict, admin_section = \ self.MODEL_OVERLOAD[(app_label, object_name)] else: app_label_for_dict = app_label # end Ishtar has_module_perms = model_admin.has_module_permission(request) if not has_module_perms: continue perms = model_admin.get_model_perms(request) # Check whether user has any perm for this module. # If so, add the module to the model_list. if True not in perms.values(): continue info = (app_label, model._meta.model_name) model_dict = { 'name': capfirst(model._meta.verbose_name_plural), 'object_name': model._meta.object_name, 'perms': perms, 'admin_url': None, 'add_url': None, # Ishtar change 'admin_section': admin_section, # End Ishtar change } if perms.get('change') or perms.get('view'): model_dict['view_only'] = not perms.get('change') try: model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=self.name) except NoReverseMatch: pass if perms.get('add'): try: model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=self.name) except NoReverseMatch: pass # Ishtar if app_label_for_dict in app_dict: app_dict[app_label_for_dict]['models'].append(model_dict) else: app_dict[app_label_for_dict] = { 'name': apps.get_app_config(app_label_for_dict).verbose_name, 'app_label': app_label_for_dict, 'app_url': reverse( 'admin:app_list', kwargs={'app_label': app_label_for_dict}, current_app=self.name, ), 'has_module_perms': has_module_perms, 'models': [model_dict], } # Ishtar end if label: return app_dict.get(label) return app_dict def get_app_list(self, request): # copied from contrib/admin/sites.py # overload to sort models by "admin_section" app_dict = self._build_app_dict(request) # Sort the apps alphabetically. app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower()) # Sort the models alphabetically within each app. for app in app_list: app['models'].sort(key=lambda x: (x['admin_section'], x['name'])) # Ishtar change return app_list def app_index(self, request, app_label, extra_context=None): # copied from contrib/admin/sites.py # overload to sort models by "admin_section" app_dict = self._build_app_dict(request, app_label) if not app_dict: raise Http404('The requested admin page does not exist.') # Sort the models alphabetically within each app. app_dict['models'].sort(key=lambda x: (x['admin_section'], x['name'])) # Ishtar change app_name = apps.get_app_config(app_label).verbose_name context = { **self.each_context(request), 'title': _('%(app)s administration') % {'app': app_name}, 'app_list': [app_dict], 'app_label': app_label, **(extra_context or {}), } request.current_app = self.name return TemplateResponse(request, self.app_index_template or [ 'admin/%s/app_index.html' % app_label, 'admin/app_index.html' ], context) admin_site = IshtarAdminSite() class IshtarCommonConfig(AppConfig): name = "ishtar_common" verbose_name = _("Ishtar - Common")