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
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__)
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__)
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)
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) )
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))
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()
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)
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
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)
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()
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 ''
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) )
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__)
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) )
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()
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__)
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))
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()
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')
def _load_work_dir(self, data, encoding): """Overwrite working directory""" self.work_dir = to_unicode(data, encoding) return self
def f(s): return to_unicode(s, encoding)