]> git.openstreetmap.org Git - osqa.git/blob - forum/modules/template_loader.py/forum/skins/__init__.py
365ed9ffca86ebf40ccd0634882b153e49fcd553
[osqa.git] / forum / modules / template_loader.py / forum / skins / __init__.py
1 from django.conf import settings
2 from django.template.loaders import filesystem
3 from django.template import TemplateDoesNotExist, Template as DJTemplate
4 from django.conf import settings as djsettings
5 import os.path
6 import logging
7
8 UNEXISTENT_TEMPLATE = object()
9
10 SKINS_FOLDER = os.path.dirname(__file__)
11 SKIN_TEMPLATES_FOLDER = 'templates'
12 DEFAULT_SKIN_NAME = 'default'
13
14
15 class Template(object):
16
17     def __init__(self, file_name):
18         self._file_name = file_name
19         self._loaded = False
20
21     def _get_mtime(self):
22         return os.path.getmtime(self._file_name)
23
24     def _check_mtime(self):
25         if self._last_mtime is None:
26             return False
27
28         return self._last_mtime == self._get_mtime()
29
30     def _load(self):
31         try:
32             f = open(self._file_name, 'r')
33             self._source = DJTemplate(f.read())
34             f.close()
35             self._loaded = True
36
37             self._last_mtime = self._get_mtime()
38         except:
39             self._loaded = False
40             self._last_mtime = None
41
42             raise
43
44     def return_tuple(self):
45         if not (self._loaded and self._check_mtime()):
46             try:
47                 self._load()
48             except:
49                 raise TemplateDoesNotExist, self._file_name
50
51         return self._source, self._file_name
52
53 class BaseTemplateLoader(object):
54     is_usable = True
55
56     def __init__(self):
57         self.cache = {}
58
59     def __call__(self, name=None, dirs=None):
60         if name is None:
61             return self
62
63         return self.load_template(name, dirs)
64
65     def load_template(self, name, dirs=None):
66         if not djsettings.TEMPLATE_DEBUG:
67             if name in self.cache:
68                 if self.cache[name] is UNEXISTENT_TEMPLATE:
69                     raise TemplateDoesNotExist, name
70
71                 try:
72                     return self.cache[name].return_tuple()
73                 except:
74                     del self.cache[name]
75
76         template = self.load_template_source(name, dirs)
77
78         if template is not None:
79             if not djsettings.DEBUG:
80                 self.cache[name] = template
81
82             return template.return_tuple()
83         else:
84             if not djsettings.DEBUG:
85                 self.cache[name] = UNEXISTENT_TEMPLATE
86
87             raise TemplateDoesNotExist, name
88
89     def load_template_source(self, name, dirs=None):
90         raise NotImplementedError
91
92
93 class SkinsTemplateLoader(BaseTemplateLoader):
94
95     def load_template_source(self, name, dirs=None):
96         file_name = os.path.join(SKINS_FOLDER, settings.OSQA_DEFAULT_SKIN, SKIN_TEMPLATES_FOLDER, name)
97
98         if os.path.exists(file_name):
99             return Template(file_name)
100
101         file_name = os.path.join(SKINS_FOLDER, DEFAULT_SKIN_NAME, SKIN_TEMPLATES_FOLDER, name)
102
103         if os.path.exists(file_name):
104             return Template(file_name)
105
106         return None
107
108 load_template_source = SkinsTemplateLoader()
109
110
111 def find_media_source(url):
112     """returns url prefixed with the skin name
113     of the first skin that contains the file 
114     directories are searched in this order:
115     settings.OSQA_DEFAULT_SKIN, then 'default', then 'commmon'
116     if file is not found - returns None
117     and logs an error message
118     """
119     while url[0] == '/': url = url[1:]
120     d = os.path.dirname
121     n = os.path.normpath
122     j = os.path.join
123     f = os.path.isfile
124     skins = n(j(d(d(__file__)),'skins'))
125     try:
126         media = os.path.join(skins, settings.OSQA_DEFAULT_SKIN, url)
127         assert(f(media))
128         use_skin = settings.OSQA_DEFAULT_SKIN
129     except:
130         try:
131             media = j(skins, 'default', url)
132             assert(f(media))
133             use_skin = 'default'
134         except:
135             media = j(skins, 'common', url)
136             try:
137                 assert(f(media))
138                 use_skin = 'common'
139             except:
140                 logging.error('could not find media for %s' % url)
141                 use_skin = ''
142                 return None
143     return use_skin + '/' + url
144