annotate piecrust/routing.py @ 1145:e94737572542

serve: Fix an issue where false positive matches were rendered as the requested page. Now we try to render the page, but also try to detect for the most common "empty" pages.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 05 Jun 2018 22:08:51 -0700
parents 1ce67d2fae0a
children 6baa94da8b16
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import re
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
2 import os.path
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
3 import copy
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 import logging
520
bab91fcef741 bake/serve: Improve support for unicode, add slugification options.
Ludovic Chabant <ludovic@chabant.com>
parents: 515
diff changeset
5 import urllib.parse
711
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
6 from werkzeug.utils import cached_property
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
12 route_re = re.compile(r'%((?P<qual>[\w\d]+):)?(?P<var>\+)?(?P<name>\w+)%')
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
13 route_esc_re = re.compile(
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
14 r'\\%((?P<qual>[\w\d]+)\\:)?(?P<var>\\\+)?(?P<name>\w+)\\%')
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
15 ugly_url_cleaner = re.compile(r'\.html$')
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17
555
daf8df5ade7d serve: Refactor the server to make pieces usable by the debugging middleware.
Ludovic Chabant <ludovic@chabant.com>
parents: 520
diff changeset
18 class RouteNotFoundError(Exception):
daf8df5ade7d serve: Refactor the server to make pieces usable by the debugging middleware.
Ludovic Chabant <ludovic@chabant.com>
parents: 520
diff changeset
19 pass
daf8df5ade7d serve: Refactor the server to make pieces usable by the debugging middleware.
Ludovic Chabant <ludovic@chabant.com>
parents: 520
diff changeset
20
daf8df5ade7d serve: Refactor the server to make pieces usable by the debugging middleware.
Ludovic Chabant <ludovic@chabant.com>
parents: 520
diff changeset
21
711
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
22 class InvalidRouteError(Exception):
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
23 pass
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
24
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
25
1100
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
26 class InvalidRouteParameterError(Exception):
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
27 pass
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
28
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
29
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
30 class RouteParameter(object):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
31 TYPE_STRING = 0
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
32 TYPE_PATH = 1
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
33 TYPE_INT2 = 2
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
34 TYPE_INT4 = 3
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
35
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
36 def __init__(self, param_name, param_type=TYPE_STRING, *, variadic=False):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
37 self.param_name = param_name
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
38 self.param_type = param_type
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
39 self.variadic = variadic
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
40
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
41
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 class Route(object):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 """ Information about a route for a PieCrust application.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44 Each route defines the "shape" of an URL and how it maps to
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
45 content sources.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46 """
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
47 def __init__(self, app, cfg):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48 self.app = app
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
49 self.config = copy.deepcopy(cfg)
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
50
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
51 self.source_name = cfg['source']
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
52 self.uri_pattern = cfg['url'].lstrip('/')
979
45ad976712ec tests: Big push to get the tests to pass again.
Ludovic Chabant <ludovic@chabant.com>
parents: 854
diff changeset
53 self.pass_num = cfg.get('pass', 1)
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
54
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
55 self.supported_params = self.source.getSupportedRouteParameters()
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
56
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
57 self.pretty_urls = app.config.get('site/pretty_urls')
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
58 self.trailing_slash = app.config.get('site/trailing_slash')
396
dc0988d937b3 serve: Fix bug where `?!debug` doesn't get appending correctly.
Ludovic Chabant <ludovic@chabant.com>
parents: 380
diff changeset
59 self.show_debug_info = app.config.get('site/show_debug_info')
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
60 self.pagination_suffix_format = app.config.get(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
61 '__cache/pagination_suffix_format')
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
62 self.uri_root = app.config.get('site/root')
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
63
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
64 self.uri_params = []
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
65 self.uri_format = route_re.sub(self._uriFormatRepl, self.uri_pattern)
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
66
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
67 # Get the straight-forward regex for matching this URI pattern.
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
68 p = route_esc_re.sub(self._uriPatternRepl,
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
69 re.escape(self.uri_pattern)) + '$'
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
70 self.uri_re = re.compile(p)
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
71
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
72 # If the URI pattern has a 'path'-type component, we'll need to match
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
73 # the versions for which that component is empty. So for instance if
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
74 # we have `/foo/%path:bar%`, we may need to match `/foo` (note the
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
75 # lack of a trailing slash). We have to build a special pattern (in
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
76 # this case without that trailing slash) to match those situations.
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
77 # (maybe there's a better way to do it but I can't think of any
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
78 # right now)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
79 uri_pattern_no_path = (
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
80 route_re.sub(self._uriNoPathRepl, self.uri_pattern)
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
81 .replace('//', '/')
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
82 .rstrip('/'))
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
83 if uri_pattern_no_path != self.uri_pattern:
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
84 p = route_esc_re.sub(self._uriPatternRepl,
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
85 re.escape(uri_pattern_no_path)) + '$'
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
86 self.uri_re_no_path = re.compile(p)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
87 else:
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
88 self.uri_re_no_path = None
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
89
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
90 self.func_name = self._validateFuncName(cfg.get('func'))
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
91 self.func_has_variadic_parameter = False
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
92 for p in self.uri_params[:-1]:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
93 param = self.getParameter(p)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
94 if param.variadic:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
95 raise Exception(
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
96 "Only the last route URL parameter can be variadic. "
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
97 "Got: %s" % self.uri_pattern)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
98 if len(self.uri_params) > 0:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
99 last_param = self.getParameter(self.uri_params[-1])
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
100 self.func_has_variadic_parameter = last_param.variadic
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
101
711
ab5c6a8ae90a bake: Replace hard-coded taxonomy support with "generator" system.
Ludovic Chabant <ludovic@chabant.com>
parents: 661
diff changeset
102 @cached_property
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
103 def source(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104 for src in self.app.sources:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
105 if src.name == self.source_name:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
106 return src
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
107 raise Exception(
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
108 "Can't find source '%s' for route '%s'." % (
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
109 self.source_name, self.uri_pattern))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
110
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
111 def hasParameter(self, name):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
112 return any(lambda p: p.param_name == name, self.supported_params)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
113
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
114 def getParameter(self, name):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
115 for p in self.supported_params:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
116 if p.param_name == name:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
117 return p
1100
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
118 raise InvalidRouteParameterError(
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
119 "No such supported route parameter '%s' in: %s" %
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
120 (name, self.uri_pattern))
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
121
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
122 def getParameterType(self, name):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
123 return self.getParameter(name).param_type
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
124
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
125 def matchesParameters(self, route_params):
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
126 return set(self.uri_params).issubset(route_params.keys())
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
127
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
128 def matchUri(self, uri, strict=False):
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
129 if not uri.startswith(self.uri_root):
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
130 raise Exception("The given URI is not absolute: %s" % uri)
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
131 uri = uri[len(self.uri_root):]
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
132
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
133 if not self.pretty_urls:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
134 uri = ugly_url_cleaner.sub('', uri)
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
135 elif self.trailing_slash:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
136 uri = uri.rstrip('/')
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
137
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
138 route_params = None
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
139 m = self.uri_re.match(uri)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
140 if m:
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
141 route_params = m.groupdict()
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
142 if self.uri_re_no_path:
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
143 m = self.uri_re_no_path.match(uri)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
144 if m:
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
145 route_params = m.groupdict()
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
146 if route_params is None:
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
147 return None
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
148
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
149 if not strict:
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
150 # When matching URIs, if the URI is a match but is missing some
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
151 # parameters, fill those up with empty strings. This can happen if,
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
152 # say, a route's pattern is `/foo/%slug%`, and we're matching an
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
153 # URL like `/foo`.
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
154 matched_keys = set(route_params.keys())
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
155 missing_keys = set(self.uri_params) - matched_keys
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
156 for k in missing_keys:
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
157 if self.getParameterType(k) != RouteParameter.TYPE_PATH:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
158 return None
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
159 route_params[k] = ''
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
160
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
161 for k in route_params:
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
162 route_params[k] = self._coerceRouteParameter(
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
163 k, route_params[k])
448
a17774094db8 serve: Fix bug with creating routing metadata from the URL.
Ludovic Chabant <ludovic@chabant.com>
parents: 438
diff changeset
164
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
165 return route_params
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
166
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
167 def getUri(self, route_params, *, sub_num=1):
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
168 route_params = dict(route_params)
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
169 for k in route_params:
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
170 route_params[k] = self._coerceRouteParameter(
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
171 k, route_params[k])
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
172
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
173 uri = self.uri_format % route_params
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
174 suffix = None
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
175 if sub_num > 1:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
176 # Note that we know the pagination suffix starts with a slash.
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
177 suffix = self.pagination_suffix_format % {'num': sub_num}
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
178
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
179 if self.pretty_urls:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
180 # Output will be:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
181 # - `subdir/name`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
182 # - `subdir/name/2`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
183 # - `subdir/name.ext`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
184 # - `subdir/name.ext/2`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
185 if suffix:
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
186 if uri == '':
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
187 uri = suffix.lstrip('/')
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
188 else:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
189 uri = uri.rstrip('/') + suffix
337
49408002798e internal: Fix stupid routing bug.
Ludovic Chabant <ludovic@chabant.com>
parents: 334
diff changeset
190 if self.trailing_slash and uri != '':
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
191 uri = uri.rstrip('/') + '/'
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
192 else:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
193 # Output will be:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
194 # - `subdir/name.html`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
195 # - `subdir/name/2.html`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
196 # - `subdir/name.ext`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
197 # - `subdir/name/2.ext`
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
198 if uri == '':
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
199 if suffix:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
200 uri = suffix.lstrip('/') + '.html'
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
201 else:
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
202 base_uri, ext = os.path.splitext(uri)
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
203 if not ext:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
204 ext = '.html'
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
205 if suffix:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
206 uri = base_uri + suffix + ext
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
207 else:
1100
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
208 # If we just have the extension to add to the URL, we
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
209 # strip any trailing slash to prevent, say, the index
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
210 # page of a source from generating an URL like
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
211 # `subdir/.html`. Instead, it does `subdir.html`.
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
212 uri = base_uri.rstrip('/') + ext
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
213
568
6b6c5442c790 bug: Correctly handle root URLs with special characters.
Ludovic Chabant <ludovic@chabant.com>
parents: 561
diff changeset
214 uri = self.uri_root + urllib.parse.quote(uri)
396
dc0988d937b3 serve: Fix bug where `?!debug` doesn't get appending correctly.
Ludovic Chabant <ludovic@chabant.com>
parents: 380
diff changeset
215
dc0988d937b3 serve: Fix bug where `?!debug` doesn't get appending correctly.
Ludovic Chabant <ludovic@chabant.com>
parents: 380
diff changeset
216 if self.show_debug_info:
dc0988d937b3 serve: Fix bug where `?!debug` doesn't get appending correctly.
Ludovic Chabant <ludovic@chabant.com>
parents: 380
diff changeset
217 uri += '?!debug'
dc0988d937b3 serve: Fix bug where `?!debug` doesn't get appending correctly.
Ludovic Chabant <ludovic@chabant.com>
parents: 380
diff changeset
218
235
55087da9a72e bake: Don't include the site root when building output paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 225
diff changeset
219 return uri
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
220
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
221 def execTemplateFunc(self, *args):
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
222 fixed_param_count = len(self.uri_params)
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
223 if self.func_has_variadic_parameter:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
224 fixed_param_count -= 1
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
225
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
226 if len(args) < fixed_param_count:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
227 raise Exception(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
228 "Route function '%s' expected %d arguments, "
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
229 "got %d: %s" %
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
230 (self.func_name, fixed_param_count, len(args), args))
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
231
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
232 if self.func_has_variadic_parameter:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
233 coerced_args = list(args[:fixed_param_count])
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
234 if len(args) > fixed_param_count:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
235 var_arg = tuple(args[fixed_param_count:])
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
236 coerced_args.append(var_arg)
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
237 else:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
238 coerced_args = args
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
239
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
240 route_params = {}
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
241 for arg_name, arg_val in zip(self.uri_params, coerced_args):
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
242 route_params[arg_name] = self._coerceRouteParameter(
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
243 arg_name, arg_val)
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
244
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
245 self.source.onRouteFunctionUsed(route_params)
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
246
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
247 return self.getUri(route_params)
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
248
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
249 def _uriFormatRepl(self, m):
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
250 if m.group('qual') or m.group('var'):
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
251 # Print a warning only if we're not in a worker process.
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
252 print_warning = not self.app.config.has('baker/worker_id')
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
253 if print_warning:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
254 logger.warning("Route '%s' specified parameter types -- "
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
255 "they're not needed anymore." %
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
256 self.uri_pattern)
790
4cbe057a8b6a routing: Add some backwards compatibility support for parameter types.
Ludovic Chabant <ludovic@chabant.com>
parents: 787
diff changeset
257
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
258 name = m.group('name')
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
259 self.uri_params.append(name)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
260 try:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
261 param_type = self.getParameterType(name)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
262 if param_type == RouteParameter.TYPE_INT4:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
263 return '%%(%s)04d' % name
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
264 elif param_type == RouteParameter.TYPE_INT2:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
265 return '%%(%s)02d' % name
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
266 return '%%(%s)s' % name
1100
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
267 except InvalidRouteParameterError:
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
268 known = [p.name for p in self.supported_params]
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
269 raise Exception("Unknown route parameter '%s' for route '%s'. "
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
270 "Must be one of: %s'" %
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
271 (name, self.uri_pattern, known))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
272
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
273 def _uriPatternRepl(self, m):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
274 name = m.group('name')
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
275 param_type = self.getParameterType(name)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
276 if param_type == RouteParameter.TYPE_PATH:
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
277 return r'(?P<%s>[^\?]*)' % name
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
278 elif param_type == RouteParameter.TYPE_INT4:
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
279 return r'(?P<%s>\d{4})' % name
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
280 elif param_type == RouteParameter.TYPE_INT2:
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
281 return r'(?P<%s>\d{2})' % name
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
282 return r'(?P<%s>[^/\?]+)' % name
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
283
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
284 def _uriNoPathRepl(self, m):
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
285 name = m.group('name')
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
286 param_type = self.getParameterType(name)
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
287 if param_type == RouteParameter.TYPE_PATH:
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
288 return ''
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
289 return r'(?P<%s>[^/\?]+)' % name
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
290
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
291 def _coerceRouteParameter(self, name, val):
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
292 try:
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
293 param_type = self.getParameterType(name)
1100
1ce67d2fae0a routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
Ludovic Chabant <ludovic@chabant.com>
parents: 979
diff changeset
294 except InvalidRouteParameterError:
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
295 # Unknown parameter... just leave it.
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
296 return val
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
297
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
298 if param_type in [RouteParameter.TYPE_INT2, RouteParameter.TYPE_INT4]:
723
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
299 try:
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
300 return int(val)
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
301 except ValueError:
606f6d57b5df routing: Cleanup URL routing and improve page matching.
Ludovic Chabant <ludovic@chabant.com>
parents: 711
diff changeset
302 raise Exception(
792
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
303 "Expected route parameter '%s' to be an integer, "
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
304 "but was: %s" % (name, param_type, val))
58ebf50235a5 routing: Simplify how routes are defined.
Ludovic Chabant <ludovic@chabant.com>
parents: 791
diff changeset
305 return val
790
4cbe057a8b6a routing: Add some backwards compatibility support for parameter types.
Ludovic Chabant <ludovic@chabant.com>
parents: 787
diff changeset
306
787
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
307 def _validateFuncName(self, name):
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
308 if not name:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
309 return None
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
310 i = name.find('(')
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
311 if i >= 0:
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
312 name = name[:i]
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
313 logger.warning(
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
314 "Route function names shouldn't contain the list of arguments "
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
315 "anymore -- just specify '%s'." % name)
f6f9a284a5f3 routing: Simplify how route functions are declared and handled.
Ludovic Chabant <ludovic@chabant.com>
parents: 734
diff changeset
316 return name
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
317
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
318
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
319 class RouteFunction:
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
320 def __init__(self, route):
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
321 self._route = route
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
322
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
323 def __call__(self, *args, **kwargs):
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 792
diff changeset
324 return self._route.execTemplateFunc(*args, **kwargs)
854
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
325
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
326 def _isCompatibleRoute(self, route):
08e02c2a2a1a core: Keep refactoring, this time to prepare for generator sources.
Ludovic Chabant <ludovic@chabant.com>
parents: 852
diff changeset
327 return self._route.uri_pattern == route.uri_pattern