20 __docformat__ = "restructuredtext en" |
20 __docformat__ = "restructuredtext en" |
21 |
21 |
22 import re |
22 import re |
23 import os |
23 import os |
24 import os.path as osp |
24 import os.path as osp |
|
25 import tempfile |
|
26 |
25 |
27 |
26 TYPE_CHECKS = [('STYLESHEETS', list), ('JAVASCRIPTS', list), |
28 TYPE_CHECKS = [('STYLESHEETS', list), ('JAVASCRIPTS', list), |
27 ('STYLESHEETS_IE', list), ('STYLESHEETS_PRINT', list), |
29 ('STYLESHEETS_IE', list), ('STYLESHEETS_PRINT', list), |
28 ] |
30 ] |
29 |
31 |
50 def reset(self): |
52 def reset(self): |
51 self.clear() |
53 self.clear() |
52 self._ordered_propfiles = [] |
54 self._ordered_propfiles = [] |
53 self._propfile_mtime = {} |
55 self._propfile_mtime = {} |
54 self._sourcefile_mtime = {} |
56 self._sourcefile_mtime = {} |
55 self._cache = {} |
|
56 |
57 |
57 def load(self, fpath): |
58 def load(self, fpath): |
58 scriptglobals = self.context.copy() |
59 scriptglobals = self.context.copy() |
59 scriptglobals['__file__'] = fpath |
60 scriptglobals['__file__'] = fpath |
60 with open(fpath, 'rb') as fobj: |
61 with open(fpath, 'rb') as fobj: |
67 raise Exception(msg) |
68 raise Exception(msg) |
68 self._propfile_mtime[fpath] = os.stat(fpath).st_mtime |
69 self._propfile_mtime[fpath] = os.stat(fpath).st_mtime |
69 self._ordered_propfiles.append(fpath) |
70 self._ordered_propfiles.append(fpath) |
70 |
71 |
71 def need_reload(self): |
72 def need_reload(self): |
72 for rid, (adirectory, rdirectory, mtime) in list(self._cache.items()): |
|
73 if os.stat(osp.join(rdirectory, rid)).st_mtime > mtime: |
|
74 del self._cache[rid] |
|
75 for fpath, mtime in self._propfile_mtime.items(): |
73 for fpath, mtime in self._propfile_mtime.items(): |
76 if os.stat(fpath).st_mtime > mtime: |
74 if os.stat(fpath).st_mtime > mtime: |
77 return True |
75 return True |
78 return False |
76 return False |
79 |
77 |
86 def reload_if_needed(self): |
84 def reload_if_needed(self): |
87 if self.need_reload(): |
85 if self.need_reload(): |
88 self.reload() |
86 self.reload() |
89 |
87 |
90 def process_resource(self, rdirectory, rid): |
88 def process_resource(self, rdirectory, rid): |
|
89 cachefile = osp.join(self._cache_directory, rid) |
|
90 self.debug('processing %s/%s into %s', |
|
91 rdirectory, rid, cachefile) |
|
92 rcachedir = osp.dirname(cachefile) |
|
93 if not osp.exists(rcachedir): |
|
94 os.makedirs(rcachedir) |
|
95 sourcefile = osp.join(rdirectory, rid) |
|
96 with open(sourcefile) as f: |
|
97 content = f.read() |
|
98 # XXX replace % not followed by a paren by %% to avoid having to do |
|
99 # this in the source css file ? |
91 try: |
100 try: |
92 return self._cache[rid][0] |
101 content = self.compile(content) |
93 except KeyError: |
102 except ValueError as ex: |
94 cachefile = osp.join(self._cache_directory, rid) |
103 self.error("can't process %s/%s: %s", rdirectory, rid, ex) |
95 self.debug('caching processed %s/%s into %s', |
104 adirectory = rdirectory |
96 rdirectory, rid, cachefile) |
105 else: |
97 rcachedir = osp.dirname(cachefile) |
106 tmpfd, tmpfile = tempfile.mkstemp(dir=rcachedir, prefix=osp.basename(cachefile)) |
98 if not osp.exists(rcachedir): |
107 with os.fdopen(tmpfd, 'w') as stream: |
99 os.makedirs(rcachedir) |
|
100 sourcefile = osp.join(rdirectory, rid) |
|
101 content = open(sourcefile).read() |
|
102 # XXX replace % not followed by a paren by %% to avoid having to do |
|
103 # this in the source css file ? |
|
104 try: |
|
105 content = self.compile(content) |
|
106 except ValueError as ex: |
|
107 self.error("can't process %s/%s: %s", rdirectory, rid, ex) |
|
108 adirectory = rdirectory |
|
109 else: |
|
110 stream = open(cachefile, 'w') |
|
111 stream.write(content) |
108 stream.write(content) |
112 stream.close() |
109 os.rename(tmpfile, cachefile) |
113 adirectory = self._cache_directory |
110 adirectory = self._cache_directory |
114 self._cache[rid] = (adirectory, rdirectory, os.stat(sourcefile).st_mtime) |
111 return adirectory |
115 return adirectory |
|
116 |
112 |
117 def compile(self, content): |
113 def compile(self, content): |
118 return self._percent_rgx.sub('%%', content) % self |
114 return self._percent_rgx.sub('%%', content) % self |
119 |
115 |
120 # these are overridden by set_log_methods below |
116 # these are overridden by set_log_methods below |