Use upstream logic for install command, and some web menus
This commit is contained in:
parent
617515a167
commit
c66d0ababa
|
@ -25,15 +25,10 @@ Messkit commands
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import stat
|
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from alembic.util.messaging import obfuscate_url_pw
|
|
||||||
|
|
||||||
from rattail import commands
|
from rattail import commands
|
||||||
from rattail.files import resource_path
|
|
||||||
|
|
||||||
from messkit import __version__
|
from messkit import __version__
|
||||||
|
|
||||||
|
@ -57,203 +52,67 @@ class Command(commands.Command):
|
||||||
long_description = ''
|
long_description = ''
|
||||||
|
|
||||||
|
|
||||||
class Install(commands.Subcommand):
|
class Install(commands.InstallSubcommand):
|
||||||
"""
|
"""
|
||||||
Install a Messkit app
|
Install the Messkit app
|
||||||
"""
|
"""
|
||||||
name = 'install'
|
name = 'install'
|
||||||
description = __doc__.strip()
|
description = __doc__.strip()
|
||||||
|
|
||||||
def run(self, args):
|
# nb. these must be explicitly set b/c config is not available
|
||||||
|
# when running normally, e.g. `messkit -n install`
|
||||||
|
app_title = "Messkit"
|
||||||
|
app_package = 'messkit'
|
||||||
|
app_eggname = 'Messkit'
|
||||||
|
app_pypiname = 'Messkit'
|
||||||
|
|
||||||
self.rprint("\n\t[blue]Welcome to Messkit![/blue]")
|
def do_install_steps(self):
|
||||||
self.rprint("\n\tThis tool will install and configure a new app.")
|
|
||||||
self.rprint("\n\t[italic]NB. You should already have created a new database in PostgreSQL or MySQL.[/italic]")
|
|
||||||
|
|
||||||
# continue?
|
# first all normal steps
|
||||||
if not self.basic_prompt("continue?", True, is_bool=True):
|
super(Install, self).do_install_steps()
|
||||||
self.rprint()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# appdir must not yet exist
|
# we also install poser..for now..?
|
||||||
appdir = os.path.join(sys.prefix, 'app')
|
self.install_poser()
|
||||||
if os.path.exists(appdir):
|
|
||||||
self.rprint("\n\t[bold red]appdir already exists:[/bold red] {}\n".format(appdir))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# get db info
|
def put_settings(self, **kwargs):
|
||||||
dbtype = self.basic_prompt('db type', 'postgresql')
|
|
||||||
dbhost = self.basic_prompt('db host', 'localhost')
|
|
||||||
dbport = self.basic_prompt('db port', '3306' if dbtype == 'mysql' else '5432')
|
|
||||||
dbname = self.basic_prompt('db name', 'messkit')
|
|
||||||
dbuser = self.basic_prompt('db user', 'rattail')
|
|
||||||
|
|
||||||
# get db password
|
rattail = [os.path.join(sys.prefix, 'bin', 'rattail'),
|
||||||
dbpass = None
|
'-c', os.path.join(sys.prefix, 'app', 'silent.conf')]
|
||||||
while not dbpass:
|
|
||||||
dbpass = self.basic_prompt('db pass', is_password=True)
|
|
||||||
|
|
||||||
# test db connection
|
# set falafel theme
|
||||||
self.rprint("\n\ttesting db connection... ", end='')
|
cmd = rattail + ['setting-put', 'tailbone.theme', 'falafel']
|
||||||
dburl = self.make_db_url(dbtype, dbhost, dbport, dbname, dbuser, dbpass)
|
subprocess.check_call(cmd)
|
||||||
error = self.test_db_connection(dburl)
|
|
||||||
if error:
|
|
||||||
self.rprint("[bold red]cannot connect![/bold red] ..error was:")
|
|
||||||
self.rprint("\n{}".format(error))
|
|
||||||
self.rprint("\n\t[bold yellow]aborting mission[/bold yellow]\n")
|
|
||||||
sys.exit(1)
|
|
||||||
self.rprint("[bold green]good[/bold green]")
|
|
||||||
|
|
||||||
# make the appdir
|
# hide theme picker
|
||||||
self.app.make_appdir(appdir)
|
cmd = rattail + ['setting-put', 'tailbone.themes.expose_picker', 'false']
|
||||||
|
subprocess.check_call(cmd)
|
||||||
|
|
||||||
# shared context for generated app files
|
# set main image
|
||||||
context = {
|
cmd = rattail + ['setting-put', 'tailbone.main_image_url', '/messkit/img/messkit.png']
|
||||||
'envdir': sys.prefix,
|
subprocess.check_call(cmd)
|
||||||
'app_package': 'messkit',
|
|
||||||
'app_title': "Messkit",
|
|
||||||
'appdir': appdir,
|
|
||||||
'db_url': dburl,
|
|
||||||
'pyramid_egg': 'Messkit',
|
|
||||||
'beaker_key': 'messkit',
|
|
||||||
}
|
|
||||||
|
|
||||||
# make config files
|
# set header image
|
||||||
rattail_conf = self.app.make_config_file(
|
cmd = rattail + ['setting-put', 'tailbone.header_image_url', '/messkit/img/messkit-small.png']
|
||||||
'rattail', os.path.join(appdir, 'rattail.conf'),
|
subprocess.check_call(cmd)
|
||||||
template_path=resource_path('messkit:templates/installer/rattail.conf.mako'),
|
|
||||||
**context)
|
|
||||||
quiet_conf = self.app.make_config_file('quiet', appdir)
|
|
||||||
web_conf = self.app.make_config_file(
|
|
||||||
'web-complete', os.path.join(appdir, 'web.conf'),
|
|
||||||
**context)
|
|
||||||
|
|
||||||
# make upgrade script
|
# set favicon image
|
||||||
path = os.path.join(appdir, 'upgrade.sh')
|
cmd = rattail + ['setting-put', 'tailbone.favicon_url', '/messkit/img/messkit-small.png']
|
||||||
self.app.render_mako_template(
|
subprocess.check_call(cmd)
|
||||||
resource_path('messkit:templates/installer/upgrade.sh.mako'),
|
|
||||||
context, output_path=path)
|
|
||||||
os.chmod(path, stat.S_IRWXU
|
|
||||||
| stat.S_IRGRP
|
|
||||||
| stat.S_IXGRP
|
|
||||||
| stat.S_IROTH
|
|
||||||
| stat.S_IXOTH)
|
|
||||||
|
|
||||||
self.rprint("\n\tappdir created at: [bold green]{}[/bold green]".format(appdir))
|
# set default grid page size
|
||||||
|
cmd = rattail + ['setting-put', 'tailbone.grid.default_pagesize', '20']
|
||||||
|
subprocess.check_call(cmd)
|
||||||
|
|
||||||
bindir = os.path.join(sys.prefix, 'bin')
|
def install_poser(self):
|
||||||
|
if not self.basic_prompt("make poser dir?", True, is_bool=True):
|
||||||
schema_installed = False
|
return False
|
||||||
if self.basic_prompt("install db schema?", True, is_bool=True):
|
|
||||||
self.rprint()
|
|
||||||
|
|
||||||
# install db schema
|
|
||||||
alembic = os.path.join(bindir, 'alembic')
|
|
||||||
cmd = [alembic, '-c', rattail_conf, 'upgrade', 'heads']
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
schema_installed = True
|
|
||||||
|
|
||||||
rattail = os.path.join(bindir, 'rattail')
|
|
||||||
|
|
||||||
# set falafel theme
|
|
||||||
cmd = [rattail, '-c', quiet_conf, '--no-versioning',
|
|
||||||
'setting-put', 'tailbone.theme', 'falafel']
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
# set main image
|
|
||||||
cmd = [rattail, '-c', quiet_conf, '--no-versioning',
|
|
||||||
'setting-put', 'tailbone.main_image_url', '/messkit/img/messkit.png']
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
# set header image
|
|
||||||
cmd = [rattail, '-c', quiet_conf, '--no-versioning',
|
|
||||||
'setting-put', 'tailbone.header_image_url', '/messkit/img/messkit-small.png']
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
# set favicon image
|
|
||||||
cmd = [rattail, '-c', quiet_conf, '--no-versioning',
|
|
||||||
'setting-put', 'tailbone.favicon_url', '/messkit/img/messkit-small.png']
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
self.rprint("\n\tdb schema installed to: [bold green]{}[/bold green]".format(
|
|
||||||
obfuscate_url_pw(dburl)))
|
|
||||||
|
|
||||||
if self.basic_prompt("create admin user?", True, is_bool=True):
|
|
||||||
|
|
||||||
# get admin credentials
|
|
||||||
username = self.basic_prompt('admin username', 'admin')
|
|
||||||
password = None
|
|
||||||
while not password:
|
|
||||||
password = self.basic_prompt('admin password', is_password=True)
|
|
||||||
if password:
|
|
||||||
confirm = self.basic_prompt('confirm password', is_password=True)
|
|
||||||
if not confirm or confirm != password:
|
|
||||||
self.rprint("[bold yellow]passwords did not match[/bold yellow]")
|
|
||||||
password = None
|
|
||||||
fullname = self.basic_prompt('full name')
|
|
||||||
|
|
||||||
self.rprint()
|
|
||||||
|
|
||||||
# make admin user
|
|
||||||
rattail = os.path.join(bindir, 'rattail')
|
|
||||||
cmd = [rattail, '-c', quiet_conf, 'make-user', '-A', username,
|
|
||||||
'--password', password]
|
|
||||||
if fullname:
|
|
||||||
cmd.extend(['--full-name', fullname])
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
self.rprint("\n\tadmin user created: [bold green]{}[/bold green]".format(
|
|
||||||
username))
|
|
||||||
|
|
||||||
if self.basic_prompt("make poser dir?", True, is_bool=True):
|
|
||||||
self.rprint()
|
|
||||||
|
|
||||||
# make poser dir
|
|
||||||
poser_handler = self.app.get_poser_handler()
|
|
||||||
poserdir = poser_handler.make_poser_dir()
|
|
||||||
|
|
||||||
self.rprint("\n\tposer dir created: [bold green]{}[/bold green]".format(
|
|
||||||
poserdir))
|
|
||||||
|
|
||||||
self.rprint("\n\t[bold green]initial setup is complete![/bold green]")
|
|
||||||
|
|
||||||
if schema_installed:
|
|
||||||
self.rprint("\n\tyou can run the web app with this command:")
|
|
||||||
pserve = os.path.join(bindir, 'pserve')
|
|
||||||
self.rprint("\n\t[blue]{} file+ini:{}[/blue]".format(pserve, web_conf))
|
|
||||||
|
|
||||||
self.rprint()
|
self.rprint()
|
||||||
|
|
||||||
# TODO: somewhere should ask about apache proxy, https etc.?
|
# make poser dir
|
||||||
|
poser_handler = self.app.get_poser_handler()
|
||||||
|
poserdir = poser_handler.make_poser_dir()
|
||||||
|
|
||||||
def make_db_url(self, dbtype, dbhost, dbport, dbname, dbuser, dbpass):
|
self.rprint("\n\tposer dir created: [bold green]{}[/bold green]".format(
|
||||||
try:
|
poserdir))
|
||||||
# newer style
|
return True
|
||||||
from sqlalchemy.engine import URL
|
|
||||||
factory = URL.create
|
|
||||||
except ImportError:
|
|
||||||
# older style
|
|
||||||
from sqlalchemy.engine.url import URL
|
|
||||||
factory = URL
|
|
||||||
|
|
||||||
if dbtype == 'mysql':
|
|
||||||
drivername = 'mysql+mysqlconnector'
|
|
||||||
else:
|
|
||||||
drivername = 'postgresql+psycopg2'
|
|
||||||
|
|
||||||
return factory(drivername=drivername,
|
|
||||||
username=dbuser,
|
|
||||||
password=dbpass,
|
|
||||||
host=dbhost,
|
|
||||||
port=dbport,
|
|
||||||
database=dbname)
|
|
||||||
|
|
||||||
def test_db_connection(self, url):
|
|
||||||
engine = sa.create_engine(url)
|
|
||||||
|
|
||||||
# check for random table; does not matter if it exists, we
|
|
||||||
# just need to test interaction and this is a neutral way
|
|
||||||
try:
|
|
||||||
engine.has_table('whatever')
|
|
||||||
except Exception as error:
|
|
||||||
return str(error)
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Messkit -- Generic-ish Data Utility App
|
# Messkit -- Generic-ish Data Utility App
|
||||||
# Copyright © 2022 Lance Edgar
|
# Copyright © 2022-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Messkit.
|
# This file is part of Messkit.
|
||||||
#
|
#
|
||||||
|
@ -42,7 +42,7 @@ class MesskitConfig(ConfigExtension):
|
||||||
config.setdefault('rattail', 'app_title', "Messkit")
|
config.setdefault('rattail', 'app_title', "Messkit")
|
||||||
config.setdefault('rattail', 'app_class_prefix', 'Messkit')
|
config.setdefault('rattail', 'app_class_prefix', 'Messkit')
|
||||||
config.setdefault('rattail', 'app_table_prefix', 'messkit')
|
config.setdefault('rattail', 'app_table_prefix', 'messkit')
|
||||||
config.setdefault('tailbone', 'menus', 'messkit.web.menus')
|
config.setdefault('tailbone.menus', 'handler', 'messkit.web.menus:MesskitMenuHandler')
|
||||||
config.setdefault('rattail', 'enum', 'messkit.enum')
|
config.setdefault('rattail', 'enum', 'messkit.enum')
|
||||||
config.setdefault('rattail', 'model', 'messkit.db.model')
|
config.setdefault('rattail', 'model', 'messkit.db.model')
|
||||||
config.setdefault('rattail.mail', 'emails', 'messkit.emails')
|
config.setdefault('rattail.mail', 'emails', 'messkit.emails')
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
## -*- mode: conf; -*-
|
|
||||||
|
|
||||||
<%text>############################################################</%text>
|
|
||||||
#
|
|
||||||
# ${app_title} core config
|
|
||||||
#
|
|
||||||
<%text>############################################################</%text>
|
|
||||||
|
|
||||||
|
|
||||||
<%text>##############################</%text>
|
|
||||||
# rattail
|
|
||||||
<%text>##############################</%text>
|
|
||||||
|
|
||||||
[rattail]
|
|
||||||
app_package = ${app_package}
|
|
||||||
timezone.default = ${timezone}
|
|
||||||
appdir = ${appdir}
|
|
||||||
datadir = ${os.path.join(appdir, 'data')}
|
|
||||||
batch.files = ${os.path.join(appdir, 'data', 'batch')}
|
|
||||||
workdir = ${os.path.join(appdir, 'work')}
|
|
||||||
export.files = ${os.path.join(appdir, 'data', 'exports')}
|
|
||||||
|
|
||||||
[rattail.config]
|
|
||||||
# require = /etc/rattail/rattail.conf
|
|
||||||
configure_logging = true
|
|
||||||
usedb = true
|
|
||||||
preferdb = true
|
|
||||||
|
|
||||||
[rattail.db]
|
|
||||||
default.url = ${db_url}
|
|
||||||
versioning.enabled = true
|
|
||||||
|
|
||||||
[rattail.mail]
|
|
||||||
|
|
||||||
# this is the global email shutoff switch
|
|
||||||
#send_emails = false
|
|
||||||
|
|
||||||
# recommended setup is to always talk to postfix on localhost and then
|
|
||||||
# it can handle any need complexities, e.g. sending to relay
|
|
||||||
smtp.server = localhost
|
|
||||||
|
|
||||||
# by default only email templates from rattail proper are used
|
|
||||||
templates = rattail:templates/mail
|
|
||||||
|
|
||||||
# this is the "default" email profile, from which all others initially
|
|
||||||
# inherit, but most/all profiles will override these values
|
|
||||||
default.prefix = [${app_title}]
|
|
||||||
default.from = rattail@localhost
|
|
||||||
default.to = root@localhost
|
|
||||||
# nb. in test environment it can be useful to disable by default, and
|
|
||||||
# then selectively enable certain (e.g. feedback, upgrade) emails
|
|
||||||
#default.enabled = false
|
|
||||||
|
|
||||||
[rattail.upgrades]
|
|
||||||
command = ${os.path.join(appdir, 'upgrade.sh')} --verbose
|
|
||||||
files = ${os.path.join(appdir, 'data', 'upgrades')}
|
|
||||||
|
|
||||||
|
|
||||||
<%text>##############################</%text>
|
|
||||||
# alembic
|
|
||||||
<%text>##############################</%text>
|
|
||||||
|
|
||||||
[alembic]
|
|
||||||
script_location = rattail.db:alembic
|
|
||||||
version_locations = rattail.db:alembic/versions
|
|
||||||
|
|
||||||
|
|
||||||
<%text>##############################</%text>
|
|
||||||
# logging
|
|
||||||
<%text>##############################</%text>
|
|
||||||
|
|
||||||
[loggers]
|
|
||||||
keys = root, exc_logger, beaker, txn, sqlalchemy, django_db, flufl_bounce, requests
|
|
||||||
|
|
||||||
[handlers]
|
|
||||||
keys = file, console, email
|
|
||||||
|
|
||||||
[formatters]
|
|
||||||
keys = generic, console
|
|
||||||
|
|
||||||
[logger_root]
|
|
||||||
handlers = file, console
|
|
||||||
level = DEBUG
|
|
||||||
|
|
||||||
[logger_exc_logger]
|
|
||||||
qualname = exc_logger
|
|
||||||
handlers = email
|
|
||||||
level = ERROR
|
|
||||||
|
|
||||||
[logger_beaker]
|
|
||||||
qualname = beaker
|
|
||||||
handlers =
|
|
||||||
level = INFO
|
|
||||||
|
|
||||||
[logger_txn]
|
|
||||||
qualname = txn
|
|
||||||
handlers =
|
|
||||||
level = INFO
|
|
||||||
|
|
||||||
[logger_sqlalchemy]
|
|
||||||
qualname = sqlalchemy.engine
|
|
||||||
handlers =
|
|
||||||
# handlers = file
|
|
||||||
# level = INFO
|
|
||||||
|
|
||||||
[logger_django_db]
|
|
||||||
qualname = django.db.backends
|
|
||||||
handlers =
|
|
||||||
level = INFO
|
|
||||||
# level = DEBUG
|
|
||||||
|
|
||||||
[logger_flufl_bounce]
|
|
||||||
qualname = flufl.bounce
|
|
||||||
handlers =
|
|
||||||
level = WARNING
|
|
||||||
|
|
||||||
[logger_requests]
|
|
||||||
qualname = requests
|
|
||||||
handlers =
|
|
||||||
# level = WARNING
|
|
||||||
|
|
||||||
[handler_file]
|
|
||||||
class = handlers.RotatingFileHandler
|
|
||||||
args = (${repr(os.path.join(appdir, 'log', 'rattail.log'))}, 'a', 1000000, 100, 'utf_8')
|
|
||||||
formatter = generic
|
|
||||||
|
|
||||||
[handler_console]
|
|
||||||
class = StreamHandler
|
|
||||||
args = (sys.stderr,)
|
|
||||||
formatter = console
|
|
||||||
# formatter = generic
|
|
||||||
# level = INFO
|
|
||||||
# level = WARNING
|
|
||||||
|
|
||||||
[handler_email]
|
|
||||||
class = handlers.SMTPHandler
|
|
||||||
args = ('localhost', 'rattail@localhost', ['root@localhost'], "[Rattail] Logging")
|
|
||||||
formatter = generic
|
|
||||||
level = ERROR
|
|
||||||
|
|
||||||
[formatter_generic]
|
|
||||||
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(funcName)s: %(message)s
|
|
||||||
datefmt = %Y-%m-%d %H:%M:%S
|
|
||||||
|
|
||||||
[formatter_console]
|
|
||||||
format = %(levelname)-5.5s [%(name)s][%(threadName)s] %(funcName)s: %(message)s
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/bin/sh -e
|
|
||||||
<%text>##################################################</%text>
|
|
||||||
#
|
|
||||||
# upgrade script for ${app_title} app
|
|
||||||
#
|
|
||||||
<%text>##################################################</%text>
|
|
||||||
|
|
||||||
if [ "$1" = "--verbose" ]; then
|
|
||||||
VERBOSE='--verbose'
|
|
||||||
QUIET=
|
|
||||||
else
|
|
||||||
VERBOSE=
|
|
||||||
QUIET='--quiet'
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ${envdir}
|
|
||||||
|
|
||||||
PIP='bin/pip'
|
|
||||||
ALEMBIC='bin/alembic'
|
|
||||||
|
|
||||||
# upgrade pip and friends
|
|
||||||
$PIP install $QUIET --disable-pip-version-check --upgrade pip
|
|
||||||
$PIP install $QUIET --upgrade setuptools wheel
|
|
||||||
|
|
||||||
# upgrade app proper
|
|
||||||
$PIP install $QUIET --upgrade --upgrade-strategy eager Messkit
|
|
||||||
|
|
||||||
# migrate schema
|
|
||||||
$ALEMBIC -c app/rattail.conf upgrade heads
|
|
|
@ -2,7 +2,7 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Messkit -- Generic-ish Data Utility App
|
# Messkit -- Generic-ish Data Utility App
|
||||||
# Copyright © 2022 Lance Edgar
|
# Copyright © 2022-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Messkit.
|
# This file is part of Messkit.
|
||||||
#
|
#
|
||||||
|
@ -24,97 +24,36 @@
|
||||||
Web Menus
|
Web Menus
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from tailbone import menus as base
|
||||||
|
|
||||||
def simple_menus(request):
|
|
||||||
|
|
||||||
people_menu = {
|
class MesskitMenuHandler(base.MenuHandler):
|
||||||
'title': "People",
|
"""
|
||||||
'type': 'menu',
|
Messkit menu handler
|
||||||
'items': [
|
"""
|
||||||
{
|
|
||||||
'title': "All People",
|
|
||||||
'route': 'people',
|
|
||||||
'perm': 'people.list',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
reports_menu = {
|
def make_menus(self, request, **kwargs):
|
||||||
'title': "Reports",
|
|
||||||
'type': 'menu',
|
|
||||||
'items': [
|
|
||||||
{
|
|
||||||
'title': "New Report",
|
|
||||||
'route': 'report_output.create',
|
|
||||||
'perm': 'report_output.create',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': "Generated Reports",
|
|
||||||
'route': 'report_output',
|
|
||||||
'perm': 'report_output.list',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': "Problem Reports",
|
|
||||||
'route': 'problem_reports',
|
|
||||||
'perm': 'problem_reports.list',
|
|
||||||
},
|
|
||||||
{'type': 'sep'},
|
|
||||||
{
|
|
||||||
'title': "Poser Reports",
|
|
||||||
'route': 'poser_reports',
|
|
||||||
'perm': 'poser_reports.list',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
admin_menu = {
|
people_menu = {
|
||||||
'title': "Admin",
|
'title': "People",
|
||||||
'type': 'menu',
|
'type': 'menu',
|
||||||
'items': [
|
'items': [
|
||||||
{
|
{
|
||||||
'title': "Users",
|
'title': "All People",
|
||||||
'route': 'users',
|
'route': 'people',
|
||||||
'perm': 'users.list',
|
'perm': 'people.list',
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
'title': "Roles",
|
}
|
||||||
'route': 'roles',
|
|
||||||
'perm': 'roles.list',
|
|
||||||
},
|
|
||||||
{'type': 'sep'},
|
|
||||||
{
|
|
||||||
'title': "App Settings",
|
|
||||||
'route': 'appsettings',
|
|
||||||
'perm': 'settings.list',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': "Email Settings",
|
|
||||||
'route': 'emailprofiles',
|
|
||||||
'perm': 'emailprofiles.list',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': "Raw Settings",
|
|
||||||
'route': 'settings',
|
|
||||||
'perm': 'settings.list',
|
|
||||||
},
|
|
||||||
{'type': 'sep'},
|
|
||||||
{
|
|
||||||
'title': "Tables",
|
|
||||||
'route': 'tables',
|
|
||||||
'perm': 'tables.list',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'title': "Messkit Upgrades",
|
|
||||||
'route': 'upgrades',
|
|
||||||
'perm': 'upgrades.list',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
menus = [
|
reports_menu = self.make_reports_menu(request, include_poser=True)
|
||||||
people_menu,
|
|
||||||
reports_menu,
|
|
||||||
admin_menu,
|
|
||||||
]
|
|
||||||
|
|
||||||
return menus
|
admin_menu = self.make_admin_menu(request, include_stores=False)
|
||||||
|
|
||||||
|
menus = [
|
||||||
|
people_menu,
|
||||||
|
reports_menu,
|
||||||
|
admin_menu,
|
||||||
|
]
|
||||||
|
|
||||||
|
return menus
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Messkit -- Generic-ish Data Utility App
|
# Messkit -- Generic-ish Data Utility App
|
||||||
# Copyright © 2022 Lance Edgar
|
# Copyright © 2022-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Messkit.
|
# This file is part of Messkit.
|
||||||
#
|
#
|
||||||
|
@ -30,8 +30,6 @@ from tailbone.util import include_configured_views
|
||||||
def includeme(config):
|
def includeme(config):
|
||||||
|
|
||||||
config.include('tailbone.views.essentials')
|
config.include('tailbone.views.essentials')
|
||||||
|
|
||||||
config.include('tailbone.views.poser')
|
config.include('tailbone.views.poser')
|
||||||
config.include('tailbone.views.reports')
|
|
||||||
|
|
||||||
include_configured_views(config)
|
include_configured_views(config)
|
||||||
|
|
Loading…
Reference in a new issue