Пример #1
0
 def _load_env(self, data, encoding):
     """Merge environment variables"""
     d = copy.copy(self.env)
     d.update([(to_unicode(k, encoding), to_unicode(v, encoding))
               for k, v in data.items()])
     self.env = d
     return self
Пример #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__)
Пример #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__)
Пример #4
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)
Пример #5
0
    def test_load_config(self):
        meta = Meta(to_unicode(os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources')))

        with self.withAssertOutput('Reading file: %s\n' % self._testfile('minimum.yml'), '') as (out, err):
            self.assertEqual(
                Setting(
                    config_path=self._testfile('minimum.yml'), encoding='utf-8', stdout=out, stderr=err
                ).load_config().root_menu,
                Menu('', [], meta)
            )
        path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'flat.yml')
        with self.withAssertOutput('Reading file: %s\n' % path, '') as (out, err):
            self.assertEqual(
                Setting(
                    config_path=self._testfile('flat.yml'), encoding='utf-8', stdout=out, stderr=err
                ).load_config().root_menu,
                Menu('Main Menu', [
                    Command('Menu 1', [CommandLine('echo 1', meta)]),
                    Command('Menu 2', [CommandLine('echo 2', meta)]),
                    Command('Menu 3', [CommandLine('echo 3', meta)]),
                    Command('Menu 4', [CommandLine('echo 4', meta)]),
                    Command('Menu 5', [CommandLine('echo 5', meta)]),
                    Command('Menu 6', [CommandLine('echo 6', meta)]),
                ], meta)
            )
Пример #6
0
    def test_load_config(self):
        meta = Meta(
            to_unicode(
                os.path.join(os.path.abspath(os.path.curdir), 'tests',
                             'resources')))

        with self.withAssertOutput(
                'Reading file: %s\n' % self._testfile('minimum.yml'),
                '') as (out, err):
            self.assertEqual(
                Setting(config_path=self._testfile('minimum.yml'),
                        encoding='utf-8',
                        stdout=out,
                        stderr=err).load_config().root_menu,
                Menu('', [], meta))
        path = os.path.join(os.path.abspath(os.path.curdir), 'tests',
                            'resources', 'flat.yml')
        with self.withAssertOutput('Reading file: %s\n' % path,
                                   '') as (out, err):
            self.assertEqual(
                Setting(config_path=self._testfile('flat.yml'),
                        encoding='utf-8',
                        stdout=out,
                        stderr=err).load_config().root_menu,
                Menu('Main Menu', [
                    Command('Menu 1', [CommandLine('echo 1', meta)]),
                    Command('Menu 2', [CommandLine('echo 2', meta)]),
                    Command('Menu 3', [CommandLine('echo 3', meta)]),
                    Command('Menu 4', [CommandLine('echo 4', meta)]),
                    Command('Menu 5', [CommandLine('echo 5', meta)]),
                    Command('Menu 6', [CommandLine('echo 6', meta)]),
                ], meta))
Пример #7
0
    def test_load_config_dynamic_cache(self):
        self.maxDiff = None

        meta = Meta(to_unicode(os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources')))
        path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'with_dynamic_cache.yml')

        cache_dir = os.path.join(os.path.curdir, 'tests', 'work')
        cache_path = os.path.join(cache_dir, '57', '8f2d1550c1fad02f46409db2b538c9')

        def clear_files():
            if os.path.exists(cache_path):
                os.remove(cache_path)
            if os.path.exists(os.path.dirname(cache_path)):
                os.removedirs(os.path.dirname(cache_path))
            if os.path.exists(cache_dir):
                os.removedirs(cache_dir)

        expect = '\n'.join([
            'Reading file: %s' % path,
            """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'""",
            'Writing eval cache: %s' % cache_path,
            'Reading file: %s' % path,
            'Reading eval cache: %s' % cache_path,
            ''
        ])

        clear_files()

        try:
            with self.withAssertOutput(expect, '') as (out, err):
                self.assertEqual(
                    Setting(
                        config_path=self._testfile('with_dynamic_cache.yml'), encoding='utf-8', stdout=out, stderr=err,
                        cache_dir=cache_dir
                    ).load_config().root_menu,
                    Menu('Main Menu', [
                        Command('Menu 1', [CommandLine('echo 1', meta)]),
                        Menu('Sub Menu', [
                            Command('Menu 2', [CommandLine('echo 2', meta)]),
                            Command('Menu 3', [CommandLine('echo 3', meta)]),
                        ], meta)
                    ], meta)
                )
                # read twice to use cache
                self.assertEqual(
                    Setting(
                        config_path=self._testfile('with_dynamic_cache.yml'), encoding='utf-8', stdout=out, stderr=err,
                        cache_dir=cache_dir
                    ).load_config().root_menu,
                    Menu('Main Menu', [
                        Command('Menu 1', [CommandLine('echo 1', meta)]),
                        Menu('Sub Menu', [
                            Command('Menu 2', [CommandLine('echo 2', meta)]),
                            Command('Menu 3', [CommandLine('echo 3', meta)]),
                        ], meta)
                    ], meta)
                )
        finally:
            clear_files()
Пример #8
0
    def parse_args(self, argv):
        assert self.now is not None

        # decode all args as utf-8
        option, args = arg_parser.parser.parse_args(
            [to_unicode(a, errors='ignore') for a in argv[1:]])

        try:
            if not args:
                # summary
                dt = oget(self._parse_date(option.date, self.now),
                          self.now.date())
                start_time = get_localzone().localize(
                    datetime(dt.year, dt.month, dt.day))

                fmt = (option.format
                       or (arg_parser.DEFAULT_FORMAT if option.days == 0 else
                           arg_parser.DEFAULT_FORMAT_DAYS))

                if option.days == 0:
                    # show events on one day
                    duration = timedelta(days=1)
                elif option.days < 0:
                    # show events from past several days
                    duration = timedelta(days=-option.days + 1)
                    start_time -= timedelta(days=-option.days)
                else:
                    # show events from several days from today
                    duration = timedelta(days=option.days + 1)

                operation = SummaryOperation(option.calendar, start_time,
                                             duration, option.credential, fmt,
                                             option.separator)
            elif args[0] == 'setup' and len(args) == 2:
                # setup
                operation = SetupOperation(args[1], option.credential,
                                           option.read_only, option.no_browser)
            elif args[0] == 'create' and len(args) >= 2:
                # create
                summary = ' '.join(args[1:])
                start, end = self._parse_time_range(option.date,
                                                    option.start_time,
                                                    option.end_time, self.now)
                ev = Event(start, end, summary, location=option.location)
                operation = CreateOperation(option.calendar, ev,
                                            option.credential)
            else:
                # help
                operation = HelpOperation()
        except Exception as e:
            # parse error
            operation = HelpOperation(e)
            if option.debug:
                import traceback
                traceback.print_exc()
                print()

        return self.copy(operation=operation, debug=option.debug)
Пример #9
0
    def _check_java_version(self):
        ret, stdout, stderr = capture_command([self.setting.java_setting.get_executable(), '-version'])
        assert ret == 0, 'Failed to get java version: ret=%d, stderr=%s' % (ret, stderr)

        first_line = ''.join(to_unicode(stderr).splitlines()[:1])
        m = re.compile(r"""java version \"(\d+[.]\d+)[.]\d+_\d+\"""").match(first_line)
        if m:
            actual = float(m.group(1))
        else:
            raise AssertionError('Unexpected java version: %s' % first_line)

        expect = self.setting.java_setting.version
        assert actual == expect, "Unexpected Java version: expect='%s', actual='%s'." % (expect, actual)
        return self
Пример #10
0
    def parse_args(self, argv):
        assert self.now is not None

        # decode all args as utf-8
        option, args = arg_parser.parser.parse_args([to_unicode(a, errors='ignore') for a in argv[1:]])

        try:
            if not args:
                # summary
                dt = oget(self._parse_date(option.date, self.now), self.now.date())
                start_time = get_localzone().localize(datetime(dt.year, dt.month, dt.day))

                fmt = (option.format or
                       (arg_parser.DEFAULT_FORMAT if option.days == 0 else arg_parser.DEFAULT_FORMAT_DAYS))

                if option.days == 0:
                    # show events on one day
                    duration = timedelta(days=1)
                elif option.days < 0:
                    # show events from past several days
                    duration = timedelta(days=-option.days + 1)
                    start_time -= timedelta(days=-option.days)
                else:
                    # show events from several days from today
                    duration = timedelta(days=option.days + 1)

                operation = SummaryOperation(option.calendar, start_time, duration,
                                             option.credential, fmt, option.separator)
            elif args[0] == 'setup' and len(args) == 2:
                # setup
                operation = SetupOperation(args[1], option.credential, option.read_only, option.no_browser)
            elif args[0] == 'create' and len(args) >= 2:
                # create
                summary = ' '.join(args[1:])
                start, end = self._parse_time_range(option.date, option.start_time, option.end_time, self.now)
                ev = Event(start, end, summary, location=option.location)
                operation = CreateOperation(option.calendar, ev, option.credential)
            else:
                # help
                operation = HelpOperation()
        except Exception as e:
            # parse error
            operation = HelpOperation(e)
            if option.debug:
                import traceback
                traceback.print_exc()
                print()

        return self.copy(operation=operation, debug=option.debug)
Пример #11
0
def print_safe(str_or_bytes, encoding='utf-8', errors='ignore', output=sys.stdout, newline='\n'):
    """
    Print unicode or bytes universally.

    :param str_or_bytes: string
    :param encoding: encoding
    :param output: output file handler
    :param errors: error handling scheme. Refer to codecs.register_error.
    """
    writer = output.buffer if hasattr(output, 'buffer') else output

    # When the input type is bytes, verify it can be decoded with the specified encoding.
    decoded = str_or_bytes if is_unicode(str_or_bytes) else to_unicode(str_or_bytes, encoding, errors)
    encoded = to_bytes(decoded, encoding, errors)

    writer.write(encoded + to_bytes(newline, encoding, errors))
    output.flush()
Пример #12
0
    def getch(self):
        """
        Read one character from stdin.

        If stdin is not a tty or set `getch_enabled`=False, read input as one line.
        :return: unicode:
        """
        ch = self._get_one_char()
        if self.keep_input_clean:
            self.clear_input_buffer()

        try:
            # accept only unicode characters (for Python 2)
            uch = to_unicode(ch, 'ascii')
        except UnicodeError:
            return ''

        return uch if self._check_key_repeat(uch) else ''
Пример #13
0
    def getch(self):
        """
        Read one character from stdin.

        If stdin is not a tty or set `getch_enabled`=False, read input as one line.
        :return: unicode:
        """
        ch = self._get_one_char()
        if self.keep_input_clean:
            self.clear_input_buffer()

        try:
            # accept only unicode characters (for Python 2)
            uch = to_unicode(ch, 'ascii')
        except UnicodeError:
            return ''

        return uch if self._check_key_repeat(uch) else ''
Пример #14
0
 def test_load_config_dynamic(self):
     meta = Meta(to_unicode(os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources')))
     path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'with_dynamic.yml')
     expect = '\n'.join([
         'Reading file: %s' % path,
         """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'\n"""
     ])
     with self.withAssertOutput(expect, '') as (out, err):
         self.assertEqual(
             Setting(
                 config_path=self._testfile('with_dynamic.yml'), encoding='utf-8', stdout=out, stderr=err
             ).load_config().root_menu,
             Menu('Main Menu', [
                 Command('Menu 1', [CommandLine('echo 1', meta)]),
                 Menu('Sub Menu', [
                     Command('Menu 2', [CommandLine('echo 2', meta)]),
                     Command('Menu 3', [CommandLine('echo 3', meta)]),
                 ], meta)
             ], meta)
         )
Пример #15
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__)
Пример #16
0
    def __init__(self, config_path=None, work_dir=None, root_menu=None, encoding=None, lang=None, width=None,
                 clear_cache=False, cache_dir=EVAL_CACHE_DIR, pid_dir=COMMAND_PID_DIR,
                 stdin=None, stdout=None, stderr=None, getch_enabled=True, source_enabled=True):
        is_url = Loader.is_url(config_path)
        work_dir = omap(lambda s: to_unicode(s, encoding), self._search_work_dir(work_dir, config_path, is_url))

        CaseClass.__init__(self,
                           ('config_path', config_path),
                           ('work_dir', work_dir),
                           ('root_menu', oget(root_menu, {})),
                           ('encoding', encoding),
                           ('lang', self._find_lang(lang)),
                           ('width', width),
                           ('clear_cache', clear_cache),
                           ('cache_dir', cache_dir),
                           ('pid_dir', pid_dir),
                           ('stdin', oget(stdin, sys.stdin)),
                           ('stdout', oget(stdout, sys.stdout)),
                           ('stderr', oget(stderr, sys.stderr)),
                           ('getch_enabled', getch_enabled),
                           ('source_enabled', source_enabled)
                           )
Пример #17
0
def print_safe(str_or_bytes,
               encoding='utf-8',
               errors='ignore',
               output=sys.stdout,
               newline='\n'):
    """
    Print unicode or bytes universally.

    :param str_or_bytes: string
    :param encoding: encoding
    :param output: output file handler
    :param errors: error handling scheme. Refer to codecs.register_error.
    """
    writer = output.buffer if hasattr(output, 'buffer') else output

    # When the input type is bytes, verify it can be decoded with the specified encoding.
    decoded = str_or_bytes if is_unicode(str_or_bytes) else to_unicode(
        str_or_bytes, encoding, errors)
    encoded = to_bytes(decoded, encoding, errors)

    writer.write(encoded + to_bytes(newline, encoding, errors))
    output.flush()
Пример #18
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__)
Пример #19
0
 def test_load_config_dynamic(self):
     meta = Meta(
         to_unicode(
             os.path.join(os.path.abspath(os.path.curdir), 'tests',
                          'resources')))
     path = os.path.join(os.path.abspath(os.path.curdir), 'tests',
                         'resources', 'with_dynamic.yml')
     expect = '\n'.join([
         'Reading file: %s' % path,
         """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'\n"""
     ])
     with self.withAssertOutput(expect, '') as (out, err):
         self.assertEqual(
             Setting(config_path=self._testfile('with_dynamic.yml'),
                     encoding='utf-8',
                     stdout=out,
                     stderr=err).load_config().root_menu,
             Menu('Main Menu', [
                 Command('Menu 1', [CommandLine('echo 1', meta)]),
                 Menu('Sub Menu', [
                     Command('Menu 2', [CommandLine('echo 2', meta)]),
                     Command('Menu 3', [CommandLine('echo 3', meta)]),
                 ], meta)
             ], meta))
Пример #20
0
    def test_load_config_dynamic_cache(self):
        self.maxDiff = None

        meta = Meta(
            to_unicode(
                os.path.join(os.path.abspath(os.path.curdir), 'tests',
                             'resources')))
        path = os.path.join(os.path.abspath(os.path.curdir), 'tests',
                            'resources', 'with_dynamic_cache.yml')

        cache_dir = os.path.join(os.path.curdir, 'tests', 'work')
        cache_path = os.path.join(cache_dir, '57',
                                  '8f2d1550c1fad02f46409db2b538c9')

        def clear_files():
            if os.path.exists(cache_path):
                os.remove(cache_path)
            if os.path.exists(os.path.dirname(cache_path)):
                os.removedirs(os.path.dirname(cache_path))
            if os.path.exists(cache_dir):
                os.removedirs(cache_dir)

        expect = '\n'.join([
            'Reading file: %s' % path,
            """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'""",
            'Writing eval cache: %s' % cache_path,
            'Reading file: %s' % path,
            'Reading eval cache: %s' % cache_path, ''
        ])

        clear_files()

        try:
            with self.withAssertOutput(expect, '') as (out, err):
                self.assertEqual(
                    Setting(
                        config_path=self._testfile('with_dynamic_cache.yml'),
                        encoding='utf-8',
                        stdout=out,
                        stderr=err,
                        cache_dir=cache_dir).load_config().root_menu,
                    Menu('Main Menu', [
                        Command('Menu 1', [CommandLine('echo 1', meta)]),
                        Menu('Sub Menu', [
                            Command('Menu 2', [CommandLine('echo 2', meta)]),
                            Command('Menu 3', [CommandLine('echo 3', meta)]),
                        ], meta)
                    ], meta))
                # read twice to use cache
                self.assertEqual(
                    Setting(
                        config_path=self._testfile('with_dynamic_cache.yml'),
                        encoding='utf-8',
                        stdout=out,
                        stderr=err,
                        cache_dir=cache_dir).load_config().root_menu,
                    Menu('Main Menu', [
                        Command('Menu 1', [CommandLine('echo 1', meta)]),
                        Menu('Sub Menu', [
                            Command('Menu 2', [CommandLine('echo 2', meta)]),
                            Command('Menu 3', [CommandLine('echo 3', meta)]),
                        ], meta)
                    ], meta))
        finally:
            clear_files()
Пример #21
0
 def test_to_unicode(self):
     self.assertEqual(string.to_unicode(b'abc'), 'abc')
     self.assertEqual(string.to_unicode('あいう'), 'あいう')
     self.assertEqual(string.to_unicode(1.23), '1.23')
Пример #22
0
 def _load_work_dir(self, data, encoding):
     """Overwrite working directory"""
     self.work_dir = to_unicode(data, encoding)
     return self
Пример #23
0
 def f(s):
     return to_unicode(s, encoding)
Пример #24
0
 def _load_env(self, data, encoding):
     """Merge environment variables"""
     d = copy.copy(self.env)
     d.update([(to_unicode(k, encoding), to_unicode(v, encoding)) for k, v in data.items()])
     self.env = d
     return self
Пример #25
0
 def _load_work_dir(self, data, encoding):
     """Overwrite working directory"""
     self.work_dir = to_unicode(data, encoding)
     return self
Пример #26
0
 def f(s):
     return to_unicode(s, encoding)
Пример #27
0
 def test_to_unicode(self):
     self.assertEqual(string.to_unicode(b'abc'), 'abc')
     self.assertEqual(string.to_unicode('あいう'), 'あいう')
     self.assertEqual(string.to_unicode(1.23), '1.23')