98 lines
2.0 KiB
Python
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)
|