127 lines
3.5 KiB
Python
127 lines
3.5 KiB
Python
import decimal
|
|
|
|
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 read(self, fp):
|
|
if fp.tell() + self.max_length <= fp.len:
|
|
data = fp.read(self.max_length)
|
|
return self.parse(data)
|
|
return None
|
|
|
|
def parse(self, s):
|
|
self.value = s.strip()
|
|
|
|
|
|
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")
|
|
|
|
def get_data(self):
|
|
value = self.value or ""
|
|
return value.zfill(self.max_length)
|
|
|
|
def parse(self, s):
|
|
self.value = int(s)
|
|
|
|
|
|
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
|
|
|
|
def parse(self, s):
|
|
pass
|
|
|
|
class BlankField(TextField):
|
|
def get_data(self):
|
|
return " " * self.max_length
|
|
|
|
def parse(self, s):
|
|
pass
|
|
|
|
class BooleanField(Field):
|
|
def __init__(self, name=None, required=True, value=None):
|
|
super(BooleanField, self).__init__(name=name, required=required, max_length=1)
|
|
self._value = value
|
|
|
|
def validate(self):
|
|
pass
|
|
|
|
def get_data(self):
|
|
return '1' if self._value else '0'
|
|
|
|
def parse(self, s):
|
|
self.value = (s == '1')
|
|
|
|
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)
|
|
|
|
def parse(self, s):
|
|
self.value = decimal.Decimal(s) * decimal.Decimal('0.01')
|
|
|
|
class DateField(TextField):
|
|
#FIXME I NEED TO BE WRITTEN!
|
|
pass
|