self.description = description
self.weight = weight
self.markdown = markdown
+
class BaseSetting(object):
- def __init__(self, name, default, field_context):
+ @classmethod
+ def add_to_class(cls, name):
+ def wrapper(self, *args, **kwargs):
+ return self.value.__getattribute__(name)(*args, **kwargs)
+
+ setattr(cls, name, wrapper)
+
+ def __init__(self, name, default, set=None, field_context=None):
self.name = name
self.default = default
- self.field_context = field_context
+ self.field_context = field_context or {}
+
+ if set is not None:
+ if not set.name in Setting.sets:
+ Setting.sets[set.name] = set
+
+ Setting.sets[set.name].append(self)
+
+ def __str__(self):
+ return str(self.value)
+
+ def __unicode__(self):
+ return unicode(self.value)
@property
def value(self):
def set_value(self, new_value):
new_value = self._parse(new_value)
+ self.save(new_value)
+
+ def save(self, value):
from forum.models import KeyValue
try:
kv = KeyValue.objects.get(key=self.name)
- old_value = kv.value
except:
kv = KeyValue(key=self.name)
- old_value = self.default
- kv.value = new_value
+ kv.value = value
kv.save()
- setting_update.send(sender=self, old_value=old_value, new_value=new_value)
-
def to_default(self):
self.set_value(self.default)
def _parse(self, value):
- return value
+ if not isinstance(value, self.base_type):
+ try:
+ return self.base_type(value)
+ except:
+ pass
+ return value
- def __str__(self):
- return str(self.value)
- def __unicode__(self):
- return unicode(self.value)
-
- def __nonzero__(self):
- return bool(self.value)
+class Setting(object):
+ emulators = {}
+ sets = {}
+ def __new__(cls, name, default, set=None, field_context=None):
+ deftype = type(default)
-class StringSetting(BaseSetting):
- def _parse(self, value):
- if isinstance(value, unicode):
- return value.encode('utf8')
+ if deftype in Setting.emulators:
+ emul = Setting.emulators[deftype]
else:
- return str(value)
-
- def __unicode__(self):
- return unicode(self.value.decode('utf8'))
-
- def __add__(self, other):
- return "%s%s" % (unicode(self), other)
-
- def __cmp__(self, other):
- return cmp(str(self), str(other))
-
-class IntegerSetting(BaseSetting):
- def _parse(self, value):
- return int(value)
-
- def __int__(self):
- return int(self.value)
-
- def __add__(self, other):
- return int(self) + int(other)
-
- def __sub__(self, other):
- return int(self) - int(other)
-
- def __cmp__(self, other):
- return int(self) - int(other)
-
-class FloatSetting(BaseSetting):
- def _parse(self, value):
- return float(value)
+ emul = type(deftype.__name__ + cls.__name__, (BaseSetting,), {'base_type': deftype})
- def __int__(self):
- return int(self.value)
+ fns = [n for n, f in [(p, getattr(deftype, p)) for p in dir(deftype) if not p in dir(cls)] if callable(f)]
- def __float__(self):
- return float(self.value)
+ for n in fns:
+ emul.add_to_class(n)
- def __add__(self, other):
- return float(self) + float(other)
-
- def __sub__(self, other):
- return float(self) - float(other)
-
- def __cmp__(self, other):
- return float(self) - float(other)
-
-class BoolSetting(BaseSetting):
- def _parse(self, value):
- return bool(value)
-
-class Setting(object):
- sets = {}
-
- def __new__(cls, name, default, set=None, field_context={}):
- if isinstance(default, bool):
- instance = BoolSetting(name, default, field_context)
- elif isinstance(default, str):
- instance = StringSetting(name, default, field_context)
- elif isinstance(default, float):
- instance = FloatSetting(name, default, field_context)
- elif isinstance(default, int):
- instance = IntegerSetting(name, default, field_context)
- else:
- instance = BaseSetting(name, default, field_context)
-
- if set is not None:
- if not set.name in cls.sets:
- cls.sets[set.name] = set
+ Setting.emulators[deftype] = emul
- cls.sets[set.name].append(instance)
+ return emul(name, default, set, field_context)
- return instance
-setting_update = django.dispatch.Signal(providing_args=['old_value', 'new_value'])