Mercurial > piecrust2
comparison piecrust/serving/util.py @ 852:4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
* Everything is a `ContentSource`, including assets directories.
* Most content sources are subclasses of the base file-system source.
* A source is processed by a "pipeline", and there are 2 built-in pipelines,
one for assets and one for pages. The asset pipeline is vaguely functional,
but the page pipeline is completely broken right now.
* Rewrite the baking process as just running appropriate pipelines on each
content item. This should allow for better parallelization.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 17 May 2017 00:11:48 -0700 |
parents | 673979a5d548 |
children | f070a4fc033c |
comparison
equal
deleted
inserted
replaced
851:2c7e57d80bba | 852:4850f8c21b6e |
---|---|
3 import hashlib | 3 import hashlib |
4 import logging | 4 import logging |
5 import datetime | 5 import datetime |
6 from werkzeug.wrappers import Response | 6 from werkzeug.wrappers import Response |
7 from werkzeug.wsgi import wrap_file | 7 from werkzeug.wsgi import wrap_file |
8 from piecrust.app import PieCrust, apply_variant_and_values | 8 from piecrust.page import QualifiedPage, PageNotFoundError |
9 from piecrust.rendering import QualifiedPage | |
10 from piecrust.routing import RouteNotFoundError | 9 from piecrust.routing import RouteNotFoundError |
11 from piecrust.sources.base import MODE_PARSING | |
12 from piecrust.sources.pageref import PageNotFoundError | |
13 from piecrust.uriutil import split_sub_uri | 10 from piecrust.uriutil import split_sub_uri |
14 | 11 |
15 | 12 |
16 logger = logging.getLogger(__name__) | 13 logger = logging.getLogger(__name__) |
17 | 14 |
25 | 22 |
26 class RequestedPage(object): | 23 class RequestedPage(object): |
27 def __init__(self): | 24 def __init__(self): |
28 self.qualified_page = None | 25 self.qualified_page = None |
29 self.req_path = None | 26 self.req_path = None |
30 self.page_num = 1 | |
31 self.not_found_errors = [] | 27 self.not_found_errors = [] |
32 | 28 |
33 | 29 |
34 def find_routes(routes, uri, is_sub_page=False): | 30 def find_routes(routes, uri, sub_num=1): |
35 """ Returns routes matching the given URL, but puts generator routes | 31 """ Returns routes matching the given URL. |
36 at the end. | |
37 """ | 32 """ |
38 res = [] | 33 res = [] |
39 gen_res = [] | |
40 for route in routes: | 34 for route in routes: |
41 metadata = route.matchUri(uri) | 35 route_params = route.matchUri(uri) |
42 if metadata is not None: | 36 if route_params is not None: |
43 if route.is_source_route: | 37 res.append((route, route_params, sub_num)) |
44 res.append((route, metadata, is_sub_page)) | 38 return res |
45 else: | |
46 gen_res.append((route, metadata, is_sub_page)) | |
47 return res + gen_res | |
48 | 39 |
49 | 40 |
50 def get_requested_page(app, req_path): | 41 def get_requested_page(app, req_path): |
51 # Remove the trailing slash to simplify how we parse URLs. | 42 # Remove the trailing slash to simplify how we parse URLs. |
52 root_url = app.config.get('site/root') | 43 root_url = app.config.get('site/root') |
58 | 49 |
59 # It could also be a sub-page (i.e. the URL ends with a page number), so | 50 # It could also be a sub-page (i.e. the URL ends with a page number), so |
60 # we try to also match the base URL (without the number). | 51 # we try to also match the base URL (without the number). |
61 req_path_no_num, page_num = split_sub_uri(app, req_path) | 52 req_path_no_num, page_num = split_sub_uri(app, req_path) |
62 if page_num > 1: | 53 if page_num > 1: |
63 routes += find_routes(app.routes, req_path_no_num, True) | 54 routes += find_routes(app.routes, req_path_no_num, page_num) |
64 | 55 |
65 if len(routes) == 0: | 56 if len(routes) == 0: |
66 raise RouteNotFoundError("Can't find route for: %s" % req_path) | 57 raise RouteNotFoundError("Can't find route for: %s" % req_path) |
67 | 58 |
68 req_page = RequestedPage() | 59 req_page = RequestedPage() |
69 for route, route_metadata, is_sub_page in routes: | 60 for route, route_params, route_sub_num in routes: |
70 try: | 61 cur_req_path = req_path |
71 cur_req_path = req_path | 62 if route_sub_num > 1: |
72 if is_sub_page: | 63 cur_req_path = req_path_no_num |
73 cur_req_path = req_path_no_num | |
74 | 64 |
75 qp = _get_requested_page_for_route( | 65 qp = _get_requested_page_for_route(app, route, route_params, |
76 app, route, route_metadata, cur_req_path) | 66 route_sub_num) |
77 if qp is not None: | 67 if qp is not None: |
78 req_page.qualified_page = qp | 68 req_page.qualified_page = qp |
79 req_page.req_path = cur_req_path | 69 req_page.req_path = cur_req_path |
80 if is_sub_page: | 70 break |
81 req_page.page_num = page_num | 71 |
82 break | 72 req_page.not_found_errors.append(PageNotFoundError( |
83 except PageNotFoundError as nfe: | 73 "No path found for '%s' in source '%s'." % |
84 req_page.not_found_errors.append(nfe) | 74 (cur_req_path, route.source_name))) |
75 | |
85 return req_page | 76 return req_page |
86 | 77 |
87 | 78 |
88 def _get_requested_page_for_route(app, route, route_metadata, req_path): | 79 def _get_requested_page_for_route(app, route, route_params, sub_num): |
89 if not route.is_generator_route: | 80 source = app.getSource(route.source_name) |
90 source = app.getSource(route.source_name) | 81 item = source.findContent(route_params) |
91 factory = source.findPageFactory(route_metadata, MODE_PARSING) | 82 if item is None: |
92 if factory is None: | 83 return None |
93 raise PageNotFoundError( | |
94 "No path found for '%s' in source '%s'." % | |
95 (req_path, source.name)) | |
96 else: | |
97 factory = route.generator.getPageFactory(route_metadata) | |
98 if factory is None: | |
99 raise PageNotFoundError( | |
100 "No path found for '%s' in generator '%s'." % | |
101 (req_path, route.generator.name)) | |
102 | 84 |
103 # Build the page. | 85 # Build the page. |
104 page = factory.buildPage() | 86 page = app.getPage(item) |
105 qp = QualifiedPage(page, route, route_metadata) | 87 qp = QualifiedPage(page, route, route_params, sub_num) |
106 return qp | 88 return qp |
107 | 89 |
108 | 90 |
109 def load_mimetype_map(): | 91 def load_mimetype_map(): |
110 mimetype_map = {} | 92 mimetype_map = {} |