Code

Ticket #437: filecache.diff

File filecache.diff, 5.7 KB (added by nesh <nesh [at] studioquattro [dot] co [dot] yu>, 9 years ago)
Line 
1Index: django/utils/filecache.py
2===================================================================
3--- django/utils/filecache.py   (revision 0)
4+++ django/utils/filecache.py   (revision 0)
5@@ -0,0 +1,193 @@
6+# -*- coding: utf-8 -*-
7+# vim:enc=utf8:fenc=utf8:sts=4:sw=4:sta:et:nofen:si:ai:nowrap
8+
9+# (C) Djordjevic Nebojsa <nesh@studioquattro.co.yu> 2005
10+# You're welcome to redistribute this software under the
11+# terms of the GNU Library General Public Licence version 2.0
12+# or, at your option, any higher version.
13+#
14+# You can read the complete GNU LGPL in the file COPYING
15+# which should come along with this software, or visit
16+# the Free Software Foundation's WEB site http://www.fsf.org
17+#
18+
19+
20+""" In memory file cache. It will automatically reload a file if it
21+    has changed. This includes its modification time being
22+    set backwards in time.
23+
24+    based on vampire TemplateCache
25+"""
26+
27+##################################################
28+## DEPENDENCIES ##
29+
30+import os
31+import time
32+
33+try:
34+  from threading import Lock
35+except:
36+    class Lock:
37+        def acquire(self): pass
38+        def release(self): pass
39+    # Lock
40+#
41+
42+##################################################
43+## GLOBALS AND CONSTANTS ##
44+
45+_cache = {}
46+
47+##################################################
48+## CLASSES ##
49+
50+class _FileInfo(object):
51+    __slots__ = ('path', 'mtime', 'atime', 'hits', 'content')
52+
53+    def __init__(self, path, mtime, content):
54+        super(_FileInfo, self).__init__()
55+        self.path = path
56+        self.mtime = mtime
57+        self.atime = time.time()
58+        self.hits = 0
59+        self.content = content
60+    # __init__
61+# _FileInfo
62+
63+class FileCache(object):
64+    """ dict based cache  """
65+
66+    __slots__ = ('_lock', '_frozen', '_cache')
67+
68+    def __init__(self):
69+        super(FileCache, self).__init__()
70+
71+        self._lock = Lock()
72+        self._frozen = False
73+        self._cache = {}
74+    # __init__
75+
76+    def files(self):
77+        self._lock.acquire()
78+        try:
79+            return self._cache.keys()
80+        finally:
81+            self._lock.release()
82+    # keys
83+
84+    def info(self, path):
85+        self._lock.acquire()
86+        try:
87+            path = os.path.normpath(path)
88+            return self._cache[path]
89+        finally:
90+            self._lock.release()
91+    # info
92+
93+    def unload(self, path):
94+        self._lock.acquire()
95+        try:
96+            path = os.path.normpath(path)
97+            if path in self._cache:
98+                del self._cache[path]
99+        finally:
100+            self._lock.release()
101+    # unload
102+
103+    def freeze(self):
104+        self._frozen = True
105+    # freeze
106+
107+    def load(self, path, mode='r'):
108+        self._lock.acquire()
109+        try:
110+            record = None
111+            # ensure the path is normalised
112+            path = os.path.normpath(path)
113+            # is page template already loaded
114+            if path in self._cache:
115+                record = self._cache[path]
116+                # check if reloads have been disabled
117+                if not self._frozen:
118+                    # has page template been changed
119+                    try:
120+                        mtime = os.path.getmtime(path)
121+                    except:
122+                        # page template must not exist
123+                        del self._cache[path]
124+                        raise
125+                    else:
126+                        if record.mtime != mtime:
127+                            # force reloading of page template
128+                            del self._cache[path]
129+                            record = None
130+                        # if
131+                    # try
132+                # if
133+            # if
134+            # need to load the page template
135+            if record is None:
136+                content = self.do_load(path, mode)
137+                mtime = os.path.getmtime(path)
138+                record = _FileInfo(path, mtime, content)
139+                self._cache[path] = record
140+                return self.make_content(content)
141+            else:
142+                content = record.content
143+                record.hits += 1
144+                record.atime = time.time()
145+                return self.make_content(content)
146+            # if
147+        finally:
148+            self._lock.release()
149+        # try
150+    # load
151+
152+    def make_content(self, content):
153+        """ return content
154+            derived classes can override this
155+            to do some proccesing before returning data
156+        """
157+        return content
158+    # make_content
159+
160+    def do_load(self, path, mode):
161+        """ load file
162+            derived classes can override this
163+            to do some proccesing before storing data
164+            i.e. parse template and store parsed version in
165+            the cache
166+        """
167+        fhandle = file(path, mode)
168+        content = fhandle.read()
169+        fhandle.close()
170+        return content
171+    # do_load
172+# FileCache
173+
174+##################################################
175+## FUNCTIONS ##
176+
177+def get_cache(cache_name, cache_object=FileCache):
178+    """ return cache named cache_name
179+        using FileCache object cache_object (default FileCache)
180+    """
181+
182+    global _cache
183+
184+    if cache_name not in _cache:
185+        _cache[cache_name] = cache_object()
186+    return _cache[cache_name]
187+# get_cache
188+
189+def delete_cache(cache_name):
190+    """ delete cache cache_name,
191+        if cache does not exists, do nothing
192+    """
193+
194+    global _cache
195+
196+    if cache_name in _cache:
197+        del _cache[cache_name]
198+# delete_cache
199
200Property changes on: django/utils/filecache.py
201___________________________________________________________________
202Name: svn:mime-type
203   + text/plain
204Name: svn:keywords
205   + "Date Rev Author URL Id"
206Name: svn:eol-style
207   + LF
208