Source code for dsgovbr.menus
from django.urls import reverse, NoReverseMatch
from django.utils.module_loading import autodiscover_modules
[docs]
class MenuItem:
def __init__(self, name, url, icon=None, order=None, permission=None, check=None):
self.name = name
self.url = url
self.icon = icon or "fas fa-angle-right"
self.order = order
self.permission = permission
self.check = check
[docs]
def is_visible(self, request):
if self.check and not self.check(request):
return False
if self.permission:
if not request.user.is_authenticated:
return False
if not request.user.has_perm(self.permission):
return False
return True
[docs]
def to_dict(self, request=None):
resolved_url = self.url
if not (
self.url.startswith("/")
or self.url.startswith("http://")
or self.url.startswith("https://")
or self.url.startswith("javascript:")
):
try:
resolved_url = reverse(self.url)
except NoReverseMatch:
pass
return {
"name": self.name,
"admin_url": resolved_url,
"icon": self.icon,
}
[docs]
class MenuFolder:
def __init__(
self,
app_label,
name,
icon=None,
app_url=None,
order=None,
permission=None,
check=None,
):
self.app_label = app_label
self.name = name
self.icon = icon or "fas fa-folder"
self.app_url = app_url or "javascript:void(0);"
self.order = order
self.permission = permission
self.check = check
self._items = []
[docs]
def add_item(self, name, url, icon=None, order=None, permission=None, check=None):
# Evitar duplicados por nome/url
for item in self._items:
if item.name == name and item.url == url:
return item
item = MenuItem(name, url, icon, order, permission, check)
self._items.append(item)
return item
[docs]
def is_visible(self, request):
if self.check and not self.check(request):
return False
if self.permission:
if not request.user.is_authenticated:
return False
if not request.user.has_perm(self.permission):
return False
return True
[docs]
def to_dict(self, request=None):
resolved_app_url = self.app_url
if not (
self.app_url.startswith("/")
or self.app_url.startswith("http://")
or self.app_url.startswith("https://")
or self.app_url.startswith("javascript:")
):
try:
resolved_app_url = reverse(self.app_url)
except NoReverseMatch:
pass
return {
"name": self.name,
"app_label": self.app_label,
"app_url": resolved_app_url,
"icon": self.icon,
"models": [],
}
[docs]
def get_full_admin_app_list(request):
from django.contrib import admin
class DummyUser:
is_active = True
is_staff = True
is_superuser = True
def has_module_perms(self, app_label):
return True
def has_perm(self, perm, obj=None):
return True
def is_anonymous(self):
return False
def is_authenticated(self):
return True
class MockRequest:
def __init__(self, orig_req):
self.user = DummyUser()
self.META = getattr(orig_req, "META", {})
self.GET = getattr(orig_req, "GET", {})
self.POST = getattr(orig_req, "POST", {})
self.path = getattr(orig_req, "path", "")
self.path_info = getattr(orig_req, "path_info", "")
self.COOKIES = getattr(orig_req, "COOKIES", {})
self.session = getattr(orig_req, "session", None)
mock_req = MockRequest(request)
try:
return admin.site.get_app_list(mock_req)
except Exception as e:
print(f"Error getting admin app list with mock request: {e}")
return []
[docs]
class MenuRegistry:
def __init__(self):
self._folders = {}
self._reorder_callbacks = []
self._global_order = []
self._items_order = {}
[docs]
def register_folder(
self,
app_label,
name=None,
icon=None,
app_url=None,
order=None,
permission=None,
check=None,
):
if app_label not in self._folders:
self._folders[app_label] = MenuFolder(
app_label=app_label,
name=name or app_label.capitalize(),
icon=icon,
app_url=app_url,
order=order,
permission=permission,
check=check,
)
else:
folder = self._folders[app_label]
if name:
folder.name = name
if icon:
folder.icon = icon
if app_url:
folder.app_url = app_url
if order is not None:
folder.order = order
if permission:
folder.permission = permission
if check:
folder.check = check
return self._folders[app_label]
[docs]
def register_item(
self,
app_label,
name,
url,
icon=None,
order=None,
permission=None,
check=None,
):
folder = self.register_folder(app_label)
return folder.add_item(name, url, icon, order, permission, check)
[docs]
def set_items_order(self, app_label, order_list):
self._items_order[app_label] = list(order_list)
registry = MenuRegistry()
[docs]
def register_folder(
app_label,
name=None,
icon=None,
app_url=None,
order=None,
permission=None,
check=None,
):
return registry.register_folder(
app_label, name, icon, app_url, order, permission, check
)
[docs]
def register_item(
app_label, name, url, icon=None, order=None, permission=None, check=None
):
return registry.register_item(app_label, name, url, icon, order, permission, check)