1from __future__ import absolute_import 2 3import re 4 5from gcalcli.exceptions import ValidationError 6from gcalcli.utils import REMINDER_REGEX, get_time_from_str 7from six.moves import input 8 9# TODO: in the future, pull these from the API 10# https://developers.google.com/calendar/v3/reference/colors 11VALID_OVERRIDE_COLORS = ['lavender', 'sage', 'grape', 'flamingo', 12 'banana', 'tangerine', 'peacock', 'graphite', 13 'blueberry', 'basil', 'tomato'] 14 15 16def get_override_color_id(color): 17 return str(VALID_OVERRIDE_COLORS.index(color) + 1) 18 19 20def get_input(printer, prompt, validator_func): 21 printer.msg(prompt, 'magenta') 22 while True: 23 try: 24 output = validate_input(validator_func) 25 return output 26 except ValidationError as e: 27 printer.msg(e.message, 'red') 28 printer.msg(prompt, 'magenta') 29 30 31def color_validator(input_str): 32 """ 33 A filter allowing only the particular colors used by the Google Calendar 34 API 35 36 Raises ValidationError otherwise. 37 """ 38 try: 39 assert input_str in VALID_OVERRIDE_COLORS + [''] 40 return input_str 41 except AssertionError: 42 raise ValidationError( 43 'Expected colors are: ' + 44 ', '.join(color for color in VALID_OVERRIDE_COLORS) + 45 '. (Ctrl-C to exit)\n') 46 47 48def str_to_int_validator(input_str): 49 """ 50 A filter allowing any string which can be 51 converted to an int. 52 Raises ValidationError otherwise. 53 """ 54 try: 55 int(input_str) 56 return input_str 57 except ValueError: 58 raise ValidationError( 59 'Input here must be a number. (Ctrl-C to exit)\n' 60 ) 61 62 63def parsable_date_validator(input_str): 64 """ 65 A filter allowing any string which can be parsed 66 by dateutil. 67 Raises ValidationError otherwise. 68 """ 69 try: 70 get_time_from_str(input_str) 71 return input_str 72 except ValueError: 73 raise ValidationError( 74 'Expected format: a date (e.g. 2019-01-01, tomorrow 10am, ' 75 '2nd Jan, Jan 4th, etc) or valid time if today. ' 76 '(Ctrl-C to exit)\n' 77 ) 78 79 80def str_allow_empty_validator(input_str): 81 """ 82 A simple filter that allows any string to pass. 83 Included for completeness and for future validation if required. 84 """ 85 return input_str 86 87 88def non_blank_str_validator(input_str): 89 """ 90 A simple filter allowing string len > 1 and not None 91 Raises ValidationError otherwise. 92 """ 93 if input_str in [None, '']: 94 raise ValidationError( 95 'Input here cannot be empty. (Ctrl-C to exit)\n' 96 ) 97 else: 98 return input_str 99 100 101def reminder_validator(input_str): 102 """ 103 Allows a string that matches utils.REMINDER_REGEX. 104 Raises ValidationError otherwise. 105 """ 106 match = re.match(REMINDER_REGEX, input_str) 107 if match or input_str == '.': 108 return input_str 109 else: 110 raise ValidationError('Expected format: <number><w|d|h|m> ' 111 '<popup|email|sms>. (Ctrl-C to exit)\n') 112 113 114def validate_input(validator_func): 115 """ 116 Wrapper around Validator funcs. 117 """ 118 inp_str = input() 119 return validator_func(inp_str) 120 121 122STR_NOT_EMPTY = non_blank_str_validator 123STR_ALLOW_EMPTY = str_allow_empty_validator 124STR_TO_INT = str_to_int_validator 125PARSABLE_DATE = parsable_date_validator 126VALID_COLORS = color_validator 127REMINDER = reminder_validator 128