jw-python/tools/python/jwutils/Cmds.py

81 lines
2.9 KiB
Python
Raw Normal View History

import os
import sys
import argparse
import importlib
import inspect
import re
import pickle
import asyncio
import jwutils
from jwutils import log
class Cmds: # export
def __init__(self, description = '', filter = '^Cmd.*', modules=None, eloop=None):
self.__description = description
self.__filter = filter
self.__modules = modules
default_log_level = log.NOTICE
default_log_flags = 'stderr,position,prio,color'
# poor man's parsing in the absence of a complete command-line definition
for i in range(1, len(sys.argv)):
if i >= len(sys.argv) - 1:
break
arg = sys.argv[i]
if arg == '--log-level':
i += 1
default_log_level = sys.argv[i]
continue
if arg == '--log-flags':
default_log_flags = sys.argv[i]
continue
log.set_flags(default_log_flags)
log.set_level(default_log_level)
self.__parser = argparse.ArgumentParser(usage=os.path.basename(sys.argv[0]) + ' [command] [options]',
formatter_class=argparse.ArgumentDefaultsHelpFormatter, description=self.__description)
self.__parser.add_argument('--log-flags', help='Log flags', default=default_log_flags)
self.__parser.add_argument('--log-level', help='Log level', default=default_log_level)
self.eloop = eloop
self.__own_eloop = False
if eloop is None:
self.eloop = asyncio.get_event_loop()
self.__own_eloop = True
subparsers = self.__parser.add_subparsers(title='Available commands', metavar='')
if self.__modules == None:
self.__modules = [ '__main__' ]
for m in self.__modules:
if m != '__main__':
importlib.import_module(m)
for name, c in inspect.getmembers(sys.modules[m], inspect.isclass):
if not re.match(self.__filter, name):
continue
if inspect.isabstract(c):
continue
log.slog(log.DEBUG, 'instantiating command "{}"'.format(c))
cmd = c()
cmd.cmds = self
cmd.add_parser(subparsers)
async def __run(self):
args = self.__parser.parse_args()
log.set_flags(args.log_flags)
log.set_level(args.log_level)
return await args.func(args)
def __del__(self):
if self.__own_eloop:
if self.eloop is not None:
self.eloop.close()
self.eloop = None
self.__own_eloop = False
def parser():
return self.__parser
def run(self):
#return self.__run()
return self.eloop.run_until_complete(self.__run())
def run_sub_commands(description = '', filter = '^Cmd.*', modules=None): # export
cmds = Cmds(description, filter, modules)
return cmds.run()