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