151 lines
5.6 KiB
Python
151 lines
5.6 KiB
Python
import importlib
|
|
import logging
|
|
import re
|
|
from django.apps import AppConfig as _AppConfig
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Form and Model Field Config
|
|
COMMON_CHAR_FIELD_LENGTH = 250
|
|
NUMBER_MAX_LENGTH = 12
|
|
TITLE_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
TRAINER_NAME_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
PHONE_NUMBER_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
LOCATION_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
TRANSPORT_OTHER_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
DEPARTURE_RIDE_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
MEETING_POINT_OTHER_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
BASECAMP_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
ACCOMMODATION_OTHER_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
MEALS_OTHER_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
ADDITIONAL_COSTS_MAX_LENGTH = COMMON_CHAR_FIELD_LENGTH
|
|
|
|
|
|
class FieldInitial(object):
|
|
_constraint_re = re.compile(r'^(?P<field>[a-z_]+)(?P<op>[=]+)(?P<value>.*)$')
|
|
|
|
def __init__(self, *args):
|
|
self._tuples = []
|
|
|
|
if len(args) == 1:
|
|
self._tuples = [(None, args[0])]
|
|
else:
|
|
constraint = None
|
|
for arg in args:
|
|
if constraint is None:
|
|
constraint = arg
|
|
else:
|
|
self._tuples.append((constraint, arg))
|
|
constraint = None
|
|
|
|
def get_value(self, session_data):
|
|
parameters = {
|
|
'mode': session_data.get('mode', None),
|
|
'sport': session_data.get('sport', None),
|
|
'level': session_data.get('level', None),
|
|
'overnight': str(bool(session_data.get('last_day', None))),
|
|
'country': session_data.get('country', None),
|
|
'terrain': session_data.get('terrain', None),
|
|
'transport': session_data.get('transport', None),
|
|
}
|
|
for tuple in self._tuples:
|
|
constraint, result = tuple
|
|
|
|
if not constraint:
|
|
return result
|
|
|
|
match = False
|
|
constraint_parts = constraint.split(',')
|
|
for sub_constraint in constraint_parts:
|
|
c = self._constraint_re.match(sub_constraint)
|
|
if c is not None:
|
|
c_field = c.group('field')
|
|
if c_field not in parameters:
|
|
logger.error('FieldInitial: Invalid field: \'%s\'', sub_constraint)
|
|
continue
|
|
c_op = c.group('op')
|
|
c_value = c.group('value')
|
|
if c_op == '==':
|
|
if parameters[c_field] == c_value:
|
|
match = True
|
|
continue
|
|
else:
|
|
match = False
|
|
break
|
|
else:
|
|
logger.error('FieldInitial: Invalid operator: \'%s\'', sub_constraint)
|
|
continue
|
|
else:
|
|
logger.error('FieldInitial: Invalid constraint: \'%s\'', constraint)
|
|
break
|
|
|
|
if match:
|
|
return result
|
|
|
|
return None
|
|
|
|
|
|
class DefaultSetting(object):
|
|
def __init__(self, name, value, key_name=None, validator=None):
|
|
self.name = name
|
|
self.value = value
|
|
if key_name is None:
|
|
self.key_name = self.name.upper()
|
|
else:
|
|
self.key_name = key_name
|
|
self.validator = validator
|
|
|
|
def validate(self, value):
|
|
if hasattr(self, 'validator') and self.validator is not None:
|
|
if callable(self.validator):
|
|
if not self.validator(value):
|
|
raise ImproperlyConfigured("Validator callback {clb} returned False".format(clb=self.validator))
|
|
else:
|
|
if not re.search(self.validator, value):
|
|
raise ImproperlyConfigured("Does not match /{re}/".format(re=self.validator))
|
|
|
|
|
|
class AppSettings(object):
|
|
def __init__(self, app_name, defaults):
|
|
settings_name = 'main.settings-' + app_name
|
|
|
|
try:
|
|
settings_module = importlib.import_module(settings_name)
|
|
except ImportError:
|
|
settings_module = None
|
|
|
|
for default in defaults:
|
|
if hasattr(settings_module, default.key_name):
|
|
value = getattr(settings_module, default.key_name)
|
|
try:
|
|
default.validate(value)
|
|
except ImproperlyConfigured as e:
|
|
msg = 'Invalid value of {key} in {module}: {cause}'.format(key=default.key_name,
|
|
module=settings_name,
|
|
cause=e.message)
|
|
raise ImproperlyConfigured(msg)
|
|
setattr(self, default.name, value)
|
|
elif isinstance(default.value, ImproperlyConfigured):
|
|
raise default.value
|
|
else:
|
|
try:
|
|
is_impconf = issubclass(default.value, ImproperlyConfigured)
|
|
except TypeError:
|
|
is_impconf = False
|
|
|
|
if is_impconf:
|
|
msg = '{key} must be defined in {module}'.format(key=default.key_name,
|
|
module=settings_name)
|
|
raise default.value(msg)
|
|
else:
|
|
setattr(self, default.name, default.value)
|
|
|
|
|
|
class AppConfig(_AppConfig):
|
|
default_settings = ()
|
|
|
|
def __init__(self, app_name, app_module):
|
|
super(AppConfig, self).__init__(app_name, app_module)
|
|
self.settings = AppSettings(app_name, self.default_settings)
|