allow for serving files directly inside pages/
This commit is contained in:
parent
757b067e16
commit
ced67bec8b
@ -6,7 +6,7 @@ import re
|
||||
|
||||
from flask import Blueprint, Markup, abort
|
||||
from flask import current_app as app
|
||||
from flask import redirect, request
|
||||
from flask import redirect, request, send_from_directory
|
||||
from tzlocal import get_localzone
|
||||
|
||||
from incorporealcms.lib import get_meta_str, init_md, render
|
||||
@ -21,7 +21,7 @@ bp = Blueprint('pages', __name__, url_prefix='/')
|
||||
def display_page(path):
|
||||
"""Get the file contents of the requested path and render the file."""
|
||||
try:
|
||||
resolved_path = request_path_to_instance_resource_path(path)
|
||||
resolved_path, render_md = request_path_to_instance_resource_path(path)
|
||||
logger.debug("received request for path '%s', resolved to '%s'", path, resolved_path)
|
||||
except PermissionError:
|
||||
abort(400)
|
||||
@ -30,6 +30,9 @@ def display_page(path):
|
||||
except FileNotFoundError:
|
||||
abort(404)
|
||||
|
||||
if not render_md:
|
||||
return send_from_directory(app.instance_path, resolved_path)
|
||||
|
||||
try:
|
||||
with app.open_instance_resource(resolved_path, 'r') as entry_file:
|
||||
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(entry_file.name), get_localzone())
|
||||
@ -76,21 +79,23 @@ def request_path_to_instance_resource_path(path):
|
||||
logger.info("client requested a path '%s' that is actually a directory", path)
|
||||
raise IsADirectoryError
|
||||
|
||||
# derive the proper markdown file depending on if this is a dir or file
|
||||
# derive the proper markdown or actual file depending on if this is a dir or file
|
||||
if os.path.isdir(resolved_path):
|
||||
absolute_resource = os.path.join(resolved_path, 'index.md')
|
||||
elif os.path.exists(resolved_path):
|
||||
logger.info("final DIRECT path = '%s' for request '%s'", resolved_path, path)
|
||||
return resolved_path.replace(f'{app.instance_path}{os.path.sep}', ''), False
|
||||
else:
|
||||
absolute_resource = f'{resolved_path}.md'
|
||||
|
||||
logger.info("final path = '%s' for request '%s'", absolute_resource, path)
|
||||
|
||||
# does the final file actually exist?
|
||||
if not os.path.exists(absolute_resource):
|
||||
logger.warning("requested final path '%s' does not exist!", absolute_resource)
|
||||
raise FileNotFoundError
|
||||
|
||||
logger.info("final path = '%s' for request '%s'", absolute_resource, path)
|
||||
# we checked that the file exists via absolute path, but now we need to give the path relative to instance dir
|
||||
return absolute_resource.replace(f'{app.instance_path}{os.path.sep}', '')
|
||||
return absolute_resource.replace(f'{app.instance_path}{os.path.sep}', ''), True
|
||||
|
||||
|
||||
def instance_resource_path_to_request_path(path):
|
||||
|
@ -9,6 +9,13 @@ def test_page_that_exists(client):
|
||||
assert b'<h1>test index</h1>' in response.data
|
||||
|
||||
|
||||
def test_direct_file_that_exists(client):
|
||||
"""Test that the app can serve a basic file at the index."""
|
||||
response = client.get('/foo.txt')
|
||||
assert response.status_code == 200
|
||||
assert b'test file' in response.data
|
||||
|
||||
|
||||
def test_page_that_doesnt_exist(client):
|
||||
"""Test that the app returns 404 for nonsense requests and they use my error page."""
|
||||
response = client.get('/ohuesthaoeusth')
|
||||
|
BIN
tests/instance/pages/bss-square-no-bg.png
Normal file
BIN
tests/instance/pages/bss-square-no-bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
1
tests/instance/pages/foo.txt
Normal file
1
tests/instance/pages/foo.txt
Normal file
@ -0,0 +1 @@
|
||||
test file
|
@ -60,44 +60,45 @@ def test_render_with_no_user_theme(app):
|
||||
def test_request_path_to_instance_resource_path(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('index') == 'pages/index.md'
|
||||
assert request_path_to_instance_resource_path('index') == ('pages/index.md', True)
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_direct_file(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('no-title') == 'pages/no-title.md'
|
||||
assert request_path_to_instance_resource_path('no-title') == ('pages/no-title.md', True)
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_in_subdir(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('subdir/page') == 'pages/subdir/page.md'
|
||||
assert request_path_to_instance_resource_path('subdir/page') == ('pages/subdir/page.md', True)
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_subdir_index(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('subdir/') == 'pages/subdir/index.md'
|
||||
assert request_path_to_instance_resource_path('subdir/') == ('pages/subdir/index.md', True)
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_relatives_walked(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert (request_path_to_instance_resource_path('subdir/more-subdir/../../more-metadata') ==
|
||||
'pages/more-metadata.md')
|
||||
('pages/more-metadata.md', True))
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_relatives_walked_indexes_work_too(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('subdir/more-subdir/../../') == 'pages/index.md'
|
||||
assert request_path_to_instance_resource_path('subdir/more-subdir/../../') == ('pages/index.md', True)
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_relatives_walked_into_subdirs_also_fine(app):
|
||||
"""Test a normal URL request is transformed into the file path."""
|
||||
with app.test_request_context():
|
||||
assert request_path_to_instance_resource_path('subdir/more-subdir/../../subdir/page') == 'pages/subdir/page.md'
|
||||
assert (request_path_to_instance_resource_path('subdir/more-subdir/../../subdir/page') ==
|
||||
('pages/subdir/page.md', True))
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_permission_error_on_ref_above_pages(app):
|
||||
@ -114,6 +115,13 @@ def test_request_path_to_instance_resource_path_isadirectory_on_file_like_req_fo
|
||||
assert request_path_to_instance_resource_path('subdir')
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_actual_file(app):
|
||||
"""Test that a request for e.g. '/foo.png' when foo.png is a real file works."""
|
||||
with app.test_request_context():
|
||||
assert (request_path_to_instance_resource_path('bss-square-no-bg.png') ==
|
||||
('pages/bss-square-no-bg.png', False))
|
||||
|
||||
|
||||
def test_request_path_to_instance_resource_path_nonexistant_file_errors(app):
|
||||
"""Test that a request for something not on disk errors."""
|
||||
with app.test_request_context():
|
||||
@ -155,13 +163,15 @@ def test_instance_resource_path_to_request_path_on_subdir_and_page(app):
|
||||
def test_request_resource_request_root(app):
|
||||
"""Test that a request can resolve to a resource and back to a request."""
|
||||
with app.test_request_context():
|
||||
instance_resource_path_to_request_path(request_path_to_instance_resource_path('index')) == ''
|
||||
instance_path, _ = request_path_to_instance_resource_path('index')
|
||||
instance_resource_path_to_request_path(instance_path) == ''
|
||||
|
||||
|
||||
def test_request_resource_request_page(app):
|
||||
"""Test that a request can resolve to a resource and back to a request."""
|
||||
with app.test_request_context():
|
||||
instance_resource_path_to_request_path(request_path_to_instance_resource_path('no-title')) == 'no-title'
|
||||
instance_path, _ = request_path_to_instance_resource_path('no-title')
|
||||
instance_resource_path_to_request_path(instance_path) == 'no-title'
|
||||
|
||||
|
||||
def test_request_path_to_breadcrumb_display_patterns():
|
||||
|
Loading…
x
Reference in New Issue
Block a user