diff options
author | Rob Crittenden <rcritten@redhat.com> | 2009-07-10 16:43:47 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2009-07-10 16:44:22 -0400 |
commit | 0e29dd7226119e69f3bf123395251140ad4260ca (patch) | |
tree | 68f423b62a64b2fecc692eb6b95af945c2597e21 | |
parent | e31d5fb1cfc7b7b2ed47202e0ef1c462f01a046b (diff) | |
download | freeipa-0e29dd7226119e69f3bf123395251140ad4260ca.tar.gz freeipa-0e29dd7226119e69f3bf123395251140ad4260ca.tar.xz freeipa-0e29dd7226119e69f3bf123395251140ad4260ca.zip |
Add textui function to display and prompt user for selection for *-find.
Since we may end up executing a *-show when an entry is selected we need
to defer destroying the connection context.
-rw-r--r-- | ipalib/backend.py | 4 | ||||
-rw-r--r-- | ipalib/cli.py | 70 |
2 files changed, 66 insertions, 8 deletions
diff --git a/ipalib/backend.py b/ipalib/backend.py index 0c93b16e6..da7fc2922 100644 --- a/ipalib/backend.py +++ b/ipalib/backend.py @@ -102,6 +102,9 @@ class Executioner(Backend): else: self.Backend.xmlclient.connect() + def destroy_context(self): + destroy_context() + def execute(self, _name, *args, **options): error = None try: @@ -115,7 +118,6 @@ class Executioner(Backend): 'non-public: %s: %s', e.__class__.__name__, str(e) ) error = InternalError() - destroy_context() if error is None: return result assert isinstance(error, PublicError) diff --git a/ipalib/cli.py b/ipalib/cli.py index 6dc0c0682..df0cd37ca 100644 --- a/ipalib/cli.py +++ b/ipalib/cli.py @@ -422,6 +422,59 @@ class textui(backend.Backend): print '' self.print_error(_('Cancelled.')) + def select_entry(self, entries, format, attrs, display_count=True): + """ + Display a list of lines in with formatting defined in ``format``. + ``attrs`` is a list of attributes in the format. + + Prompt user for a selection and return the value (index of + ``entries`` -1). + + If only one entry is provided then always return 0. + + Return: 0..n for the index of the selected entry + -1 if all entries should be displayed + -2 to quit, no entries to be displayed + """ + if not self.env.interactive or not sys.stdout.isatty(): + return -1 + + counter = len(entries) + i = 1 + for e in entries: + # There is no guarantee that all attrs are in any given + # entry + d = {} + for a in attrs: + d[a] = e.get(a, '') + self.print_line("%d: %s" % (i, format % d)) + i = i + 1 + + if display_count: + self.print_count(entries, 'Found %d match', 'Found %d matches') + + while True: + try: + resp = self.prompt("Choose one: (1 - %s), a for all, q to quit" % counter) + except EOFError: + return -2 + + if resp.lower() == "q": + return -2 + if resp.lower() == "a": + return -1 + try: + selection = int(resp) - 1 + if (selection >= 0 and selection < counter): + break + except: + # fall through to the error msg + pass + + self.print_line("Please enter a number between 1 and %s" % counter) + + self.print_line('') + return selection class help(frontend.Command): """ @@ -630,13 +683,16 @@ class cli(backend.Executioner): kw = self.parse(cmd, argv) if self.env.interactive: self.prompt_interactively(cmd, kw) - result = self.execute(name, **kw) - if callable(cmd.output_for_cli): - for param in cmd.params(): - if param.password and param.name in kw: - del kw[param.name] - (args, options) = cmd.params_2_args_options(**kw) - cmd.output_for_cli(self.api.Backend.textui, result, *args, **options) + try: + result = self.execute(name, **kw) + if callable(cmd.output_for_cli): + for param in cmd.params(): + if param.password and param.name in kw: + del kw[param.name] + (args, options) = cmd.params_2_args_options(**kw) + cmd.output_for_cli(self.api.Backend.textui, result, *args, **options) + finally: + self.destroy_context() def parse(self, cmd, argv): parser = self.build_parser(cmd) |