]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/skins/__init__.py
Merge pull request #46 from udacity/subfolder_fixes
[osqa.git] / forum / skins / __init__.py
index be6bd4f38e33055255d52ea788ba3b02dd27b840..33e0097cc147f15054f95ec997ffb596f0b47ef0 100644 (file)
 from django.conf import settings
 from django.conf import settings
-from django.template import loader
-from django.template.loaders import filesystem 
-from django.http import HttpResponse
+from django.template.loaders import filesystem
+from django.template import TemplateDoesNotExist, Template as DJTemplate
+from django.conf import settings as djsettings
 import os.path
 import logging
 
 import os.path
 import logging
 
-#module for skinning osqa
-#at this point skin can be changed only in settings file
-#via OSQA_DEFAULT_SKIN variable
+UNEXISTENT_TEMPLATE = object()
 
 
-#note - Django template loaders use method django.utils._os.safe_join
-#to work on unicode file paths
-#here it is ignored because it is assumed that we won't use unicode paths
+SKINS_FOLDER = os.path.dirname(__file__)
+SKIN_TEMPLATES_FOLDER = 'templates'
+DEFAULT_SKIN_NAME = 'default'
+FORCE_DEFAULT_PREFIX = "%s/" % DEFAULT_SKIN_NAME
+
+
+class Template(object):
+
+    def __init__(self, file_name):
+        self._file_name = file_name
+        self._loaded = False
+
+    def _get_mtime(self):
+        return os.path.getmtime(self._file_name)
+
+    def _check_mtime(self):
+        if self._last_mtime is None:
+            return False
+
+        return self._last_mtime == self._get_mtime()
+
+    def _load(self):
+        try:
+            f = open(self._file_name, 'r')
+            self._source = f.read()
+            f.close()
+            self._loaded = True
+
+            self._last_mtime = self._get_mtime()
+        except:
+            self._loaded = False
+            self._last_mtime = None
+
+            raise
+
+    def return_tuple(self):
+        if not (self._loaded and self._check_mtime()):
+            try:
+                self._load()
+            except:
+                raise TemplateDoesNotExist, self._file_name
+
+        return self._source, self._file_name
+
+class BaseTemplateLoader(object):
+    is_usable = True
+
+    def __init__(self):
+        self.cache = {}
+
+    def __call__(self, name=None, dirs=None):
+        if name is None:
+            return self
+
+        return self.load_template(name, dirs)
+
+    def load_template(self, name, dirs=None):
+        if not djsettings.TEMPLATE_DEBUG:
+            if name in self.cache:
+                if self.cache[name] is UNEXISTENT_TEMPLATE:
+                    raise TemplateDoesNotExist, name
+
+                try:
+                    return self.cache[name].return_tuple()
+                except:
+                    del self.cache[name]
+
+        template = self.load_template_source(name, dirs)
+
+        if template is not None:
+            if not djsettings.DEBUG:
+                self.cache[name] = template
+
+            return template.return_tuple()
+        else:
+            if not djsettings.DEBUG:
+                self.cache[name] = UNEXISTENT_TEMPLATE
+
+            raise TemplateDoesNotExist, name
+
+    def load_template_source(self, name, dirs=None):
+        raise NotImplementedError
+
+
+class SkinsTemplateLoader(BaseTemplateLoader):
+
+    def load_template_source(self, name, dirs=None):
+
+        if name.startswith(FORCE_DEFAULT_PREFIX):
+
+            file_name = os.path.join(SKINS_FOLDER, DEFAULT_SKIN_NAME, SKIN_TEMPLATES_FOLDER, name[len(FORCE_DEFAULT_PREFIX):])
+
+            if os.path.exists(file_name):
+                return Template(file_name)
+            else:
+                return None
+
+        for skin in (settings.OSQA_DEFAULT_SKIN, DEFAULT_SKIN_NAME):
+            file_name = os.path.join(SKINS_FOLDER, skin, SKIN_TEMPLATES_FOLDER, name)
+
+            if os.path.exists(file_name):
+                return Template(file_name)
+
+        return None
+
+load_template_source = SkinsTemplateLoader()
 
 
-def load_template_source(name, dirs=None):
-    try:
-        tname = os.path.join(settings.OSQA_DEFAULT_SKIN,'templates',name)
-        return filesystem.load_template_source(tname,dirs)
-    except:
-        tname = os.path.join('default','templates',name)
-        return filesystem.load_template_source(tname,dirs)
-load_template_source.is_usable = True
 
 def find_media_source(url):
     """returns url prefixed with the skin name
 
 def find_media_source(url):
     """returns url prefixed with the skin name
@@ -55,3 +148,4 @@ def find_media_source(url):
                 use_skin = ''
                 return None
     return use_skin + '/' + url
                 use_skin = ''
                 return None
     return use_skin + '/' + url
+