class batch(Command): NO_CLI = True takes_args = ( Any('methods*', doc=_('Nested Methods to execute'), ), ) take_options = ( Str('version', cli_name='version', doc=_('Client version. Used to determine if server will accept request.'), exclude='webui', flags=['no_option', 'no_output'], default=API_VERSION, autofill=True, ), ) has_output = ( Output('count', int, doc=''), Output('results', (list, tuple), doc='') ) def execute(self, *args, **options): results = [] for arg in args[0]: params = dict() name = None try: if 'method' not in arg: raise errors.RequirementError(name='method') if 'params' not in arg: raise errors.RequirementError(name='params') name = arg['method'] if name not in self.Command: raise errors.CommandError(name=name) a, kw = arg['params'] newkw = dict((str(k), v) for k, v in kw.items()) params = api.Command[name].args_options_2_params(*a, **newkw) newkw.setdefault('version', options['version']) result = api.Command[name](*a, **newkw) self.info( '%s: batch: %s(%s): SUCCESS', context.principal, name, ', '.join(api.Command[name]._repr_iter(**params)) ) result['error']=None except Exception as e: if isinstance(e, errors.RequirementError) or \ isinstance(e, errors.CommandError): self.info( '%s: batch: %s', context.principal, # pylint: disable=no-member e.__class__.__name__ ) else: self.info( '%s: batch: %s(%s): %s', context.principal, name, # pylint: disable=no-member ', '.join(api.Command[name]._repr_iter(**params)), e.__class__.__name__ ) if isinstance(e, errors.PublicError): reported_error = e else: reported_error = errors.InternalError() result = dict( error=reported_error.strerror, error_code=reported_error.errno, error_name=unicode(type(reported_error).__name__), ) results.append(result) return dict(count=len(results) , results=results)
class help(frontend.Local): """ Display help for a command or topic. """ class Writer(object): """ Writer abstraction """ def __init__(self, outfile): self.outfile = outfile self.buffer = [] @property def buffer_length(self): length = 0 for line in self.buffer: length += len(line.split("\n")) return length def append(self, string=u""): self.buffer.append(unicode(string)) def write(self): if self.buffer_length > get_terminal_height(): data = "\n".join(self.buffer).encode("utf-8") open_in_pager(data) else: try: for line in self.buffer: print(line, file=self.outfile) except IOError: pass takes_args = ( Str('command?', cli_name='topic', label=_('Topic or Command'), doc=_('The topic or command name.')), ) takes_options = ( Any('outfile?', flags=['no_option']), ) has_output = tuple() topic = None def _get_topic(self, topic): doc = u'' parent_topic = None for package in self.api.packages: module_name = '{0}.{1}'.format(package.__name__, topic) try: module = sys.modules[module_name] except KeyError: try: module = importlib.import_module(module_name) except ImportError: continue if module.__doc__ is not None: doc = unicode(module.__doc__ or '').strip() try: parent_topic = module.topic except AttributeError: pass return doc, parent_topic def _count_topic_mcl(self, topic_name, mod_name): mcl = max((self._topics[topic_name][1], len(mod_name))) self._topics[topic_name][1] = mcl def _on_finalize(self): # {topic: ["description", mcl, { # "subtopic": ["description", mcl, [commands]]}]} # {topic: ["description", mcl, [commands]]} self._topics = {} # [builtin_commands] self._builtins = [] # build help topics for c in self.api.Command: if c is not self.api.Command.get_plugin(c.name): continue if c.NO_CLI: continue if c.topic is not None: doc, topic_name = self._get_topic(c.topic) doc = doc.split('\n', 1)[0] if topic_name is None: # a module without grouping topic_name = c.topic if topic_name in self._topics: self._topics[topic_name][2].append(c) else: self._topics[topic_name] = [doc, 0, [c]] mcl = max((self._topics[topic_name][1], len(c.name))) self._topics[topic_name][1] = mcl else: # a module grouped in a topic topic = self._get_topic(topic_name) mod_name = c.topic if topic_name in self._topics: if mod_name in self._topics[topic_name][2]: self._topics[topic_name][2][mod_name][2].append(c) else: self._topics[topic_name][2][mod_name] = [ doc, 0, [c]] self._count_topic_mcl(topic_name, mod_name) # count mcl for for the subtopic mcl = max(( self._topics[topic_name][2][mod_name][1], len(c.name))) self._topics[topic_name][2][mod_name][1] = mcl else: self._topics[topic_name] = [ topic[0].split('\n', 1)[0], 0, {mod_name: [doc, 0, [c]]}] self._count_topic_mcl(topic_name, mod_name) else: self._builtins.append(c) # compute maximum topic length topics = list(self._topics) + [c.name for c in self._builtins] self._mtl = max(len(s) for s in topics) super(help, self)._on_finalize() def run(self, key=None, outfile=None, **options): if outfile is None: outfile = sys.stdout writer = self.Writer(outfile) name = from_cli(key) if key is None: self.api.parser.print_help(outfile) return if name == "topics": self.print_topics(outfile) return if name in self._topics: self.print_commands(name, outfile) elif name in self.Command: cmd = self.Command[name] if cmd.NO_CLI: raise HelpError(topic=name) self.Backend.cli.build_parser(cmd).print_help(outfile) elif any(name in t[2] for t in self._topics.values() if type(t[2]) is dict): self.print_commands(name, outfile) elif name == "commands": mcl = 0 for cmd_plugin in self.Command: if cmd_plugin is not self.Command.get_plugin(cmd_plugin.name): continue if cmd_plugin.NO_CLI: continue mcl = max(mcl, len(cmd_plugin.name)) writer.append('{0} {1}'.format( to_cli(cmd_plugin.name).ljust(mcl), cmd_plugin.summary)) else: raise HelpError(topic=name) writer.write() def print_topics(self, outfile): writer = self.Writer(outfile) for t, topic in sorted(self._topics.items()): writer.append('{0} {1}'.format( to_cli(t).ljust(self._mtl), topic[0])) writer.write() def print_commands(self, topic, outfile): writer = self.Writer(outfile) if topic in self._topics and type(self._topics[topic][2]) is dict: # we want to display topic which has subtopics for subtopic in self._topics[topic][2]: doc = self._topics[topic][2][subtopic][0] mcl = self._topics[topic][1] writer.append(' {0} {1}'.format( to_cli(subtopic).ljust(mcl), doc)) else: # we want to display subtopic or a topic which has no subtopics if topic in self._topics: mcl = self._topics[topic][1] commands = self._topics[topic][2] else: commands = [] for t in self._topics: if type(self._topics[t][2]) is not dict: continue if topic not in self._topics[t][2]: continue mcl = self._topics[t][2][topic][1] commands = self._topics[t][2][topic][2] break doc, _topic = self._get_topic(topic) if topic not in self.Command and len(commands) == 0: raise HelpError(topic=topic) writer.append(doc) if commands: writer.append() writer.append(_('Topic commands:')) for c in commands: writer.append( ' {0} {1}'.format( to_cli(c.name).ljust(mcl), c.summary)) writer.append() writer.append(_('To get command help, use:')) writer.append(_(' ipa <command> --help')) writer.append() writer.write()
class help(frontend.Local): """ Display help for a command or topic. """ takes_args = (Str('command?', cli_name='topic', label=_('Topic or Command'), doc=_('The topic or command name.')), ) takes_options = (Any('outfile?', flags=['no_option']), ) has_output = tuple() _PLUGIN_BASE_MODULE = 'ipalib.plugins' def _get_command_module(self, module): """ Return last part of ``module`` name, or ``None`` if module is this file. For example: """ if module == __name__: return return module.split('.')[-1] def _get_module_topic(self, module_name): if not sys.modules[module_name]: __import__(module_name) module = sys.modules[module_name] topic = getattr(module, 'topic', None) if topic is None: topic = (self._get_command_module(module_name), None) return topic def _count_topic_mcl(self, topic_name, mod_name): mcl = max((self._topics[topic_name][1], len(mod_name))) self._topics[topic_name][1] = mcl def _on_finalize(self): # {topic: ["description", mcl, {"subtopic": ["description", mcl, [commands]]}]} # {topic: ["description", mcl, [commands]]} self._topics = {} # [builtin_commands] self._builtins = [] # build help topics for c in self.api.Command(): if c.NO_CLI: continue topic = self._get_module_topic(c.module) topic_name = topic[0] if topic_name: if topic[1] is None: # a module without grouping if topic_name in self._topics: self._topics[topic_name][2].append(c) else: m = '%s.%s' % (self._PLUGIN_BASE_MODULE, topic_name) try: module = sys.modules[m] except KeyError: doc = '' else: doc = (unicode(_(module.__doc__)) or '').strip().split('\n', 1)[0] self._topics[topic_name] = [doc, 0, [c]] mcl = max((self._topics[topic_name][1], len(c.name))) self._topics[topic_name][1] = mcl else: # a module grouped in a topic doc = (unicode(_(sys.modules[c.module].__doc__)) or '').strip().split('\n', 1)[0] mod_name = c.module.rsplit('.', 1)[1] if topic_name in self._topics: if mod_name in self._topics[topic_name][2]: self._topics[topic_name][2][mod_name][2].append(c) else: self._topics[topic_name][2][mod_name] = [ doc, 0, [c] ] self._count_topic_mcl(topic_name, mod_name) # count mcl for for the subtopic mcl = max((self._topics[topic_name][2][mod_name][1], len(c.name))) self._topics[topic_name][2][mod_name][1] = mcl else: self._topics[topic_name] = [ unicode(_(topic[1])), 0, { mod_name: [doc, 0, [c]] } ] self._count_topic_mcl(topic_name, mod_name) else: self._builtins.append(c) # compute maximum topic length topics = list(self._topics) + [c.name for c in self._builtins] self._mtl = max(len(s) for s in topics) super(help, self)._on_finalize() def run(self, key, outfile=None, **options): if outfile is None: outfile = sys.stdout writer = self._writer(outfile) name = from_cli(key) mod_name = '%s.%s' % (self._PLUGIN_BASE_MODULE, name) if key is None: self.api.parser.print_help(outfile) return if name == "topics": self.print_topics(outfile) return if name in self._topics: self.print_commands(name, outfile) elif name in self.Command: cmd = self.Command[name] if cmd.NO_CLI: raise HelpError(topic=name) self.Backend.cli.build_parser(cmd).print_help(outfile) elif mod_name in sys.modules: self.print_commands(name, outfile) elif name == "commands": mcl = max(len(s) for s in (self.Command)) for cname in self.Command: cmd = self.Command[cname] if cmd.NO_CLI: continue writer('%s %s' % (to_cli(cmd.name).ljust(mcl), cmd.summary)) else: raise HelpError(topic=name) def _writer(self, outfile): def writer(string=''): try: print(unicode(string), file=outfile) except IOError: pass return writer def print_topics(self, outfile): writer = self._writer(outfile) for t, topic in sorted(self._topics.items()): writer('%s %s' % (to_cli(t).ljust(self._mtl), topic[0])) def print_commands(self, topic, outfile): writer = self._writer(outfile) if topic in self._topics and type(self._topics[topic][2]) is dict: # we want to display topic which has subtopics for subtopic in self._topics[topic][2]: doc = self._topics[topic][2][subtopic][0] mcl = self._topics[topic][1] writer(' %s %s' % (to_cli(subtopic).ljust(mcl), doc)) else: # we want to display subtopic or a topic which has no subtopics if topic in self._topics: mcl = self._topics[topic][1] commands = self._topics[topic][2] else: commands = [] for t in self._topics: if type(self._topics[t][2]) is not dict: continue if topic not in self._topics[t][2]: continue mcl = self._topics[t][2][topic][1] commands = self._topics[t][2][topic][2] break m = '%s.%s' % (self._PLUGIN_BASE_MODULE, topic) doc = (unicode(_(sys.modules[m].__doc__)) or '').strip() if topic not in self.Command and len(commands) == 0: raise HelpError(topic=topic) writer(doc) if commands: writer() writer(_('Topic commands:')) for c in commands: writer(' %s %s' % (to_cli(c.name).ljust(mcl), c.summary)) writer() writer(_('To get command help, use:')) writer(_(' ipa <command> --help')) writer()