comparison piecrust/sources/posts.py @ 363:dd25bd3ce1f9

serve: Refactoring and fixes to be able to serve taxonomy pages. * Page sources' `findPagePath` is renamed to `findPageFactory`, so that it also returns source metadata. * Page refs now store possible hits more properly, and use the previous point to also store metadata. As a result, they can also return a proper factory. * Implement `findPageFactory` correctly in all built-in sources. * When the Chef server matches a taxonomy page, get the source metadata from the page ref in order to make a more proper page. * Make the `getRoute(s)` functions explicitely say if they want taxonomy routes or not.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 26 Apr 2015 15:07:40 -0700
parents 0641fe5c3ef9
children 73bd408caebc
comparison
equal deleted inserted replaced
362:ff595828a364 363:dd25bd3ce1f9
28 @property 28 @property
29 def path_format(self): 29 def path_format(self):
30 return self.__class__.PATH_FORMAT 30 return self.__class__.PATH_FORMAT
31 31
32 def resolveRef(self, ref_path): 32 def resolveRef(self, ref_path):
33 return os.path.normpath(os.path.join(self.fs_endpoint_path, ref_path)) 33 path = os.path.normpath(os.path.join(self.fs_endpoint_path, ref_path))
34 34 metadata = self._parseMetadataFromPath(ref_path)
35 def findPagePath(self, metadata, mode): 35 return path, metadata
36
37 def findPageFactory(self, metadata, mode):
36 year = metadata.get('year') 38 year = metadata.get('year')
37 month = metadata.get('month') 39 month = metadata.get('month')
38 day = metadata.get('day') 40 day = metadata.get('day')
39 slug = metadata.get('slug') 41 slug = metadata.get('slug')
40 42
44 if month is not None: 46 if month is not None:
45 month = int(month) 47 month = int(month)
46 if day is not None: 48 if day is not None:
47 day = int(day) 49 day = int(day)
48 except ValueError: 50 except ValueError:
49 return None, None 51 return None
50 52
51 ext = metadata.get('ext') 53 ext = metadata.get('ext')
52 if ext is None: 54 if ext is None:
53 if len(self.supported_extensions) == 1: 55 if len(self.supported_extensions) == 1:
54 ext = self.supported_extensions[0] 56 ext = self.supported_extensions[0]
89 raise PageNotFoundError() 91 raise PageNotFoundError()
90 path = possible_paths[0] 92 path = possible_paths[0]
91 elif mode == MODE_PARSING and not os.path.isfile(path): 93 elif mode == MODE_PARSING and not os.path.isfile(path):
92 raise PageNotFoundError(path) 94 raise PageNotFoundError(path)
93 95
94 regex_repl = {
95 'year': '(?P<year>\d{4})',
96 'month': '(?P<month>\d{2})',
97 'day': '(?P<day>\d{2})',
98 'slug': '(?P<slug>.*)',
99 'ext': '(?P<ext>.*)'
100 }
101 path_format_re = re.sub(r'([\-\.])', r'\\\1', self.path_format)
102 pattern = path_format_re % regex_repl + '$'
103 m = re.search(pattern, path.replace('\\', '/'))
104 if not m:
105 raise Exception("Expected to be able to match path with path "
106 "format: %s" % path)
107
108 year = int(m.group('year'))
109 month = int(m.group('month'))
110 day = int(m.group('day'))
111 timestamp = datetime.date(year, month, day)
112 fac_metadata = {
113 'year': year,
114 'month': month,
115 'day': day,
116 'slug': m.group('slug'),
117 'date': timestamp
118 }
119
120 rel_path = os.path.relpath(path, self.fs_endpoint_path) 96 rel_path = os.path.relpath(path, self.fs_endpoint_path)
121 rel_path = rel_path.replace('\\', '/') 97 rel_path = rel_path.replace('\\', '/')
122 return rel_path, fac_metadata 98 fac_metadata = self._parseMetadataFromPath(rel_path)
99 return PageFactory(self, rel_path, fac_metadata)
123 100
124 def setupPrepareParser(self, parser, app): 101 def setupPrepareParser(self, parser, app):
125 parser.add_argument('-d', '--date', help="The date of the post, " 102 parser.add_argument('-d', '--date', help="The date of the post, "
126 "in `year/month/day` format (defaults to today).") 103 "in `year/month/day` format (defaults to today).")
127 parser.add_argument('slug', help="The URL slug for the new post.") 104 parser.add_argument('slug', help="The URL slug for the new post.")
152 if not os.path.isdir(self.fs_endpoint_path): 129 if not os.path.isdir(self.fs_endpoint_path):
153 if self.ignore_missing_dir: 130 if self.ignore_missing_dir:
154 return False 131 return False
155 raise InvalidFileSystemEndpointError(self.name, self.fs_endpoint_path) 132 raise InvalidFileSystemEndpointError(self.name, self.fs_endpoint_path)
156 return True 133 return True
134
135 def _parseMetadataFromPath(self, path):
136 regex_repl = {
137 'year': '(?P<year>\d{4})',
138 'month': '(?P<month>\d{2})',
139 'day': '(?P<day>\d{2})',
140 'slug': '(?P<slug>.*)',
141 'ext': '(?P<ext>.*)'
142 }
143 path_format_re = re.sub(r'([\-\.])', r'\\\1', self.path_format)
144 pattern = path_format_re % regex_repl + '$'
145 m = re.search(pattern, path.replace('\\', '/'))
146 if not m:
147 raise Exception("Expected to be able to match path with path "
148 "format: %s" % path)
149
150 year = int(m.group('year'))
151 month = int(m.group('month'))
152 day = int(m.group('day'))
153 timestamp = datetime.date(year, month, day)
154 metadata = {
155 'year': year,
156 'month': month,
157 'day': day,
158 'slug': m.group('slug'),
159 'date': timestamp
160 }
161 return metadata
157 162
158 def _makeFactory(self, path, slug, year, month, day): 163 def _makeFactory(self, path, slug, year, month, day):
159 path = path.replace('\\', '/') 164 path = path.replace('\\', '/')
160 timestamp = datetime.date(year, month, day) 165 timestamp = datetime.date(year, month, day)
161 metadata = { 166 metadata = {