add the ability to redirect a file-looking request to a dir
if the client has requested /foo, and foo is actually a directory, this redirects the client to /foo/
This commit is contained in:
		
							parent
							
								
									cf8f0325a2
								
							
						
					
					
						commit
						0f7495bf2b
					
				| @ -6,7 +6,7 @@ import os | |||||||
| import markdown | import markdown | ||||||
| from flask import Blueprint, Markup, abort | from flask import Blueprint, Markup, abort | ||||||
| from flask import current_app as app | from flask import current_app as app | ||||||
| from flask import render_template | from flask import redirect, render_template | ||||||
| from tzlocal import get_localzone | from tzlocal import get_localzone | ||||||
| 
 | 
 | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| @ -19,6 +19,9 @@ md = markdown.Markdown(extensions=['meta', 'tables']) | |||||||
| @bp.route('/<path:path>') | @bp.route('/<path:path>') | ||||||
| def display_page(path): | def display_page(path): | ||||||
|     """Get the file contents of the requested path and render the file.""" |     """Get the file contents of the requested path and render the file.""" | ||||||
|  |     if is_file_path_actually_dir_path(path): | ||||||
|  |         return redirect(f'{path}/', code=301) | ||||||
|  | 
 | ||||||
|     resolved_path = resolve_page_file(path) |     resolved_path = resolve_page_file(path) | ||||||
|     logger.debug("received request for path '%s', resolved to '%s'", path, resolved_path) |     logger.debug("received request for path '%s', resolved to '%s'", path, resolved_path) | ||||||
|     try: |     try: | ||||||
| @ -52,6 +55,22 @@ def resolve_page_file(path): | |||||||
|     return path |     return path | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def is_file_path_actually_dir_path(path): | ||||||
|  |     """Check if requested path which looks like a file is actually a directory. | ||||||
|  | 
 | ||||||
|  |     If, for example, /foo used to be a file (foo.md) which later became a directory, | ||||||
|  |     foo/, this returns True. Useful for when I make my structure more complicated | ||||||
|  |     than it originally was, or if users are just weird. | ||||||
|  |     """ | ||||||
|  |     if not path.endswith('/'): | ||||||
|  |         logger.debug("requested path '%s' looks like a file", path) | ||||||
|  |         if os.path.isdir(f'{app.instance_path}/pages/{path}'): | ||||||
|  |             logger.debug("...and it's actually a dir") | ||||||
|  |             return True | ||||||
|  | 
 | ||||||
|  |     return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def generate_parent_navs(path): | def generate_parent_navs(path): | ||||||
|     """Create a series of paths/links to navigate up from the given path.""" |     """Create a series of paths/links to navigate up from the given path.""" | ||||||
|     # derive additional path/location stuff based on path |     # derive additional path/location stuff based on path | ||||||
|  | |||||||
| @ -35,3 +35,20 @@ def test_page_has_modified_timestamp(client): | |||||||
|     response = client.get('/') |     response = client.get('/') | ||||||
|     assert response.status_code == 200 |     assert response.status_code == 200 | ||||||
|     assert re.search(r'Last modified: ....-..-.. ..:..:.. ...', response.data.decode()) is not None |     assert re.search(r'Last modified: ....-..-.. ..:..:.. ...', response.data.decode()) is not None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_that_page_request_redirects_to_directory(client): | ||||||
|  |     """Test that a request to /foo reirects to /foo/, if foo is a directory. | ||||||
|  | 
 | ||||||
|  |     This might be useful in cases where a formerly page-only page has been | ||||||
|  |     converted to a directory with subpages. | ||||||
|  |     """ | ||||||
|  |     response = client.get('/subdir') | ||||||
|  |     assert response.status_code == 301 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_that_dir_request_does_not_redirect(client): | ||||||
|  |     """Test that a request to /foo/ serves the index page, if foo is a directory.""" | ||||||
|  |     response = client.get('/subdir/') | ||||||
|  |     assert response.status_code == 200 | ||||||
|  |     assert b'another page' in response.data | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| """Unit test helper methods.""" | """Unit test helper methods.""" | ||||||
| from incorporealcms.pages import generate_parent_navs, resolve_page_file | from incorporealcms.pages import generate_parent_navs, is_file_path_actually_dir_path, resolve_page_file | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_resolve_page_file_dir_to_index(): | def test_resolve_page_file_dir_to_index(): | ||||||
| @ -50,3 +50,27 @@ def test_generate_page_navs_subdir_with_title_parsing_real_page(app): | |||||||
|             ('SUB!', '/subdir-with-title/'), |             ('SUB!', '/subdir-with-title/'), | ||||||
|             ('/subdir-with-title/page', '/subdir-with-title/page') |             ('/subdir-with-title/page', '/subdir-with-title/page') | ||||||
|         ] |         ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_is_file_path_actually_dir_path_valid_file_is_yes(app): | ||||||
|  |     """Test that a file request for what's actually a directory is detected as such.""" | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert is_file_path_actually_dir_path('/subdir') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_is_file_path_actually_dir_path_valid_dir_is_no(app): | ||||||
|  |     """Test that a directory request is still a directory request.""" | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert not is_file_path_actually_dir_path('/subdir/') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_is_file_path_actually_dir_path_nonsense_file_is_no(app): | ||||||
|  |     """Test that requests to nonsense file-looking paths aren't treated as dirs.""" | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert not is_file_path_actually_dir_path('/antphnathpnthapnthsnthax') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_is_file_path_actually_dir_path_nonsense_dir_is_no(app): | ||||||
|  |     """Test that a directory request is a directory request even if the dir doesn't exist.""" | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert not is_file_path_actually_dir_path('/antphnathpnthapnthsnthax/') | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user