-
Notifications
You must be signed in to change notification settings - Fork 28
/
admin.py
127 lines (103 loc) · 4.03 KB
/
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2022 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""Invenio Administration core admin module."""
from flask import Blueprint
from flask_menu import current_menu
from werkzeug.utils import import_string
from invenio_administration.menu import AdminMenu
from .views.base import AdminView
class Administration:
"""Admin views core manager."""
def __init__(
self,
app=None,
name=None,
url=None,
ui_endpoint=None,
base_template=None,
):
"""Constructor.
:param app: flask application
:param name: application name, defaults to "Admin"
:param url: base admin url to register the dashboard view and subviews
:param dashboard_view: home page view
:param ui_endpoint: base UI endpoint,
leaves flexibility to implement two different admin apps,
or to provide custom endpoint
:param base_template: base admin template.
Defaults to "admin/base.html"
"""
super().__init__()
self.app = app
self._views = []
self._menu = AdminMenu()
self._menu_key = "admin_navigation"
self.blueprint = None
if name is None:
name = "Administration"
self.name = name
self.dashboard_view_class = self.load_admin_dashboard(app)
self.endpoint = ui_endpoint or "administration"
self.url = url or "/administration"
self.base_template = base_template or "invenio_administration/base.html"
self.create_blueprint()
if self.dashboard_view_class is not None:
self._add_dashboard_view()
@app.before_first_request
def init_menu():
self._menu.register_menu_entries(current_menu, self._menu_key)
self._menu.register_admin_entry(current_menu, self.endpoint)
def load_admin_dashboard(self, app):
"""Load dashboard view configuration."""
dashboard_config = app.config["ADMINISTRATION_DASHBOARD_VIEW"]
dashboard_class = import_string(dashboard_config)
return dashboard_class
def create_blueprint(self):
"""Create Flask blueprint."""
# Create blueprint and register rules
self.blueprint = Blueprint(
self.endpoint,
__name__,
url_prefix=self.url,
template_folder="templates",
static_folder="static",
)
@property
def views(self):
"""Registered admin views."""
return self._views
def add_view(self, view, view_instance, *args, **kwargs):
"""Add a view to admin views."""
# Validate view's class and name's uniqueness.
if not issubclass(view.view_class, AdminView):
raise TypeError(f"View class must be of type {AdminView.__name__}")
if any(v.view_class.name == view.view_class.name for v in self.views):
raise ValueError(f"View name already registered: {view.view_class.name}")
self.views.append(view)
self.blueprint.add_url_rule(
rule=view_instance.url,
view_func=view,
)
from invenio_administration.views.base import (
AdminFormView,
AdminResourceDetailView,
)
if not isinstance(view_instance, AdminResourceDetailView) and not isinstance(
view_instance, AdminFormView):
self._menu.add_view_to_menu(view_instance)
def _add_dashboard_view(self):
"""Add the admin dashboard view."""
dashboard_instance = self.dashboard_view_class(
admin=self, extension_name="invenio-administration"
)
dashboard_view = self.dashboard_view_class.as_view(
self.dashboard_view_class.name,
admin=self,
extension_name="invenio-administration",
)
self.add_view(dashboard_view, dashboard_instance)