]> git.openstreetmap.org Git - osqa.git/blob - forum/settings/base.py
Adds the option to create static pages with several options to customize its behaviour.
[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 import logging
5
6 TMP_MINICACHE_SECONDS = 5
7
8 class SettingSet(list):
9     def __init__(self, name, title, description, weight=1000, markdown=False):
10         self.name = name
11         self.title = title
12         self.description = description
13         self.weight = weight
14         self.markdown = markdown
15
16
17 class BaseSetting(object):
18     @classmethod
19     def add_to_class(cls, name):
20         def wrapper(self, *args, **kwargs):
21             return self.value.__getattribute__(name)(*args, **kwargs)
22
23         setattr(cls, name, wrapper)
24
25     def __init__(self, name, default, set=None, field_context=None):
26         self.name = name
27         self.default = default
28         self.field_context = field_context or {}
29
30         self._temp = None
31
32         if set is not None:
33             if not set.name in Setting.sets:
34                 Setting.sets[set.name] = set
35
36             Setting.sets[set.name].append(self)
37
38     def __str__(self):
39         return str(self.value)
40
41     def __unicode__(self):
42         return unicode(self.value)
43
44     @property
45     def value(self):
46         if self._temp:
47             v, exp = self._temp
48             if exp + timedelta(seconds=TMP_MINICACHE_SECONDS) > datetime.now():
49                 return v
50
51         from forum.models import KeyValue
52
53         try:
54             kv = KeyValue.objects.get(key=self.name)
55             v = kv.value
56             self._temp = (v, datetime.now() + timedelta(seconds=TMP_MINICACHE_SECONDS))
57             return v
58         except KeyValue.DoesNotExist:
59             self._temp = (self.default, datetime.now() + timedelta(seconds=TMP_MINICACHE_SECONDS))
60         except Exception, e:
61             logging.error("Error retrieving setting from database (%s): %s" % (self.name, str(e)))
62             
63         return self.default
64
65     def set_value(self, new_value):
66         new_value = self._parse(new_value)
67         self._temp = None
68         self.save(new_value)
69
70     def save(self, value):
71         from forum.models import KeyValue
72
73         try:
74             kv = KeyValue.objects.get(key=self.name)
75         except KeyValue.DoesNotExist:
76             kv = KeyValue(key=self.name)
77         except Exception, e:
78             logging.error("Error savin setting to database (%s): %s" % (self.name, str(e)))
79             return
80
81         kv.value = value
82         kv.save()
83
84     def to_default(self):
85         self.set_value(self.default)
86
87     def _parse(self, value):
88         if not isinstance(value, self.base_type):
89             try:
90                 return self.base_type(value)
91             except:
92                 pass
93         return value
94
95 class AnyTypeSetting(BaseSetting):
96      def _parse(self, value):
97         return value
98
99
100 class Setting(object):
101     emulators = {}
102     sets = {}
103
104     def __new__(cls, name, default, set=None, field_context=None):
105         if default is None:
106             return AnyTypeSetting(name, default, set, field_context)
107             
108         deftype = type(default)
109
110         if deftype in Setting.emulators:
111             emul = Setting.emulators[deftype]
112         else:
113             emul = type(deftype.__name__ + cls.__name__, (BaseSetting,), {'base_type': deftype})
114
115             fns = [n for n, f in [(p, getattr(deftype, p)) for p in dir(deftype) if not p in dir(cls)] if callable(f)]
116
117             for n in fns:
118                emul.add_to_class(n)
119
120             Setting.emulators[deftype] = emul
121
122         return emul(name, default, set, field_context)
123
124