Add prompt_param method to avoid code duplication

Extracted common code from ipalib/plugins/cli.py and
ipalib/plugins/dns.py that provided way to prompt user
for the value of specific attribute.

Added prompt_param method to Command class in ipalib/frontend.py

Done as part of https://fedorahosted.org/freeipa/ticket/3602
This commit is contained in:
Tomas Babej
2013-06-05 12:50:29 +02:00
committed by Martin Kosek
parent 8984e3e105
commit 89ffaf411d
3 changed files with 54 additions and 41 deletions
+12 -13
View File
@@ -1178,11 +1178,13 @@ class cli(backend.Executioner):
``self.env.prompt_all`` is ``True``, this method will prompt for any ``self.env.prompt_all`` is ``True``, this method will prompt for any
params that have a missing values, even if the param is optional. params that have a missing values, even if the param is optional.
""" """
honor_alwaysask = True honor_alwaysask = True
for param in cmd.params(): for param in cmd.params():
if param.alwaysask and param.name in kw: if param.alwaysask and param.name in kw:
honor_alwaysask = False honor_alwaysask = False
break break
for param in cmd.params(): for param in cmd.params():
if (param.required and param.name not in kw) or \ if (param.required and param.name not in kw) or \
(param.alwaysask and honor_alwaysask) or self.env.prompt_all: (param.alwaysask and honor_alwaysask) or self.env.prompt_all:
@@ -1196,19 +1198,16 @@ class cli(backend.Executioner):
) )
else: else:
default = cmd.get_default_of(param.name, **kw) default = cmd.get_default_of(param.name, **kw)
error = None optional = param.alwaysask or not param.required
while True:
if error is not None: value = cmd.prompt_param(param,
self.Backend.textui.print_prompt_attribute_error(unicode(param.label), default=default,
unicode(error)) optional=optional,
raw = self.Backend.textui.prompt(param.label, default, optional=param.alwaysask or not param.required) kw=kw)
try:
value = param(raw, **kw) if value is not None:
if value is not None: kw[param.name] = value
kw[param.name] = value
break
except (ValidationError, ConversionError), e:
error = e.error
elif param.password and kw.get(param.name, False) is True: elif param.password and kw.get(param.name, False) is True:
kw[param.name] = self.Backend.textui.prompt_password( kw[param.name] = self.Backend.textui.prompt_password(
param.label, param.confirm param.label, param.confirm
+31 -6
View File
@@ -22,19 +22,18 @@ Base classes for all front-end plugins.
""" """
import re import re
import inspect
from distutils import version from distutils import version
from ipapython.version import API_VERSION from ipapython.version import API_VERSION
from ipapython.ipa_log_manager import root_logger from ipapython.ipa_log_manager import root_logger
from base import lock, check_name, NameSpace from base import NameSpace
from plugable import Plugin, is_production_mode from plugable import Plugin, is_production_mode
from parameters import create_param, parse_param_spec, Param, Str, Flag, Password from parameters import create_param, Param, Str, Flag, Password
from output import Output, Entry, ListOfEntries from output import Output, Entry, ListOfEntries
from text import _, ngettext from text import _
from errors import (ZeroArgumentError, MaxArgumentError, OverlapError, from errors import (ZeroArgumentError, MaxArgumentError, OverlapError,
RequiresRoot, VersionError, RequirementError, OptionError, InvocationError) VersionError, OptionError, InvocationError,
from constants import TYPE_ERROR ValidationError, ConversionError)
from ipalib import messages from ipalib import messages
@@ -560,6 +559,32 @@ class Command(HasParam):
if name in params: if name in params:
yield(name, params[name]) yield(name, params[name])
def prompt_param(self, param, default=None, optional=False, kw=dict(),
label=None):
"""
Prompts the user for the value of given parameter.
Returns the parameter instance.
"""
if label is None:
label = param.label
while True:
raw = self.Backend.textui.prompt(label, default, optional=optional)
# Backend.textui.prompt does not fill in the default value,
# we have to do it ourselves
if not raw.strip():
raw = default
try:
return param(raw, **kw)
except (ValidationError, ConversionError), e:
# Display error and prompt again
self.Backend.textui.print_prompt_attribute_error(unicode(label),
unicode(e.error))
def normalize(self, **kw): def normalize(self, **kw):
""" """
Return a dictionary of normalized values. Return a dictionary of normalized values.
+11 -22
View File
@@ -759,26 +759,16 @@ class DNSRecord(Str):
return tuple(self._convert_dnsrecord_extra(extra) for extra in self.extra) return tuple(self._convert_dnsrecord_extra(extra) for extra in self.extra)
def __get_part_param(self, backend, part, output_kw, default=None): def __get_part_param(self, cmd, part, output_kw, default=None):
name = self.part_name_format % (self.rrtype.lower(), part.name) name = self.part_name_format % (self.rrtype.lower(), part.name)
label = self.part_label_format % (self.rrtype, unicode(part.label)) label = self.part_label_format % (self.rrtype, unicode(part.label))
optional = not part.required optional = not part.required
while True: output_kw[name] = cmd.prompt_param(part,
try: optional=optional,
raw = backend.textui.prompt(label, label=label)
optional=optional,
default=default)
if not raw.strip():
raw = default
output_kw[name] = part(raw) def prompt_parts(self, cmd, mod_dnsvalue=None):
break
except (errors.ValidationError, errors.ConversionError), e:
backend.textui.print_prompt_attribute_error(
unicode(label), unicode(e.error))
def prompt_parts(self, backend, mod_dnsvalue=None):
mod_parts = None mod_parts = None
if mod_dnsvalue is not None: if mod_dnsvalue is not None:
mod_parts = self._get_part_values(mod_dnsvalue) mod_parts = self._get_part_values(mod_dnsvalue)
@@ -793,18 +783,17 @@ class DNSRecord(Str):
else: else:
default = None default = None
self.__get_part_param(backend, part, user_options, default) self.__get_part_param(cmd, part, user_options, default)
return user_options return user_options
def prompt_missing_parts(self, backend, kw, prompt_optional=False): def prompt_missing_parts(self, cmd, kw, prompt_optional=False):
user_options = {} user_options = {}
if self.parts is None: if self.parts is None:
return user_options return user_options
for part in self.parts: for part in self.parts:
name = self.part_name_format % (self.rrtype.lower(), part.name) name = self.part_name_format % (self.rrtype.lower(), part.name)
label = self.part_label_format % (self.rrtype, unicode(part.label))
if name in kw: if name in kw:
continue continue
@@ -814,7 +803,7 @@ class DNSRecord(Str):
continue continue
default = part.get_default(**kw) default = part.get_default(**kw)
self.__get_part_param(backend, part, user_options, default) self.__get_part_param(cmd, part, user_options, default)
return user_options return user_options
@@ -2395,7 +2384,7 @@ class dnsrecord_add(LDAPCreate):
# it can be used to fill all required params by itself # it can be used to fill all required params by itself
new_kw = {} new_kw = {}
for rrparam in self.obj.iterate_rrparams_by_parts(kw, skip_extra=True): for rrparam in self.obj.iterate_rrparams_by_parts(kw, skip_extra=True):
user_options = rrparam.prompt_missing_parts(self.Backend, kw, user_options = rrparam.prompt_missing_parts(self, kw,
prompt_optional=False) prompt_optional=False)
new_kw.update(user_options) new_kw.update(user_options)
kw.update(new_kw) kw.update(new_kw)
@@ -2437,7 +2426,7 @@ class dnsrecord_add(LDAPCreate):
continue continue
ok = True ok = True
user_options = param.prompt_parts(self.Backend) user_options = param.prompt_parts(self)
kw.update(user_options) kw.update(user_options)
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
@@ -2698,7 +2687,7 @@ class dnsrecord_mod(LDAPUpdate):
mod_value = self.Backend.textui.prompt_yesno( mod_value = self.Backend.textui.prompt_yesno(
_("Modify %(name)s '%(value)s'?") % dict(name=param.label, value=rec_value), default=False) _("Modify %(name)s '%(value)s'?") % dict(name=param.label, value=rec_value), default=False)
if mod_value is True: if mod_value is True:
user_options = param.prompt_parts(self.Backend, mod_dnsvalue=rec_value) user_options = param.prompt_parts(self, mod_dnsvalue=rec_value)
kw[param.name] = [rec_value] kw[param.name] = [rec_value]
kw.update(user_options) kw.update(user_options)