0001-general-serve-all-static-files-from-static-11582.patch
tests/test_ctl.py | ||
---|---|---|
21 | 21 |
def test_collectstatic(pub): |
22 | 22 |
CmdCollectStatic.collectstatic(pub) |
23 | 23 |
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'wcs.css')) |
24 |
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'qommon.css')) |
|
25 |
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'gadjo.css')) |
|
26 |
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'xstatic', 'jquery.js')) |
|
24 | 27 |
CmdCollectStatic.collectstatic(pub, clear=True, link=True) |
25 | 28 |
assert os.path.islink(os.path.join(pub.app_dir, 'collectstatic', 'css', 'wcs.css')) |
tests/test_rootdirectory.py | ||
---|---|---|
150 | 150 |
assert 'authentication required' in output # locales ? |
151 | 151 | |
152 | 152 |
def test_static_directories(): |
153 |
assert get_app(pub).get('/css/wcs.css') |
|
154 |
assert get_app(pub).get('/images/feed-icon-10x10.png') |
|
155 |
assert get_app(pub).get('/qo/css/qommon.css')
|
|
153 |
assert get_app(pub).get('/static/css/wcs.css')
|
|
154 |
assert get_app(pub).get('/static/images/feed-icon-10x10.png')
|
|
155 |
assert get_app(pub).get('/static/css/qommon.css')
|
|
156 | 156 |
if os.path.exists('/usr/share/javascript/leaflet/'): |
157 |
assert get_app(pub).get('/leaflet/leaflet.js') |
|
157 |
assert get_app(pub).get('/static/leaflet/leaflet.js')
|
|
158 | 158 |
assert get_app(pub).get('/static/css/gadjo.css') |
159 | 159 |
assert get_app(pub).get('/static/xstatic/jquery.js') |
160 | 160 |
assert get_app(pub).get('/static/xstatic/jquery-ui.js') |
161 | 161 | |
162 |
assert 'Directory listing denied' in get_app(pub).get('/css/').body |
|
162 |
assert 'Directory listing denied' in get_app(pub).get('/static/css/').body
|
|
163 | 163 |
assert get_app(pub).get('/static/xxx', status=404) |
wcs/ctl/collectstatic.py | ||
---|---|---|
41 | 41 | |
42 | 42 |
@classmethod |
43 | 43 |
def collectstatic(cls, pub, clear=False, link=False): |
44 |
root_directory_class = pub.root_directory_class |
|
44 |
from wcs.root import StaticsDirectory |
|
45 |
root_directory_class = StaticsDirectory |
|
45 | 46 |
static_dir = os.path.join(pub.app_dir, 'collectstatic') |
46 | 47 |
if clear and os.path.exists(static_dir): |
47 | 48 |
shutil.rmtree(static_dir) |
wcs/qommon/http_response.py | ||
---|---|---|
60 | 60 |
if not self.javascript_scripts: |
61 | 61 |
self.javascript_scripts = [] |
62 | 62 |
mappings = { |
63 |
'jquery.js': '../../static/xstatic/jquery.js',
|
|
64 |
'jquery-ui.js': '../../static/xstatic/jquery-ui.js',
|
|
63 |
'jquery.js': '../xstatic/jquery.js', |
|
64 |
'jquery-ui.js': '../xstatic/jquery-ui.js', |
|
65 | 65 |
} |
66 | 66 |
for script_name in script_names: |
67 | 67 |
mapped_script_name = mappings.get(script_name) or script_name |
68 | 68 |
if not mapped_script_name in self.javascript_scripts: |
69 | 69 |
if script_name == 'qommon.map.js': |
70 | 70 |
self.add_javascript(['jquery.js']) |
71 |
self.add_javascript(['../../leaflet/leaflet.js'])
|
|
72 |
self.add_css_include('../../leaflet/leaflet.css')
|
|
71 |
self.add_javascript(['../leaflet/leaflet.js']) |
|
72 |
self.add_css_include('../leaflet/leaflet.css') |
|
73 | 73 |
if script_name == 'jquery-ui.js': |
74 |
self.add_css_include('../../static/xstatic/themes/smoothness/jquery-ui.min.css')
|
|
74 |
self.add_css_include('../xstatic/themes/smoothness/jquery-ui.min.css') |
|
75 | 75 |
self.javascript_scripts.append(str(mapped_script_name)) |
76 | 76 |
if script_name == 'afterjob.js': |
77 | 77 |
self.add_javascript_code('var QOMMON_ROOT_URL = "%s";\n' % \ |
... | ... | |
92 | 92 |
if self.javascript_scripts: |
93 | 93 |
root_url = get_publisher().get_root_url() + get_publisher().qommon_static_dir |
94 | 94 |
s += '\n'.join(['<script type="text/javascript" src="%sjs/%s"></script>' % ( |
95 |
root_url, str(x)) for x in self.javascript_scripts |
|
96 |
if not x[0] == '/']) |
|
97 |
s += '\n' |
|
98 |
s += '\n'.join(['<script type="text/javascript" src="%sjs/%s"></script>' % ( |
|
99 |
get_publisher().get_root_url(), x[1:]) for x in self.javascript_scripts |
|
100 |
if x[0] == '/']) |
|
95 |
root_url, str(x)) for x in self.javascript_scripts]) |
|
101 | 96 |
s += '\n' |
102 | 97 |
if self.javascript_code_parts: |
103 | 98 |
s += '<script type="text/javascript">' |
wcs/qommon/publisher.py | ||
---|---|---|
81 | 81 |
unpickler_class = None |
82 | 82 | |
83 | 83 |
after_login_url = '' |
84 |
qommon_static_dir = 'qo/'
|
|
84 |
qommon_static_dir = 'static/'
|
|
85 | 85 |
qommon_admin_css = 'css/dc2/admin.css' |
86 | 86 |
default_theme = 'default' |
87 | 87 |
wcs/root.py | ||
---|---|---|
196 | 196 |
return errors.TraversalError() |
197 | 197 | |
198 | 198 | |
199 |
class StaticsDirectory(Directory): |
|
200 |
static_directories = { |
|
201 |
# maps /leaflet/ to the directory provided by the libjs-openlayers package |
|
202 |
'leaflet': ['/usr/share/javascript/leaflet'], |
|
203 |
'': ['web', 'qommon', 'django:gadjo'], |
|
204 |
'xstatic': ['xstatic:jquery', 'xstatic:jquery_ui', 'xstatic:font_awesome'], |
|
205 |
} |
|
206 | ||
207 |
@classmethod |
|
208 |
def resolve_static_directories(cls, prefix): |
|
209 |
directories = cls.static_directories[prefix] |
|
210 |
for directory in directories: |
|
211 |
if directory[0] == '/': |
|
212 |
yield directory |
|
213 |
elif not ':' in directory: |
|
214 |
yield os.path.join(get_publisher().data_dir, directory) |
|
215 |
else: |
|
216 |
directory_type, value = directory.split(':') |
|
217 |
try: |
|
218 |
if directory_type == 'xstatic': |
|
219 |
module = import_module('xstatic.pkg.%s' % value) |
|
220 |
yield module.BASE_DIR |
|
221 |
elif directory_type == 'django': |
|
222 |
module = import_module(value) |
|
223 |
yield os.path.join(os.path.dirname(module.__file__), 'static') |
|
224 |
except ImportError: |
|
225 |
pass |
|
226 | ||
227 |
def _q_traverse(self, path): |
|
228 |
if path[0] in self.static_directories.keys(): |
|
229 |
prefix, rest = path[0], path[1:] |
|
230 |
else: |
|
231 |
prefix, rest = '', path |
|
232 | ||
233 |
if not rest: |
|
234 |
raise errors.AccessForbiddenError() |
|
235 | ||
236 |
for directory in self.resolve_static_directories(prefix): |
|
237 |
try: |
|
238 |
return StaticDirectory(directory, follow_symlinks=True)._q_traverse(rest) |
|
239 |
except errors.TraversalError: |
|
240 |
continue |
|
241 |
raise errors.TraversalError() |
|
242 | ||
243 | ||
199 | 244 |
class RootDirectory(Directory): |
200 | 245 |
_q_exports = ['admin', 'backoffice', 'forms', 'login', 'logout', 'saml', |
201 | 246 |
'ident', 'register', 'afterjobs', 'themes', 'myspace', 'user', 'roles', |
202 | 247 |
'pages', ('tmp-upload', 'tmp_upload'), 'api', '__version__', |
203 | 248 |
'tryauth', 'auth', 'preview', ('reload-top', 'reload_top'), |
204 |
'fargo', ('i18n.js', 'i18n_js')] |
|
249 |
'fargo', ('i18n.js', 'i18n_js'), 'static']
|
|
205 | 250 | |
206 | 251 |
api = ApiDirectory() |
207 | 252 |
themes = template.ThemesDirectory() |
208 | 253 |
myspace = MyspaceDirectory() |
209 | 254 |
pages = qommon.pages.PagesDirectory() |
210 | 255 |
fargo = file_validation.FargoDirectory() |
211 | ||
212 |
static_directories = { |
|
213 |
'css': ['web/css'], |
|
214 |
'images': ['web/images'], |
|
215 |
'qo': ['qommon'], |
|
216 |
# maps /leaflet/ to the directory provided by the libjs-openlayers package |
|
217 |
'leaflet': ['/usr/share/javascript/leaflet'], |
|
218 |
'static': ['django:gadjo'], |
|
219 |
'static_xstatic': ['xstatic:jquery', 'xstatic:jquery_ui', 'xstatic:font_awesome'], |
|
220 |
} |
|
256 |
static = StaticsDirectory() |
|
221 | 257 | |
222 | 258 |
def tryauth(self): |
223 | 259 |
return forms.root.tryauth(get_publisher().get_root_url()) |
... | ... | |
303 | 339 |
if not self.backoffice: |
304 | 340 |
self.backoffice = get_publisher().backoffice_directory_class() |
305 | 341 | |
306 |
if path and path[0] in self.static_directories: |
|
307 |
return self.serve_statics(path) |
|
308 | ||
309 | 342 |
try: |
310 | 343 |
return Directory._q_traverse(self, path) |
311 | 344 |
except errors.TraversalError: |
... | ... | |
313 | 346 | |
314 | 347 |
return forms.root.RootDirectory()._q_traverse(path) |
315 | 348 | |
316 |
@classmethod |
|
317 |
def resolve_static_directories(cls, prefix): |
|
318 |
directories = cls.static_directories[prefix] |
|
319 |
for directory in directories: |
|
320 |
if directory[0] == '/': |
|
321 |
yield directory |
|
322 |
elif not ':' in directory: |
|
323 |
yield os.path.join(get_publisher().data_dir, directory) |
|
324 |
else: |
|
325 |
directory_type, value = directory.split(':') |
|
326 |
try: |
|
327 |
if directory_type == 'xstatic': |
|
328 |
module = import_module('xstatic.pkg.%s' % value) |
|
329 |
yield module.BASE_DIR |
|
330 |
elif directory_type == 'django': |
|
331 |
module = import_module(value) |
|
332 |
yield os.path.join(os.path.dirname(module.__file__), 'static') |
|
333 |
except ImportError: |
|
334 |
pass |
|
335 | ||
336 |
def serve_statics(self, path): |
|
337 |
if path[:2] == ['static', 'xstatic']: |
|
338 |
# hack path so it's easier to lookup files from xstatic modules |
|
339 |
# (the gadjo xstatic storage adds a "xstatic" prefix that is not on |
|
340 |
# the filesystem, while StaticDirectory expects the filesystem |
|
341 |
# layout to match exactly; so we merge the first two elements in a |
|
342 |
# single one, so we get the real path in path[1:]) |
|
343 |
path = ['static_xstatic'] + path[2:] |
|
344 | ||
345 |
for directory in self.resolve_static_directories(path[0]): |
|
346 |
try: |
|
347 |
return StaticDirectory(directory, follow_symlinks=True)._q_traverse(path[1:]) |
|
348 |
except errors.TraversalError: |
|
349 |
continue |
|
350 |
raise errors.TraversalError() |
|
351 | ||
352 | 349 |
def _q_lookup(self, component): |
353 | 350 |
# is this a category ? |
354 | 351 |
try: |
355 |
- |