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