Mercurial > piecrust2
view piecrust/commands/builtin/admin.py @ 891:f13d618cfec6
themes: Allow keeping local overrides when copying a theme locally.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 02 Jul 2017 22:19:58 -0700 |
parents | dcdec4b951a1 |
children | 33a89139c284 |
line wrap: on
line source
import os import os.path import logging from piecrust import CACHE_DIR, CONFIG_PATH from piecrust.commands.base import ChefCommand from piecrust.pathutil import SiteNotFoundError logger = logging.getLogger(__name__) class AdministrationPanelCommand(ChefCommand): def __init__(self): super(AdministrationPanelCommand, self).__init__() self.name = 'admin' self.description = "Manages the PieCrust administration panel." self.requires_website = False def setupParser(self, parser, app): subparsers = parser.add_subparsers() p = subparsers.add_parser( 'init', help="Creates a new administration panel website.") p.set_defaults(sub_func=self._initAdminSite) p = subparsers.add_parser( 'genpass', help=("Generates the hashed password for use as an " "admin password")) p.add_argument('password', help="The password to hash.") p.set_defaults(sub_func=self._generatePassword) p = subparsers.add_parser( 'run', help="Runs the administrative panel website.") p.add_argument( '-p', '--port', help="The port for the administrative panel website.", default=8090) p.add_argument( '-a', '--address', help="The host for the administrative panel website.", default='localhost') p.add_argument( '--no-assets', help="Don't process and monitor the asset folder(s).", dest='monitor_assets', action='store_false') p.add_argument( '--use-reloader', help="Restart the server when PieCrust code changes", action='store_true') p.add_argument( '--use-debugger', help="Show the debugger when an error occurs", action='store_true') p.set_defaults(sub_func=self._runAdminSite) def checkedRun(self, ctx): if ctx.app.root_dir is None: raise SiteNotFoundError(theme=ctx.app.theme_site) if not hasattr(ctx.args, 'sub_func'): ctx.parser.parse_args(['admin', '--help']) return return ctx.args.sub_func(ctx) def _runAdminSite(self, ctx): # See `_run_sse_check` in `piecrust.serving.wrappers` for an # explanation of this check. if (ctx.args.monitor_assets and ( not (ctx.args.debug or ctx.args.use_reloader) or os.environ.get('WERKZEUG_RUN_MAIN') == 'true')): from piecrust.serving.procloop import ProcessingLoop out_dir = os.path.join( ctx.app.root_dir, CACHE_DIR, 'admin', 'server') proc_loop = ProcessingLoop(ctx.appfactory, out_dir) proc_loop.start() es = { 'FOODTRUCK_CMDLINE_MODE': True, 'FOODTRUCK_ROOT': ctx.app.root_dir, 'FOODTRUCK_URL_PREFIX': '', 'SECRET_KEY': os.urandom(22), 'LOGIN_DISABLED': True} if ctx.args.debug or ctx.args.use_debugger: es['DEBUG'] = True run_foodtruck( host=ctx.args.address, port=ctx.args.port, use_reloader=ctx.args.use_reloader, extra_settings=es) def _initAdminSite(self, ctx): import io import getpass from piecrust.admin import bcryptfallback as bcrypt secret_key = os.urandom(22) admin_username = input("Admin username (admin): ") or 'admin' admin_password = getpass.getpass("Admin password: ") if not admin_password: logger.warning("No administration password set!") logger.warning("Don't make this instance of the PieCrust " "administration panel public.") logger.info("You can later set an admin password by editing " "the `admin.cfg` file and using the " "`chef admin genpass` command.") else: binpw = admin_password.encode('utf8') hashpw = bcrypt.hashpw(binpw, bcrypt.gensalt()).decode('utf8') admin_password = hashpw ft_config = """ admin: secret_key: %(secret_key)s username: %(username)s # You can generate another hashed password with `chef admin genpass`. password: %(password)s """ ft_config = ft_config % { 'secret_key': secret_key, 'username': admin_username, 'password': admin_password } config_path = os.path.join(ctx.app.root_dir, CONFIG_PATH) with open(config_path, 'a+', encoding='utf8') as fp: fp.seek(0, io.SEEK_END) fp.write('\n') fp.write(ft_config) def _generatePassword(self, ctx): from piecrust.admin import bcryptfallback as bcrypt binpw = ctx.args.password.encode('utf8') hashpw = bcrypt.hashpw(binpw, bcrypt.gensalt()).decode('utf8') logger.info(hashpw) def run_foodtruck(host=None, port=None, use_reloader=False, extra_settings=None): es = {} if extra_settings: es.update(extra_settings) # Disable PIN protection with Werkzeug's debugger. os.environ['WERKZEUG_DEBUG_PIN'] = 'off' try: from piecrust.admin.web import create_foodtruck_app app = create_foodtruck_app(es) app.run(host=host, port=port, use_reloader=use_reloader, threaded=True) except SystemExit: # This is needed for Werkzeug's code reloader to be able to correctly # shutdown the child process in order to restart it (otherwise, SSE # generators will keep it alive). try: from . import pubutil logger.debug("Shutting down SSE generators from main...") pubutil.server_shutdown = True except ImportError: pass raise