"""Use any of hooks below or write your own. You are welcome to contribute them!"""
import re
import time
from .bobexceptions import ValidationError
[docs]def to_boolean(configurator, question, answer):
"""
If you want to convert an answer to Python boolean, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
idiot.question = Are you young?
idiot.post_ask_question = mrbob.hooks:to_boolean
Following variables can be converted to a boolean: **y, n, yes, no, true, false, 1, 0**
"""
value = answer.lower()
if value in ['y', 'yes', 'true', '1']:
return True
elif value in ['n', 'no', 'false', '0']:
return False
else:
raise ValidationError('Value must be a boolean (y/n)')
[docs]def to_integer(configurator, question, answer):
"""
If you want to convert an answer to Python integer, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
owner.question = What's your age?
owner.post_ask_question = mrbob.hooks:to_integer
"""
try:
return int(answer)
except ValueError:
raise ValidationError('Value must be an integer')
[docs]def to_decimal(configurator, question, answer):
"""
If you want to convert an answer to Python float, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
daemon.question = What interval should the daemon poll for data?
daemon.post_ask_question = mrbob.hooks:to_decimal
"""
try:
return float(answer)
except ValueError:
raise ValidationError('Value must be a decimal')
[docs]def validate_choices(configurator, question, answer):
"""
If you want to validate an answer using a limited set of choices, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
license.question = What license would you like to use?
license.post_ask_question = mrbob.hooks:validate_choices
license.choices = MIT|BSD|Apache 2.0|Other
license.choices_case_sensitive = yes
license.choices_delimiter = |
Currently choices are split using whitespace by default. If you wish to
have whitespace within each choice, you may specify a custom delimiter
which will be used to split the choices.
This hook may be set to validate the choices in a case sensitive manner.
However, this behaviour is disabled by default.
"""
delimiter = question.extra.get('choices_delimiter')
choices = question.extra.get('choices', '').split(delimiter)
# If no choices are defined, then we assume the provided answer is correct
if not choices:
return answer
# Determine case sensitivity
case_sensitive_config = question.extra.get('choices_case_sensitive')
case_sensitive = False
if case_sensitive_config:
try:
case_sensitive = to_boolean(None, None, case_sensitive_config)
except ValidationError:
pass
if case_sensitive:
valid = answer in choices
else:
valid = answer.lower() in [c.lower() for c in choices]
if valid:
return answer
else:
raise ValidationError(
'Value must be ' + ', '.join(choices[:-1]) + ' or ' + choices[-1])
[docs]def validate_regex(configurator, question, answer):
"""
If you want to validate an answer using a regular expression, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
project.question = Please specify a name (only lowercase characters)?
project.post_ask_question = mrbob.hooks:validate_regex
project.regex = ^[a-z]+$
"""
regex = question.extra.get('regex')
# If no regex is defined, then we assume the provided answer is correct
if not regex:
return answer
if re.match(regex, answer):
return answer
else:
raise ValidationError(
'Value was not of the expected format (%s)' % regex)
[docs]def set_current_datetime(configurator, question):
"""
If you want to set the default answer of a question to the current
date and time, use this function as :ref:`pre-question-hook`:
.. code-block:: ini
[questions]
project.question = What year was the project started?
project.pre_ask_question = mrbob.hooks:set_current_datetime
project.datetime_format = %%Y
The datetime_format property should be of the standard Python strftime
format. It defaults to YYYY-MM-DD if not specified.
Please note that you'll have to escape the % character (by using %%)
due to the fact it's a special character in INI files.
See the following URL for more information:
http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
"""
datetime_format = question.extra.get('datetime_format', '%Y-%m-%d')
question.default = time.strftime(datetime_format)
[docs]def validate_datetime(configurator, question, answer):
"""
If you want to validate a date using a chosen date format, you can
use this function as :ref:`post-question-hook`:
.. code-block:: ini
[questions]
project.question = What year was the project started?
project.post_ask_question = mrbob.hooks:validate_datetime
project.datetime_format = %%Y
The datetime_format property should be of the standard Python strftime
format. It defaults to YYYY-MM-DD if not specified.
Please note that you'll have to escape the % character (by using %%)
due to the fact it's a special character in INI files.
See the following URL for more information:
http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
"""
datetime_format = question.extra.get('datetime_format', '%Y-%m-%d')
try:
time.strptime(answer, datetime_format)
return answer
except ValueError:
raise ValidationError(
'Value was not a date in the format ' + datetime_format)
[docs]def show_message(configurator):
"""
If you want to display a message to the user when rendering is complete, you
can use this function as :ref:`post-render-hook`:
.. code-block:: ini
[template]
post_render = mrbob.hooks:show_message
message = Well done, %(author.name)s, your code is ready!
As shown above, you can use standard Python formatting in ``post_render_msg``.
"""
message = configurator.templateconfig.get('message', '')
if not configurator.quiet and message:
print(message % configurator.variables)