103 |
104 |
104 def __init__(self, config): |
105 def __init__(self, config): |
105 self._resources = {} |
106 self._resources = {} |
106 self.config = config |
107 self.config = config |
107 self.logger = getLogger('cubicweb.web') |
108 self.logger = getLogger('cubicweb.web') |
|
109 self.lock = threading.Lock() |
108 |
110 |
109 def _resource(self, path): |
111 def _resource(self, path): |
110 """get the resouce""" |
112 """get the resouce""" |
111 try: |
113 try: |
112 return self._resources[path] |
114 return self._resources[path] |
141 return osp.join(self.config.appdatahome, 'uicache', fname) |
143 return osp.join(self.config.appdatahome, 'uicache', fname) |
142 |
144 |
143 def concat_cached_filepath(self, paths): |
145 def concat_cached_filepath(self, paths): |
144 filepath = self.build_filepath(paths) |
146 filepath = self.build_filepath(paths) |
145 if not self._up_to_date(filepath, paths): |
147 if not self._up_to_date(filepath, paths): |
146 with open(filepath, 'wb') as f: |
148 tmpfile = filepath + '.tmp' |
147 for path in paths: |
149 try: |
148 dirpath, rid = self._resource(path) |
150 with self.lock: |
149 if rid is None: |
151 if self._up_to_date(filepath, paths): |
150 # In production mode log an error, do not return a 404 |
152 # first check could have raced with some other thread |
151 # XXX the erroneous content is cached anyway |
153 # updating the file |
152 self.logger.error('concatenated data url error: %r file ' |
154 return filepath |
153 'does not exist', path) |
155 with open(tmpfile, 'wb') as f: |
154 if self.config.debugmode: |
156 for path in paths: |
155 raise NotFound(path) |
157 dirpath, rid = self._resource(path) |
156 else: |
158 if rid is None: |
157 with open(osp.join(dirpath, rid), 'rb') as source: |
159 # In production mode log an error, do not return a 404 |
158 for line in source: |
160 # XXX the erroneous content is cached anyway |
159 f.write(line) |
161 self.logger.error('concatenated data url error: %r file ' |
160 f.write('\n') |
162 'does not exist', path) |
|
163 if self.config.debugmode: |
|
164 raise NotFound(path) |
|
165 else: |
|
166 with open(osp.join(dirpath, rid), 'rb') as source: |
|
167 for line in source: |
|
168 f.write(line) |
|
169 f.write('\n') |
|
170 os.rename(tmpfile, filepath) |
|
171 except: |
|
172 os.remove(tmpfile) |
|
173 raise |
161 return filepath |
174 return filepath |
162 |
175 |
163 |
176 |
164 class DataController(StaticFileController): |
177 class DataController(StaticFileController): |
165 """Controller in charge of serving static file in /data/ |
178 """Controller in charge of serving static file in /data/ |