comparison piecrust/sources/posts.py @ 520:bab91fcef741

bake/serve: Improve support for unicode, add slugification options. * Add slugification options for taxonomies. * Sort out some unicode support problems on OSX. * Add tests.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 28 Jul 2015 18:34:21 -0700
parents 73bd408caebc
children 0c74a6c4533d
comparison
equal deleted inserted replaced
519:9d1a89cd8146 520:bab91fcef741
1 import os 1 import os
2 import os.path 2 import os.path
3 import re 3 import re
4 import glob
5 import logging 4 import logging
6 import datetime 5 import datetime
6 from piecrust import osutil
7 from piecrust.sources.base import ( 7 from piecrust.sources.base import (
8 PageSource, InvalidFileSystemEndpointError, PageFactory, 8 PageSource, InvalidFileSystemEndpointError, PageFactory,
9 MODE_CREATING, MODE_PARSING) 9 MODE_CREATING, MODE_PARSING)
10 from piecrust.sources.interfaces import IPreparingSource 10 from piecrust.sources.interfaces import IPreparingSource
11 from piecrust.sources.mixins import SimplePaginationSourceMixin 11 from piecrust.sources.mixins import SimplePaginationSourceMixin
83 self.fs_endpoint_path, self.path_format % replacements)) 83 self.fs_endpoint_path, self.path_format % replacements))
84 84
85 if needs_recapture: 85 if needs_recapture:
86 if mode == MODE_CREATING: 86 if mode == MODE_CREATING:
87 raise ValueError("Not enough information to find a post path.") 87 raise ValueError("Not enough information to find a post path.")
88 possible_paths = glob.glob(path) 88 possible_paths = osutil.glob(path)
89 if len(possible_paths) != 1: 89 if len(possible_paths) != 1:
90 return None 90 return None
91 path = possible_paths[0] 91 path = possible_paths[0]
92 elif mode == MODE_PARSING and not os.path.isfile(path): 92 elif mode == MODE_PARSING and not os.path.isfile(path):
93 return None 93 return None
181 def buildPageFactories(self): 181 def buildPageFactories(self):
182 if not self._checkFsEndpointPath(): 182 if not self._checkFsEndpointPath():
183 return 183 return
184 logger.debug("Scanning for posts (flat) in: %s" % self.fs_endpoint_path) 184 logger.debug("Scanning for posts (flat) in: %s" % self.fs_endpoint_path)
185 pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})_(.*)\.(\w+)$') 185 pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})_(.*)\.(\w+)$')
186 _, __, filenames = next(os.walk(self.fs_endpoint_path)) 186 _, __, filenames = next(osutil.walk(self.fs_endpoint_path))
187 for f in filenames: 187 for f in filenames:
188 match = pattern.match(f) 188 match = pattern.match(f)
189 if match is None: 189 if match is None:
190 name, ext = os.path.splitext(f) 190 name, ext = os.path.splitext(f)
191 logger.warning("'%s' is not formatted as 'YYYY-MM-DD_slug-title.%s' " 191 logger.warning("'%s' is not formatted as 'YYYY-MM-DD_slug-title.%s' "
210 if not self._checkFsEndpointPath(): 210 if not self._checkFsEndpointPath():
211 return 211 return
212 logger.debug("Scanning for posts (shallow) in: %s" % self.fs_endpoint_path) 212 logger.debug("Scanning for posts (shallow) in: %s" % self.fs_endpoint_path)
213 year_pattern = re.compile(r'(\d{4})$') 213 year_pattern = re.compile(r'(\d{4})$')
214 file_pattern = re.compile(r'(\d{2})-(\d{2})_(.*)\.(\w+)$') 214 file_pattern = re.compile(r'(\d{2})-(\d{2})_(.*)\.(\w+)$')
215 _, year_dirs, __ = next(os.walk(self.fs_endpoint_path)) 215 _, year_dirs, __ = next(osutil.walk(self.fs_endpoint_path))
216 year_dirs = [d for d in year_dirs if year_pattern.match(d)] 216 year_dirs = [d for d in year_dirs if year_pattern.match(d)]
217 for yd in year_dirs: 217 for yd in year_dirs:
218 if year_pattern.match(yd) is None: 218 if year_pattern.match(yd) is None:
219 logger.warning("'%s' is not formatted as 'YYYY' and will be ignored. " 219 logger.warning("'%s' is not formatted as 'YYYY' and will be ignored. "
220 "Is that a typo?") 220 "Is that a typo?")
221 continue 221 continue
222 year = int(yd) 222 year = int(yd)
223 year_dir = os.path.join(self.fs_endpoint_path, yd) 223 year_dir = os.path.join(self.fs_endpoint_path, yd)
224 224
225 _, __, filenames = next(os.walk(year_dir)) 225 _, __, filenames = next(osutil.walk(year_dir))
226 for f in filenames: 226 for f in filenames:
227 match = file_pattern.match(f) 227 match = file_pattern.match(f)
228 if match is None: 228 if match is None:
229 name, ext = os.path.splitext(f) 229 name, ext = os.path.splitext(f)
230 logger.warning("'%s' is not formatted as 'MM-DD_slug-title.%s' " 230 logger.warning("'%s' is not formatted as 'MM-DD_slug-title.%s' "
250 return 250 return
251 logger.debug("Scanning for posts (hierarchy) in: %s" % self.fs_endpoint_path) 251 logger.debug("Scanning for posts (hierarchy) in: %s" % self.fs_endpoint_path)
252 year_pattern = re.compile(r'(\d{4})$') 252 year_pattern = re.compile(r'(\d{4})$')
253 month_pattern = re.compile(r'(\d{2})$') 253 month_pattern = re.compile(r'(\d{2})$')
254 file_pattern = re.compile(r'(\d{2})_(.*)\.(\w+)$') 254 file_pattern = re.compile(r'(\d{2})_(.*)\.(\w+)$')
255 _, year_dirs, __ = next(os.walk(self.fs_endpoint_path)) 255 _, year_dirs, __ = next(osutil.walk(self.fs_endpoint_path))
256 year_dirs = [d for d in year_dirs if year_pattern.match(d)] 256 year_dirs = [d for d in year_dirs if year_pattern.match(d)]
257 for yd in year_dirs: 257 for yd in year_dirs:
258 year = int(yd) 258 year = int(yd)
259 year_dir = os.path.join(self.fs_endpoint_path, yd) 259 year_dir = os.path.join(self.fs_endpoint_path, yd)
260 260
261 _, month_dirs, __ = next(os.walk(year_dir)) 261 _, month_dirs, __ = next(osutil.walk(year_dir))
262 month_dirs = [d for d in month_dirs if month_pattern.match(d)] 262 month_dirs = [d for d in month_dirs if month_pattern.match(d)]
263 for md in month_dirs: 263 for md in month_dirs:
264 month = int(md) 264 month = int(md)
265 month_dir = os.path.join(year_dir, md) 265 month_dir = os.path.join(year_dir, md)
266 266
267 _, __, filenames = next(os.walk(month_dir)) 267 _, __, filenames = next(osutil.walk(month_dir))
268 for f in filenames: 268 for f in filenames:
269 match = file_pattern.match(f) 269 match = file_pattern.match(f)
270 if match is None: 270 if match is None:
271 name, ext = os.path.splitext(f) 271 name, ext = os.path.splitext(f)
272 logger.warning("'%s' is not formatted as 'DD_slug-title.%s' " 272 logger.warning("'%s' is not formatted as 'DD_slug-title.%s' "