def parse(data, meta, loader, encoding='utf-8', depth=0): """ Parse one command operation. :param data: dict: :param meta: Meta: meta configuration inherited from the parent menu :param loader: not used :param encoding: string: :param depth: not used :return: Command: """ if (DEBUG): print( 'entity.command.py - Command -parse(data,meta,loader,encoding,depth) - caller:' + str(inspect.stack()[1][3])) if len(data) != 1: raise ValueError('Command should have only one element, not %s.' % len(data)) title, content = get_single_item(data) assert isinstance( title, six.string_types ), 'Command title must be string, not %s' % type(title).__name__ title = to_unicode(title, encoding) if isinstance(content, six.string_types): # single command return Command(title, [CommandLine.parse(content, meta, encoding)]) elif isinstance(content, list): # command list return Command( title, [CommandLine.parse(d, meta, encoding) for d in content]) else: raise ValueError('Invalid command content type: %s' % type(content).__name__)
def parse(data, meta, encoding='utf-8'): """ Parse one command line. :param data: string or dict: :param meta: Meta: meta configuration inherited from the parent menu :param encoding: string: :return: CommandLine: """ if (DEBUG): print('entity.command_line.py CommandLine- parse()- caller:' + str(inspect.stack()[1][3])) assert isinstance(meta, Meta) def f(s): return to_unicode(s, encoding) if is_strlike(data): return CommandLine(f(data), meta, encoding) elif isinstance(data, dict): cmd, params = get_single_item(data) assert is_strlike( cmd), 'cmd must be string, not %s.' % type(cmd).__name__ new_meta = meta.updated(params, encoding) return CommandLine(to_unicode(cmd, encoding), new_meta, encoding) else: raise ValueError('CommandLine must be string or dict, not %s.' % type(data).__name__)
def _is_command_like(content): """ We assume the data is command when it is a string or one-element dict which contains string key and dict value :param content: object to parse :return: true when the data is command-like """ if (DEBUG): print('entity.item.py - Item - _is_command_like()- caller:' + str(inspect.stack()[1][3])) if isinstance(content, six.string_types): return True if isinstance(content, list): for item in content: ok = False if isinstance(item, six.string_types): ok = True if isinstance(item, dict) and len(item) == 1: cmd, attr = get_single_item(item) ok = isinstance(cmd, six.string_types) and isinstance( attr, dict) if not ok: return False return True return False
def parse(data, meta, loader, encoding='utf-8', depth=0): """ :param data: :param meta: :param loader: :param encoding: :param depth: indicator for the nesting level :return: """ if (DEBUG): print('entity.item.py - Item - parse()- caller:' + str(inspect.stack()[1][3])) from devops_menu.entity import Menu, Command, KEYWORD_META, KEYWORD_INCLUDE, KEYWORD_EVAL # avoid for inclusion loops and stack overflow assert depth < 50, 'Nesting level too deep.' # if the data has meta key, it should be a menu. if KEYWORD_META in data: print("\t" + 'found meta keywork in data') return Menu.parse(data, meta, loader, encoding, depth) # parse eval cache setting eval_expire = None if KEYWORD_EVAL in data: if 'cache' in data: eval_expire = data['cache'] del data['cache'] assert len( data ) == 1, 'Item should have only one element, not %s.' % len(data) title, content = get_single_item(data) if title == KEYWORD_INCLUDE: assert isinstance(content, six.string_types), \ '"include" section must have string content, not %s.' % type(content).__name__ return Menu.parse(loader.load(False, content), meta, loader, encoding, depth) elif title == KEYWORD_EVAL: assert isinstance(content, six.string_types), \ '"eval" section must have string content, not %s.' % type(content).__name__ return Menu.parse(loader.load(True, content, eval_expire), meta, loader, encoding, depth) elif Item._is_command_like(content): return Command.parse(data, meta, loader, encoding, depth) else: return Menu.parse(data, meta, loader, encoding, depth)
def parse(data, meta, loader, encoding='utf-8', depth=0): """ :param data: :param meta: :param loader: :param encoding: :param depth: :return: """ if (DEBUG): print('entity.menu.py - Menu - parse()- caller:' + str(inspect.stack()[1][3])) from devops_menu.entity import KEYWORD_META, Item if (DEBUG): print('read meta configurations') print(data) if KEYWORD_META in data: meta = meta.updated(data[KEYWORD_META], encoding) del data[KEYWORD_META] assert len( data) == 1, 'Menu should have only one item, not %s.' % len(data) title, content = get_single_item(data) assert isinstance( title, six.string_types ), 'Menu title must be string, not %s.' % type(title).__name__ assert isinstance( content, list ), 'Menu content must be list, not %s.' % type(content).__name__ title = to_unicode(title, encoding) items = [ Item.parse(item, meta, loader, encoding, depth + 1) for item in content ] return Menu(title, items, meta)