class ValidationError(Exception): pass class Field(object): creation_counter = 0 def __init__(self, name=None, max_length=0, required=True, uppercase=True): self.name = name self._value = None self.max_length = max_length self.required = required self.uppercase = uppercase self.creation_counter = Field.creation_counter Field.creation_counter += 1 def validate(self): raise NotImplemented() def get_data(self): raise NotImplemented() def __setvalue(self, value): self._value = value def __getvalue(self): return self._value value = property(__getvalue, __setvalue) def __repr__(self): return self.name class TextField(Field): def validate(self): if self.value == None and self.required: raise ValidationError("value required") if len(self.value) > self.max_length: raise ValidationError("value is too long") def get_data(self): value = self.value or "" if self.uppercase: value = value.upper() return value.ljust(self.max_length).encode('ascii') class StateField(TextField): def __init__(self, name=None, required=True): return super(StateField, self).__init__(name=name, max_length=2, required=required) class EmailField(TextField): def __init__(self, name=None, required=True, max_length=None): return super(EmailField, self).__init__(name=name, max_length=max_length, required=required, uppercase=False) class NumericField(TextField): def validate(self): super(NumericField, self).validate() try: int(self.value) except ValueError: raise ValidationError("field contains non-numeric characters") class StaticField(TextField): def __init__(self, name=None, required=True, value=None): super(StaticField, self).__init__(name=name, required=required, max_length=len(value)) self._value = value class BlankField(TextField): def get_data(self): return " " * self.max_length class BooleanField(Field): def validate(self): pass def get_data(self): return '1' if self._value else '0' class MoneyField(Field): def validate(self): if self.value == None and self.required: raise ValidationError("value required") if len(str(int((self.value or 0)*100))) > self.max_length: raise ValidationError("value is too long") def get_data(self): return str(int((self.value or 0)*100)).encode('ascii').zfill(self.max_length)