vultron/vultron/cmd.py

98 lines
2.0 KiB
Python

import os
import vultron.api
class CmdNotFound(Exception):
def __str__(self):
return f"error: command not found: {self.args[0]}"
class NoApiKey(Exception):
# FIXME: __str__ message
pass
class FeatureMissing(Exception):
# FIXME: __str__ message
pass
# FIXME: Move command execution into Command class, so wrapper can do pre/post
# work.
class Command:
"""A nop Vultron command. This feature is not implemented yet."""
FTR_PRFX = "vultron_"
def __init__(self, prog, api_key, out):
self.prog = prog
self.out = out
self.uses_api = True
self.default = "help"
self.init()
if self.uses_api and api_key is None:
raise NoApiKey()
self.api = vultron.api.Client(api_key)
def init(self):
pass
def find(self, name):
needle = f"{self.FTR_PRFX}{name}".lower()
haystack = dir(self)
for legume in haystack:
if legume.lower().startswith(needle):
fn = getattr(self, legume)
if callable(fn):
return fn
else:
raise FeatureMissing(legume)
raise CmdNotFound(name)
def vultron_help(self, *args):
"""This help message."""
prog = os.path.basename(self.prog)
cmd = type(self).__name__.lower()
subs = dir(self)
print(f"usage: {prog} [options] {cmd} <sub-command>")
print()
print("About:")
if self.__doc__ is None:
print(Command.__doc__)
else:
print(self.__doc__)
print()
# FIXME: print global options here
print("Sub-commands:")
for sub in subs:
name = sub.lower()
if name.startswith(self.FTR_PRFX):
name = name[len(self.FTR_PRFX):]
fn = getattr(self, sub)
if callable(fn):
desc = name
if fn.__doc__ is not None:
desc += f" - {fn.__doc__}"
print(f"\t{desc}")
def find_cmd(needle):
needle = needle.lower()
haystack = Command.__subclasses__()
for legume in haystack:
if legume.__name__.lower().startswith(needle):
return legume
raise CmdNotFound(needle)