general: serve all static files from /static/ (#11582)

This commit is contained in:
Frédéric Péters 2016-06-29 08:48:01 +02:00
parent 79ad86c349
commit 80b6308f80
13 changed files with 84 additions and 97 deletions

View File

@ -33,10 +33,13 @@ package installs a init.d script automatically.
ServerAdmin webmaster@example.com
ServerName www.example.com
DocumentRoot /usr/share/wcs/web/
Alias /qo/ /usr/share/wcs/qommon/
SCGIMount / 127.0.0.1:3001
<LocationMatch "^/(css|images|js|qo)/.*">
# this part allows serving static files directly from Apache, but it
# requires to run wcsctl.py collectstatic first.
Alias /static/ /var/lib/wcs/collectstatic/
<LocationMatch "^/static">
SCGIHandler off
</LocationMatch>

View File

@ -1,6 +1,6 @@
/* adapted from alto dotclear theme */
@import url(/qo/css/qommon.css);
@import url(/static/css/qommon.css);
html, body {
background: #CCCCCC;

View File

@ -3,10 +3,10 @@
<head>
<title>[page_title]</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, user-scalable=0">
<script type="text/javascript" src="[root_url]qo/js/jquery.js"></script>
<script type="text/javascript" src="[root_url]static/xstatic/jquery.js"></script>
[script]
<script type="text/javascript" src="[root_url]qo/js/wcs.mobile.js"></script>
<link rel="stylesheet" type="text/css" href="[root_url]qo/css/mobile.css"/>
<script type="text/javascript" src="[root_url]static/js/wcs.mobile.js"></script>
<link rel="stylesheet" type="text/css" href="[root_url]static/css/mobile.css"/>
<link rel="stylesheet" type="text/css" href="[theme_url]/mobile.css"/>
</head>
<body[if-any onload] onload="[onload]"[end]>

View File

@ -1,2 +1,2 @@
@import url(../qo/css/sofresh.css);
@import url(sofresh.css);

View File

@ -1,18 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>w.c.s.</title>
<link rel="stylesheet" type="text/css" href="/css/wcs.css"/>
<style type="text/css">
p#wcs {
margin-top: 30%;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<p id="wcs">
w.c.s
</p>
</body>
</html>

View File

@ -2,14 +2,20 @@
ServerAdmin webmaster@locahost
ServerName www.example.com
DocumentRoot /usr/share/wcs/web/
Alias /qo/ /usr/share/wcs/qommon/
SCGIMount / 127.0.0.1:3001
<LocationMatch "^/(css|images|js|qo)/.*">
Alias /static/ /var/lib/wcs/collectstatic/
<LocationMatch "^/static">
SCGIHandler off
</LocationMatch>
Alias /themes/ /usr/share/wcs/themes/
RewriteEngine On
RewriteCond /usr/share/wcs/%{REQUEST_URI} !-f
RewriteCond /usr/share/wcs/%{REQUEST_URI} !-d
RewriteRule ^/themes/(.*)$ /var/lib/wcs/%{HTTP_HOST}/themes/$1
CustomLog /var/log/apache2/wcs-access.log combined
ErrorLog /var/log/apache2/wcs-error.log
</VirtualHost>

View File

@ -21,5 +21,8 @@ def test_loading():
def test_collectstatic(pub):
CmdCollectStatic.collectstatic(pub)
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'wcs.css'))
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'qommon.css'))
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'gadjo.css'))
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'xstatic', 'jquery.js'))
CmdCollectStatic.collectstatic(pub, clear=True, link=True)
assert os.path.islink(os.path.join(pub.app_dir, 'collectstatic', 'css', 'wcs.css'))

View File

@ -150,14 +150,14 @@ def test_advertized_site_user_access():
assert 'authentication required' in output # locales ?
def test_static_directories():
assert get_app(pub).get('/css/wcs.css')
assert get_app(pub).get('/images/feed-icon-10x10.png')
assert get_app(pub).get('/qo/css/qommon.css')
assert get_app(pub).get('/static/css/wcs.css')
assert get_app(pub).get('/static/images/feed-icon-10x10.png')
assert get_app(pub).get('/static/css/qommon.css')
if os.path.exists('/usr/share/javascript/leaflet/'):
assert get_app(pub).get('/leaflet/leaflet.js')
assert get_app(pub).get('/static/leaflet/leaflet.js')
assert get_app(pub).get('/static/css/gadjo.css')
assert get_app(pub).get('/static/xstatic/jquery.js')
assert get_app(pub).get('/static/xstatic/jquery-ui.js')
assert 'Directory listing denied' in get_app(pub).get('/css/').body
assert 'Directory listing denied' in get_app(pub).get('/static/css/').body
assert get_app(pub).get('/static/xxx', status=404)

View File

@ -41,7 +41,8 @@ class CmdCollectStatic(Command):
@classmethod
def collectstatic(cls, pub, clear=False, link=False):
root_directory_class = pub.root_directory_class
from wcs.root import StaticsDirectory
root_directory_class = StaticsDirectory
static_dir = os.path.join(pub.app_dir, 'collectstatic')
if clear and os.path.exists(static_dir):
shutil.rmtree(static_dir)

View File

@ -60,18 +60,18 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
if not self.javascript_scripts:
self.javascript_scripts = []
mappings = {
'jquery.js': '../../static/xstatic/jquery.js',
'jquery-ui.js': '../../static/xstatic/jquery-ui.js',
'jquery.js': '../xstatic/jquery.js',
'jquery-ui.js': '../xstatic/jquery-ui.js',
}
for script_name in script_names:
mapped_script_name = mappings.get(script_name) or script_name
if not mapped_script_name in self.javascript_scripts:
if script_name == 'qommon.map.js':
self.add_javascript(['jquery.js'])
self.add_javascript(['../../leaflet/leaflet.js'])
self.add_css_include('../../leaflet/leaflet.css')
self.add_javascript(['../leaflet/leaflet.js'])
self.add_css_include('../leaflet/leaflet.css')
if script_name == 'jquery-ui.js':
self.add_css_include('../../static/xstatic/themes/smoothness/jquery-ui.min.css')
self.add_css_include('../xstatic/themes/smoothness/jquery-ui.min.css')
self.javascript_scripts.append(str(mapped_script_name))
if script_name == 'afterjob.js':
self.add_javascript_code('var QOMMON_ROOT_URL = "%s";\n' % \
@ -92,12 +92,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
if self.javascript_scripts:
root_url = get_publisher().get_root_url() + get_publisher().qommon_static_dir
s += '\n'.join(['<script type="text/javascript" src="%sjs/%s"></script>' % (
root_url, str(x)) for x in self.javascript_scripts
if not x[0] == '/'])
s += '\n'
s += '\n'.join(['<script type="text/javascript" src="%sjs/%s"></script>' % (
get_publisher().get_root_url(), x[1:]) for x in self.javascript_scripts
if x[0] == '/'])
root_url, str(x)) for x in self.javascript_scripts])
s += '\n'
if self.javascript_code_parts:
s += '<script type="text/javascript">'

View File

@ -81,7 +81,7 @@ class QommonPublisher(Publisher):
unpickler_class = None
after_login_url = ''
qommon_static_dir = 'qo/'
qommon_static_dir = 'static/'
qommon_admin_css = 'css/dc2/admin.css'
default_theme = 'default'

View File

@ -363,7 +363,7 @@ def decorate(body, response):
app_label = get_publisher().get_site_option('app_label') or 'w.c.s.'
else:
if current_theme == 'default':
css = root_url + 'css/%s.css' % get_publisher().APP_NAME
css = root_url + 'static/css/%s.css' % get_publisher().APP_NAME
else:
css = root_url + 'themes/%s/%s.css' % (current_theme, get_publisher().APP_NAME)

View File

@ -196,28 +196,64 @@ class RegisterDirectory(Directory):
return errors.TraversalError()
class StaticsDirectory(Directory):
static_directories = {
# maps /leaflet/ to the directory provided by the libjs-openlayers package
'leaflet': ['/usr/share/javascript/leaflet'],
'': ['web', 'qommon', 'django:gadjo'],
'xstatic': ['xstatic:jquery', 'xstatic:jquery_ui', 'xstatic:font_awesome'],
}
@classmethod
def resolve_static_directories(cls, prefix):
directories = cls.static_directories[prefix]
for directory in directories:
if directory[0] == '/':
yield directory
elif not ':' in directory:
yield os.path.join(get_publisher().data_dir, directory)
else:
directory_type, value = directory.split(':')
try:
if directory_type == 'xstatic':
module = import_module('xstatic.pkg.%s' % value)
yield module.BASE_DIR
elif directory_type == 'django':
module = import_module(value)
yield os.path.join(os.path.dirname(module.__file__), 'static')
except ImportError:
pass
def _q_traverse(self, path):
if path[0] in self.static_directories.keys():
prefix, rest = path[0], path[1:]
else:
prefix, rest = '', path
if not rest:
raise errors.AccessForbiddenError()
for directory in self.resolve_static_directories(prefix):
try:
return StaticDirectory(directory, follow_symlinks=True)._q_traverse(rest)
except errors.TraversalError:
continue
raise errors.TraversalError()
class RootDirectory(Directory):
_q_exports = ['admin', 'backoffice', 'forms', 'login', 'logout', 'saml',
'ident', 'register', 'afterjobs', 'themes', 'myspace', 'user', 'roles',
'pages', ('tmp-upload', 'tmp_upload'), 'api', '__version__',
'tryauth', 'auth', 'preview', ('reload-top', 'reload_top'),
'fargo', ('i18n.js', 'i18n_js')]
'fargo', ('i18n.js', 'i18n_js'), 'static']
api = ApiDirectory()
themes = template.ThemesDirectory()
myspace = MyspaceDirectory()
pages = qommon.pages.PagesDirectory()
fargo = file_validation.FargoDirectory()
static_directories = {
'css': ['web/css'],
'images': ['web/images'],
'qo': ['qommon'],
# maps /leaflet/ to the directory provided by the libjs-openlayers package
'leaflet': ['/usr/share/javascript/leaflet'],
'static': ['django:gadjo'],
'static_xstatic': ['xstatic:jquery', 'xstatic:jquery_ui', 'xstatic:font_awesome'],
}
static = StaticsDirectory()
def tryauth(self):
return forms.root.tryauth(get_publisher().get_root_url())
@ -303,9 +339,6 @@ class RootDirectory(Directory):
if not self.backoffice:
self.backoffice = get_publisher().backoffice_directory_class()
if path and path[0] in self.static_directories:
return self.serve_statics(path)
try:
return Directory._q_traverse(self, path)
except errors.TraversalError:
@ -313,42 +346,6 @@ class RootDirectory(Directory):
return forms.root.RootDirectory()._q_traverse(path)
@classmethod
def resolve_static_directories(cls, prefix):
directories = cls.static_directories[prefix]
for directory in directories:
if directory[0] == '/':
yield directory
elif not ':' in directory:
yield os.path.join(get_publisher().data_dir, directory)
else:
directory_type, value = directory.split(':')
try:
if directory_type == 'xstatic':
module = import_module('xstatic.pkg.%s' % value)
yield module.BASE_DIR
elif directory_type == 'django':
module = import_module(value)
yield os.path.join(os.path.dirname(module.__file__), 'static')
except ImportError:
pass
def serve_statics(self, path):
if path[:2] == ['static', 'xstatic']:
# hack path so it's easier to lookup files from xstatic modules
# (the gadjo xstatic storage adds a "xstatic" prefix that is not on
# the filesystem, while StaticDirectory expects the filesystem
# layout to match exactly; so we merge the first two elements in a
# single one, so we get the real path in path[1:])
path = ['static_xstatic'] + path[2:]
for directory in self.resolve_static_directories(path[0]):
try:
return StaticDirectory(directory, follow_symlinks=True)._q_traverse(path[1:])
except errors.TraversalError:
continue
raise errors.TraversalError()
def _q_lookup(self, component):
# is this a category ?
try: