add web frontend menu management
This commit is contained in:
parent
bf8750a196
commit
f5b2eb1193
|
@ -3,7 +3,7 @@ from datetime import datetime
|
||||||
start_time = datetime.now()
|
start_time = datetime.now()
|
||||||
|
|
||||||
from .application import Application
|
from .application import Application
|
||||||
from .config import Config
|
from .config import Config, UserLevel
|
||||||
from .request import Request
|
from .request import Request
|
||||||
from .response import Response
|
from .response import Response
|
||||||
from .view import View
|
from .view import View
|
||||||
|
|
|
@ -9,7 +9,7 @@ from urllib.parse import parse_qsl, urlparse
|
||||||
from izzylib import DotDict, Path, logging
|
from izzylib import DotDict, Path, logging
|
||||||
from izzylib.template import Template
|
from izzylib.template import Template
|
||||||
|
|
||||||
from .config import Config
|
from .config import Config, UserLevel
|
||||||
from .error_handlers import GenericError, MissingTemplateError
|
from .error_handlers import GenericError, MissingTemplateError
|
||||||
from .middleware import AccessLog, Headers
|
from .middleware import AccessLog, Headers
|
||||||
from .view import Manifest, Style
|
from .view import Manifest, Style
|
||||||
|
@ -67,6 +67,9 @@ class Application(sanic.Sanic):
|
||||||
for route in cls.paths:
|
for route in cls.paths:
|
||||||
self.add_route(cls.as_view(), route)
|
self.add_route(cls.as_view(), route)
|
||||||
|
|
||||||
|
if cls.menu:
|
||||||
|
self.set_menu_item(*cls.menu)
|
||||||
|
|
||||||
|
|
||||||
def add_error_handler(self, handler):
|
def add_error_handler(self, handler):
|
||||||
handle = handler(self)
|
handle = handler(self)
|
||||||
|
@ -78,6 +81,18 @@ class Application(sanic.Sanic):
|
||||||
self.register_middleware(mw.handler, mw.attach)
|
self.register_middleware(mw.handler, mw.attach)
|
||||||
|
|
||||||
|
|
||||||
|
def get_menu_item(self, name, level=0):
|
||||||
|
return self.cfg.menu[parse_level(level)][name]
|
||||||
|
|
||||||
|
|
||||||
|
def set_menu_item(self, name, path, level=0):
|
||||||
|
self.cfg.menu[parse_level(level)][name] = path
|
||||||
|
|
||||||
|
|
||||||
|
def del_menu_item(self, name, level=0):
|
||||||
|
del self.cfg.menu[parse_level(level)][name]
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
# register built-in middleware now so they're last in the chain
|
# register built-in middleware now so they're last in the chain
|
||||||
self.add_middleware(Headers)
|
self.add_middleware(Headers)
|
||||||
|
@ -104,3 +119,16 @@ class Application(sanic.Sanic):
|
||||||
|
|
||||||
self.stop()
|
self.stop()
|
||||||
logging.info('Bye! :3')
|
logging.info('Bye! :3')
|
||||||
|
|
||||||
|
|
||||||
|
def parse_level(level):
|
||||||
|
if type(level) == int:
|
||||||
|
new_level = UserLevel(level)
|
||||||
|
|
||||||
|
elif type(level) == str:
|
||||||
|
new_level = UserLevel[level.upper()]
|
||||||
|
|
||||||
|
elif type(level) != UserLevel:
|
||||||
|
raise TypeError(f'User level must be a string, integer, or UserLevel, not a {level.__class__.__name__}')
|
||||||
|
|
||||||
|
return new_level
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from enum import Enum
|
||||||
from izzylib import DotDict
|
from izzylib import DotDict
|
||||||
from multiprocessing import cpu_count
|
from multiprocessing import cpu_count
|
||||||
|
|
||||||
|
@ -5,6 +6,13 @@ from .request import Request
|
||||||
from .response import Response
|
from .response import Response
|
||||||
|
|
||||||
|
|
||||||
|
class UserLevel(Enum):
|
||||||
|
GUEST = 0
|
||||||
|
USER = 10
|
||||||
|
MODERATOR = 20
|
||||||
|
ADMIN = 30
|
||||||
|
|
||||||
|
|
||||||
class Config(DotDict):
|
class Config(DotDict):
|
||||||
defaults = dict(
|
defaults = dict(
|
||||||
name = 'IzzyLib Http Server',
|
name = 'IzzyLib Http Server',
|
||||||
|
@ -22,16 +30,24 @@ class Config(DotDict):
|
||||||
sig_handler = None,
|
sig_handler = None,
|
||||||
sig_handler_args = [],
|
sig_handler_args = [],
|
||||||
sig_handler_kwargs = {},
|
sig_handler_kwargs = {},
|
||||||
menu = {},
|
|
||||||
tpl_search = [],
|
tpl_search = [],
|
||||||
tpl_globals = {},
|
tpl_globals = {},
|
||||||
tpl_context = None,
|
tpl_context = None,
|
||||||
tpl_autoescape = True,
|
tpl_autoescape = True,
|
||||||
tpl_default = True
|
tpl_default = True,
|
||||||
|
menu = {
|
||||||
|
UserLevel.GUEST: {},
|
||||||
|
UserLevel.USER: {},
|
||||||
|
UserLevel.MODERATOR: {},
|
||||||
|
UserLevel.ADMIN: {}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
if kwargs.pop('menu', None):
|
||||||
|
raise ValueError('Use the Application.set_menu_item function to set menu items')
|
||||||
|
|
||||||
super().__init__({**self.defaults, **kwargs})
|
super().__init__({**self.defaults, **kwargs})
|
||||||
|
|
||||||
if kwargs.get('host') and not kwargs.get('web_host'):
|
if kwargs.get('host') and not kwargs.get('web_host'):
|
||||||
|
@ -39,6 +55,9 @@ class Config(DotDict):
|
||||||
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
|
if key == 'menu':
|
||||||
|
raise KeyError('Use the Application.set_menu_item function to set menu items')
|
||||||
|
|
||||||
if key not in self.defaults.keys():
|
if key not in self.defaults.keys():
|
||||||
raise KeyError(f'Invalid config key {key}')
|
raise KeyError(f'Invalid config key {key}')
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from .response import Response
|
||||||
|
|
||||||
class View(HTTPMethodView):
|
class View(HTTPMethodView):
|
||||||
routes = []
|
routes = []
|
||||||
|
menu = None # example: ("Home", "\", 0)
|
||||||
|
|
||||||
|
|
||||||
def dispatch_request(self, request, *args, **kwargs):
|
def dispatch_request(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -3,8 +3,8 @@ from setuptools import setup, find_namespace_packages
|
||||||
|
|
||||||
|
|
||||||
requires = [
|
requires = [
|
||||||
'sanic==20.12.3',
|
'sanic=>20.12.3',
|
||||||
'sanic-cors==1.0.0',
|
'sanic-cors=>1.0.0',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue