diff options
Diffstat (limited to 'funcweb/funcweb/widget_validation.py')
-rw-r--r-- | funcweb/funcweb/widget_validation.py | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/funcweb/funcweb/widget_validation.py b/funcweb/funcweb/widget_validation.py new file mode 100644 index 0000000..0347fa6 --- /dev/null +++ b/funcweb/funcweb/widget_validation.py @@ -0,0 +1,333 @@ +from turbogears import validators #the shiny validator part + +class WidgetSchemaFactory(object): + """ + The purpose of the class is to produce a + validators.Schema object according to method + arguments that are retrieved from minions + """ + + def __init__(self,method_argument_dict): + """ + @param method_argument_dict : The dict that is + from minion in format of {'arg':{'type':'string','options':[...]}} + the format is defined in func/minion/func_arg.py + """ + + self.method_argument_dict = method_argument_dict + self.validator_list = {} #the validator that will create final schema + + def _add_validators(self): + """ + Method is an entry point of factory iters over the all arguments + and according to their types it sends the process to more specialized + validator adders + """ + + for argument_name,argument_values in self.method_argument_dict.iteritems(): + #some lazy stuff :) + #for ex : _add_int_validator(some_arg) + getattr(self,"_add_%s_validator"%(argument_values['type']))(argument_name) + + def _add_boolean_validator(self,argument_name): + bool_data_set = {} + + #the optional keyword + if self.method_argument_dict[argument_name].has_key('optional'): + if self.method_argument_dict[argument_name]['optional']: + bool_data_set['not_empty']=False + else: + bool_data_set['not_empty']=True + + + if bool_data_set: + self.validator_list[argument_name]=validators.Bool(**bool_data_set) + else: + self.validator_list[argument_name]=validators.Bool() + + + + + def _add_int_validator(self,argument_name): + """ + Gets the options of the int type and adds a + new validator to validator_list + """ + #the initializer for the int_validator + int_data_set = {} + + #the optional keyword + if self.method_argument_dict[argument_name].has_key('optional'): + if self.method_argument_dict[argument_name]['optional']: + int_data_set['not_empty']=False + else: + int_data_set['not_empty']=True + + if self.method_argument_dict[argument_name].has_key('range'): + #because the range is [min,max] list the 0 is min 1 is the max + int_data_set['min']=self.method_argument_dict[argument_name]['range'][0] + int_data_set['max']=self.method_argument_dict[argument_name]['range'][1] + if self.method_argument_dict[argument_name].has_key('min'): + int_data_set['min']=self.method_argument_dict[argument_name]['min'] + if self.method_argument_dict[argument_name].has_key('max'): + int_data_set['max']=self.method_argument_dict[argument_name]['max'] + + #add the validator to the list + if int_data_set: + self.validator_list[argument_name]=MinionIntValidator(**int_data_set) + else: + self.validator_list[argument_name]=MinionIntValidator() + + + + + def _add_string_validator(self,argument_name): + """ + Gets the options of the string type and adds a + new validator to validator_list + """ + + string_data_set={} + str_validator_list =[] + + if self.method_argument_dict[argument_name].has_key('optional'): + if self.method_argument_dict[argument_name]['optional']: + string_data_set['not_empty']=False + else: + string_data_set['not_empty']=True + + if self.method_argument_dict[argument_name].has_key('min_length'): + string_data_set['min']=self.method_argument_dict[argument_name]['min_length'] + if self.method_argument_dict[argument_name].has_key('max_length'): + string_data_set['max']=self.method_argument_dict[argument_name]['max_length'] + if self.method_argument_dict[argument_name].has_key('validator'): + str_validator_list.append(getattr(validators,'Regex')(self.method_argument_dict[argument_name]['validator'])) + + #if we have set a string_data_set + if string_data_set: + str_validator_list.append(getattr(validators,'String')(**string_data_set)) + + #if true it should be a validator.All thing + if len(str_validator_list)>1: + self.validator_list[argument_name]=getattr(validators,'All')(*str_validator_list) + elif str_validator_list: + self.validator_list[argument_name]=str_validator_list[0] + else: #if there is no option + self.validator_list[argument_name]=getattr(validators,'String')() + + + + + def _add_float_validator(self,argument_name): + """ + Gets the options of the float type and adds a + new validator to validator_list + """ + + #the initializer for the float_validator + float_data_set = {} + + #is it optional + if self.method_argument_dict[argument_name].has_key('optional'): + if self.method_argument_dict[argument_name]['optional']: + float_data_set['not_empty']=False + else: + float_data_set['not_empty']=True + + + if self.method_argument_dict[argument_name].has_key('min'): + float_data_set['min']=self.method_argument_dict[argument_name]['min'] + if self.method_argument_dict[argument_name].has_key('max'): + float_data_set['max']=self.method_argument_dict[argument_name]['max'] + + #add the validator to the list + if float_data_set: + self.validator_list[argument_name]=MinionFloatValidator(**float_data_set) + else: + self.validator_list[argument_name]=MinionFloatValidator() + + + + def _add_list_validator(self,argument_name,the_type='list'): + """ + Gets the options of the list type and adds a + new validator to validator_list + """ + list_data_set = {} + + #is it optional + if self.method_argument_dict[argument_name].has_key('optional'): + if self.method_argument_dict[argument_name]['optional']: + list_data_set['not_empty']=False + else: + list_data_set['not_empty']=True + + if self.method_argument_dict[argument_name].has_key('validator'): + list_data_set['regex_string'] = self.method_argument_dict[argument_name]['validator'] + + if list_data_set: + if the_type == 'list': + self.validator_list[argument_name]=MinionListValidator(**list_data_set) + else: + self.validator_list[argument_name]=MinionHashValidator(**list_data_set) + + else: + if the_type == 'list': + self.validator_list[argument_name]=MinionListValidator() + else: + self.validator_list[argument_name]=MinionHashValidator() + + + + def _add_hash_validator(self,argument_name): + """ + Gets the options of the hash type and adds a + new validator to validator_list + """ + self._add_list_validator(argument_name,the_type = 'hash') + + + def get_ready_schema(self): + """ + Get the final validator schema + """ + final_schema = validators.Schema() + if not self.validator_list: + self._add_validators() + + for vd_name,vd in self.validator_list.iteritems(): + #setattr(final_schema,vd_name,vd) + getattr(final_schema,'fields')[vd_name]= vd + + return final_schema + +######################################################################## +class MinionIntValidator(validators.FancyValidator): + + """ + Confirms that the input/output is of the proper type of int. + + """ + #automatically will be assigned + min = None + max = None + + def _to_python(self,value,state): + """ + Will check just the type here and return + value to be validated in validate_python + """ + try: + value = int(value) + except (ValueError, TypeError): + raise validators.Invalid('The field should be integer',value,state) + + return int(value) + + + def validate_python(self,value,state): + """ + The actual validator + """ + #firstly run the supers one + if self.min and self.min: + if value < self.min: + raise validators.Invalid('The number you entered should be bigger that %d'%(self.min),value,state) + + if self.max and self.max: + if value > self.max: + raise validators.Invalid('The number you entered exceeds the %d'%(self.max),value,state) + + +################################################################## +class MinionFloatValidator(MinionIntValidator): + + def _to_python(self,value,state): + """ + Will check just the type here and return + value to be validated in validate_python + """ + try: + value = float(value) + except (ValueError, TypeError): + raise validators.Invalid('The field should be a float',value,state) + + return float(value) + +################################################################# +class MinionListValidator(validators.FancyValidator): + + regex_string = None + + def _to_python(self,value,state): + """ + Will check just the type here and return + value to be validated in validate_python + """ + #will add more beautiful validation here after + #integrate the complex widgets for lists and dicts + if self.not_empty: + if len(value)==0: + raise validators.Invalid('Empty list passed when not_empty is set',value,state) + + + tmp = [] + if type(tmp) != type(value): + value = list(value) + value = [list_value.strip() for list_value in value] + + return value + + def validate_python(self,value,state): + import re + if self.regex_string: + try: + compiled_regex = re.compile(self.regex_string) + except Exception,e: + raise validators.Invalid('The passed regex_string is not a valid expression'%self.regex_string,value,state) + + for list_value in value: + if not re.match(compiled_regex,str(list_value)): + raise validators.Invalid('The %s doesnt match to the regex expression that was supplied'%list_value,value,state) + + #there is no else for now :) + +class MinionHashValidator(validators.FancyValidator): + + regex_string = None + + def _to_python(self,value,state): + """ + Will check just the type here and return + value to be validated in validate_python + """ + #will add more beautiful validation here after + #integrate the complex widgets for lists and dicts + if self.not_empty: + if len(value)==0: + raise validators.Invalid('Empty hash passed when not_empty is set',value,state) + + #check the type firstly + tmp = {} + if type(tmp) != type(value): + raise validators.Invalid('The value passed to MinionHashValidator should be a dict object',value,state) + + #print value + return value + + def validate_python(self,value,state): + #print value + import re + if self.regex_string: + try: + compiled_regex = re.compile(self.regex_string) + except Exception,e: + raise validators.Invalid('The passed regex_string is not a valid expression'%self.regex_string,value,state) + for dict_value in value.itervalues(): + if not re.match(compiled_regex,str(dict_value)): + raise validators.Invalid('The %s doesnt match to the regex expression that was supplied'%dict_value,value,state) + + + +if __name__ == "__main__": + pass |