]> git.openstreetmap.org Git - osqa.git/blob - forum/settings/base.py
Some improvements in cache.
[osqa.git] / forum / settings / base.py
1 import django.dispatch
2 from django.utils.encoding import force_unicode
3
4 class SettingSet(list):
5     def __init__(self, name, title, description, weight=1000, markdown=False):
6         self.name = name
7         self.title = title
8         self.description = description
9         self.weight = weight
10         self.markdown = markdown
11         
12
13 class BaseSetting(object):
14     @classmethod
15     def add_to_class(cls, name):
16         def wrapper(self, *args, **kwargs):
17             return self.value.__getattribute__(name)(*args, **kwargs)
18
19         setattr(cls, name, wrapper)
20
21     def __init__(self, name, default, set=None, field_context=None):
22         self.name = name
23         self.default = default
24         self.field_context = field_context or {}
25
26         if set is not None:
27             if not set.name in Setting.sets:
28                 Setting.sets[set.name] = set
29
30             Setting.sets[set.name].append(self)
31
32     def __str__(self):
33         return str(self.value)
34
35     def __unicode__(self):
36         return unicode(self.value)
37
38     @property
39     def value(self):
40         from forum.models import KeyValue
41
42         try:
43             kv = KeyValue.objects.get(key=self.name)
44         except:
45             kv = KeyValue(key=self.name, value=self._parse(self.default))
46             kv.save()
47
48         return kv.value
49
50     def set_value(self, new_value):
51         new_value = self._parse(new_value)
52         self.save(new_value)
53
54     def save(self, value):
55         from forum.models import KeyValue
56
57         try:
58             kv = KeyValue.objects.get(key=self.name)
59         except:
60             kv = KeyValue(key=self.name)
61
62         kv.value = value
63         kv.save()
64
65     def to_default(self):
66         self.set_value(self.default)
67
68     def _parse(self, value):
69         if not isinstance(value, self.base_type):
70             try:
71                 return self.base_type(value)
72             except:
73                 pass
74         return value
75
76 class AnyTypeSetting(BaseSetting):
77      def _parse(self, value):
78         return value
79
80
81 class Setting(object):
82     emulators = {}
83     sets = {}
84
85     def __new__(cls, name, default, set=None, field_context=None):
86         if default is None:
87             return AnyTypeSetting(name, default, set, field_context)
88             
89         deftype = type(default)
90
91         if deftype in Setting.emulators:
92             emul = Setting.emulators[deftype]
93         else:
94             emul = type(deftype.__name__ + cls.__name__, (BaseSetting,), {'base_type': deftype})
95
96             fns = [n for n, f in [(p, getattr(deftype, p)) for p in dir(deftype) if not p in dir(cls)] if callable(f)]
97
98             for n in fns:
99                emul.add_to_class(n)
100
101             Setting.emulators[deftype] = emul
102
103         return emul(name, default, set, field_context)
104
105