MrDraw/src/octoprint/cli/__init__.py

151 lines
5.1 KiB
Python

# coding=utf-8
from __future__ import absolute_import
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms of the AGPLv3 License"
import click
import octoprint
#~~ click context
class OctoPrintContext(object):
"""Custom context wrapping the standard options."""
def __init__(self, configfile=None, basedir=None, verbosity=0):
self.configfile = configfile
self.basedir = basedir
self.verbosity = verbosity
pass_octoprint_ctx = click.make_pass_decorator(OctoPrintContext, ensure=True)
"""Decorator to pass in the :class:`OctoPrintContext` instance."""
#~~ Custom click option to hide from help
class HiddenOption(click.Option):
"""Custom option sub class with empty help."""
def get_help_record(self, ctx):
pass
def hidden_option(*param_decls, **attrs):
"""Attaches a hidden option to the command. All positional arguments are
passed as parameter declarations to :class:`Option`; all keyword
arguments are forwarded unchanged. This is equivalent to creating an
:class:`Option` instance manually and attaching it to the
:attr:`Command.params` list.
"""
import inspect
from click.decorators import _param_memo
def decorator(f):
if 'help' in attrs:
attrs['help'] = inspect.cleandoc(attrs['help'])
_param_memo(f, HiddenOption(param_decls, **attrs))
return f
return decorator
#~~ helper for settings context options
def set_ctx_obj_option(ctx, param, value):
"""Helper for setting eager options on the context."""
if ctx.obj is None:
ctx.obj = OctoPrintContext()
if hasattr(ctx.obj, param.name):
setattr(ctx.obj, param.name, value)
#~~ helper for setting a lot of bulk options
def bulk_options(options):
"""
Utility decorator to decorate a function with a list of click decorators.
The provided list of ``options`` will be reversed to ensure correct
processing order (inverse from what would be intuitive).
"""
def decorator(f):
options.reverse()
for option in options:
option(f)
return f
return decorator
#~~ helper for setting --basedir, --config and --verbose options
def standard_options(hidden=False):
"""
Decorator to add the standard options shared among all "octoprint" commands.
Adds the options ``--basedir``, ``--config`` and ``--verbose``. If ``hidden``
is set to ``True``, the options will be available on the command but not
listed in its help page.
"""
factory = click.option
if hidden:
factory = hidden_option
options = [
factory("--basedir", "-b", type=click.Path(), callback=set_ctx_obj_option, is_eager=True, expose_value=False,
help="Specify the basedir to use for uploads, timelapses etc."),
factory("--config", "-c", "configfile", type=click.Path(), callback=set_ctx_obj_option, is_eager=True, expose_value=False,
help="Specify the config file to use."),
factory("--verbose", "-v", "verbosity", count=True, callback=set_ctx_obj_option, is_eager=True, expose_value=False,
help="Increase logging verbosity"),
]
return bulk_options(options)
#~~ helper for settings legacy options we still have to support on "octoprint"
legacy_options = bulk_options([
hidden_option("--host", type=click.STRING),
hidden_option("--port", type=click.INT),
hidden_option("--logging", type=click.Path()),
hidden_option("--debug", "-d", is_flag=True),
hidden_option("--daemon", type=click.Choice(["start", "stop", "restart"])),
hidden_option("--pid", type=click.Path(), default="/tmp/octoprint.pid"),
hidden_option("--iknowwhatimdoing", "allow_root", is_flag=True),
])
"""Legacy options available directly on the "octoprint" command in earlier versions.
Kept available for reasons of backwards compatibility, but hidden from the
generated help pages."""
#~~ "octoprint" command, merges server_commands and plugin_commands groups
from .server import server_commands
from .plugins import plugin_commands
from .dev import dev_commands
from .client import client_commands
@click.group(name="octoprint", invoke_without_command=True, cls=click.CommandCollection,
sources=[server_commands, plugin_commands, dev_commands, client_commands])
@standard_options()
@legacy_options
@click.version_option(version=octoprint.__version__)
@click.pass_context
def octo(ctx, debug, host, port, logging, daemon, pid, allow_root):
if ctx.invoked_subcommand is None:
# We have to support calling the octoprint command without any
# sub commands to remain backwards compatible.
#
# But better print a message to inform people that they should
# use the sub commands instead.
if daemon:
click.echo("Daemon operation via \"octoprint --daemon "
"start|stop|restart\" is deprecated, please use "
"\"octoprint daemon start|stop|restart\" from now on")
from octoprint.cli.server import daemon_command
ctx.invoke(daemon_command, debug=debug, pid=pid, daemon=daemon, allow_root=allow_root)
else:
click.echo("Starting the server via \"octoprint\" is deprecated, "
"please use \"octoprint serve\" from now on.")
from octoprint.cli.server import serve_command
ctx.invoke(serve_command, debug=debug, host=host, port=port, logging=logging, allow_root=allow_root)