]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/settings/base.py
An initial settings group to support user-defined upper and lower sidebar content...
[osqa.git] / forum / settings / base.py
index dc0157718e7a0c7d9b58ec19847f3839b2fac88d..e16097027102d0cb6f19b443aab9cf705897a2e8 100644 (file)
@@ -8,12 +8,32 @@ class SettingSet(list):
         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):
@@ -29,112 +49,50 @@ class BaseSetting(object):
 
     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'])