0001-general-revamp-static-file-serving-to-use-external-m.patch
wcs/ctl/collectstatic.py | ||
---|---|---|
1 |
# w.c.s. - web application for online forms |
|
2 |
# Copyright (C) 2005-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software; you can redistribute it and/or modify |
|
5 |
# it under the terms of the GNU General Public License as published by |
|
6 |
# the Free Software Foundation; either version 2 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU General Public License |
|
15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import os |
|
18 |
import shutil |
|
19 | ||
20 |
from qommon.ctl import Command, make_option |
|
21 | ||
22 | ||
23 |
class CmdCollectStatic(Command): |
|
24 |
name = 'collectstatic' |
|
25 | ||
26 |
def __init__(self): |
|
27 |
Command.__init__(self, [ |
|
28 |
make_option('-c', '--clear', action='store_true', |
|
29 |
dest='clear', default=False), |
|
30 |
make_option('-l', '--link', action='store_true', |
|
31 |
dest='link', default=False), |
|
32 |
]) |
|
33 | ||
34 |
def execute(self, base_options, sub_options, args): |
|
35 |
import publisher |
|
36 |
publisher.WcsPublisher.configure(self.config) |
|
37 |
pub = publisher.WcsPublisher.create_publisher( |
|
38 |
register_cron=False, register_tld_names=False) |
|
39 |
return self.collecstatic(pub, |
|
40 |
clear=sub_options.clear, link=sub_options.link) |
|
41 | ||
42 |
def collecstatic(self, pub, clear=False, link=False): |
|
43 |
root_directory_class = pub.root_directory_class |
|
44 |
static_dir = os.path.join(pub.app_dir, 'static') |
|
45 |
if clear and os.path.exists(static_dir): |
|
46 |
shutil.rmtree(static_dir) |
|
47 |
if not os.path.exists(static_dir): |
|
48 |
os.mkdir(static_dir) |
|
49 |
for prefix in root_directory_class.static_directories: |
|
50 |
for directory in root_directory_class.resolve_static_directories(prefix): |
|
51 |
if not os.path.exists(directory): |
|
52 |
continue |
|
53 |
real_prefix = prefix.replace('_', '/') # xstatic hack |
|
54 |
dst_base = os.path.join(static_dir, real_prefix) |
|
55 |
for basedir, dirnames, filenames in os.walk(directory): |
|
56 |
for filename in filenames: |
|
57 |
dst_path = os.path.join(dst_base, basedir[len(directory)+1:]) |
|
58 |
dst_filename = os.path.join(dst_path, filename) |
|
59 |
if not os.path.exists(dst_path): |
|
60 |
os.makedirs(dst_path) |
|
61 |
if os.path.exists(dst_filename): |
|
62 |
os.unlink(dst_filename) |
|
63 |
if link: |
|
64 |
os.symlink(os.path.join(basedir, filename), dst_filename) |
|
65 |
else: |
|
66 |
shutil.copy(os.path.join(basedir, filename), dst_filename) |
|
67 | ||
68 |
CmdCollectStatic.register() |
wcs/root.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU General Public License |
15 | 15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from importlib import import_module |
|
17 | 18 |
import json |
18 | 19 |
import os |
19 | 20 |
import re |
... | ... | |
207 | 208 |
pages = qommon.pages.PagesDirectory() |
208 | 209 |
fargo = file_validation.FargoDirectory() |
209 | 210 | |
211 |
static_directories = { |
|
212 |
'css': ['web/css'], |
|
213 |
'images': ['web/images'], |
|
214 |
'themes': ['web/themes'], |
|
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:font_awesome'], |
|
220 |
} |
|
221 | ||
210 | 222 |
def tryauth(self): |
211 | 223 |
return forms.root.tryauth(get_publisher().get_root_url()) |
212 | 224 | |
... | ... | |
287 | 299 |
if not self.backoffice: |
288 | 300 |
self.backoffice = get_publisher().backoffice_directory_class() |
289 | 301 | |
302 |
if path[:2] == ['static', 'xstatic']: |
|
303 |
# hack path so it's easier to lookup files from xstatic modules |
|
304 |
# (the gadjo xstatic storage adds a "xstatic" prefix that is not on |
|
305 |
# the filesystem, while StaticDirectory expects the filesystem |
|
306 |
# layout to match exactly; so we merge the first two elements in a |
|
307 |
# single one, so we get the real path in path[1:]) |
|
308 |
path = ['static_xstatic'] + path[2:] |
|
309 | ||
290 | 310 |
try: |
291 | 311 |
return Directory._q_traverse(self, path) |
292 | 312 |
except errors.TraversalError: |
... | ... | |
294 | 314 | |
295 | 315 |
return forms.root.RootDirectory()._q_traverse(path) |
296 | 316 | |
297 |
def _q_lookup(self, component): |
|
298 |
if component in ('css','images'): |
|
299 |
return StaticDirectory(os.path.join(get_publisher().data_dir, 'web', component), follow_symlinks = True) |
|
300 |
if component == 'qo': |
|
301 |
dirname = os.path.join(get_publisher().data_dir, 'qommon') |
|
302 |
return StaticDirectory(dirname, follow_symlinks = True) |
|
317 |
@classmethod |
|
318 |
def resolve_static_directories(cls, prefix): |
|
319 |
directories = cls.static_directories[prefix] |
|
320 |
for directory in directories: |
|
321 |
if directory[0] == '/': |
|
322 |
yield directory |
|
323 |
elif not ':' in directory: |
|
324 |
yield os.path.join(get_publisher().data_dir, directory) |
|
325 |
else: |
|
326 |
directory_type, value = directory.split(':') |
|
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 | ||
334 |
def serve_statics(self, component): |
|
335 |
for directory in self.resolve_static_directories(component): |
|
336 |
try: |
|
337 |
return StaticDirectory(directory, follow_symlinks=True) |
|
338 |
except errors.TraversalError: |
|
339 |
pass |
|
340 |
raise errors.TraversalError() |
|
303 | 341 | |
304 |
# maps /leaflet/ to the directory provided by the libjs-openlayers package
|
|
305 |
if component == 'leaflet':
|
|
306 |
return StaticDirectory('/usr/share/javascript/leaflet')
|
|
342 |
def _q_lookup(self, component):
|
|
343 |
if component in self.static_directories:
|
|
344 |
return self.serve_statics(component)
|
|
307 | 345 | |
308 | 346 |
# is this a category ? |
309 | 347 |
try: |
310 |
- |