Example #1
0
    def parse(data, meta, loader, encoding='utf-8', depth=0):
        """
        :param data:
        :param meta:
        :param loader:
        :param encoding:
        :param depth:
        :return:
        """
        from easy_menu.entity import KEYWORD_META, Item

        # read meta configurations
        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)
Example #2
0
    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 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__)
Example #3
0
    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 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__)
Example #4
0
    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:
        """
        from easy_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:
            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)
Example #5
0
    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:
        """
        from easy_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:
            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)
Example #6
0
    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 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
Example #7
0
    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:
        """
        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__)
Example #8
0
    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 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
Example #9
0
    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:
        """
        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__)