comparison piecrust/sources/base.py @ 171:d5991525801d

sources: Add an `IListableSource` interface for sources that can be listed. Page sources that implement this interface can be "iterated through", like a hierarchy, which is useful for the upcoming `Linker` feature.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 03 Jan 2015 20:51:34 -0800
parents c3831a762bc2
children e61fbae61402
comparison
equal deleted inserted replaced
170:c3831a762bc2 171:d5991525801d
257 257
258 def buildMetadata(self, args): 258 def buildMetadata(self, args):
259 raise NotImplementedError() 259 raise NotImplementedError()
260 260
261 261
262 class IListableSource:
263 def listPath(self, rel_path):
264 raise NotImplementedError()
265
266 def getDirpath(self, rel_path):
267 raise NotImplementedError()
268
269 def getBasename(self, rel_path):
270 raise NotImplementedError()
271
272
262 class SimplePaginationSourceMixin(IPaginationSource): 273 class SimplePaginationSourceMixin(IPaginationSource):
263 def getItemsPerPage(self): 274 def getItemsPerPage(self):
264 return self.config['items_per_page'] 275 return self.config['items_per_page']
265 276
266 def getSourceIterator(self): 277 def getSourceIterator(self):
296 def getPageFactories(self): 307 def getPageFactories(self):
297 for p in self.inner_source: 308 for p in self.inner_source:
298 yield CachedPageFactory(p) 309 yield CachedPageFactory(p)
299 310
300 311
301 class SimplePageSource(PageSource): 312 class SimplePageSource(PageSource, IListableSource):
302 def __init__(self, app, name, config): 313 def __init__(self, app, name, config):
303 super(SimplePageSource, self).__init__(app, name, config) 314 super(SimplePageSource, self).__init__(app, name, config)
304 self.fs_endpoint = config.get('fs_endpoint', name) 315 self.fs_endpoint = config.get('fs_endpoint', name)
305 self.fs_endpoint_path = os.path.join(self.root_dir, self.fs_endpoint) 316 self.fs_endpoint_path = os.path.join(self.root_dir, self.fs_endpoint)
306 self.supported_extensions = list(app.config.get('site/auto_formats').keys()) 317 self.supported_extensions = list(app.config.get('site/auto_formats').keys())
358 self._populateMetadata(rel_path, metadata) 369 self._populateMetadata(rel_path, metadata)
359 return rel_path, metadata 370 return rel_path, metadata
360 371
361 return None, None 372 return None, None
362 373
374 def listPath(self, rel_path):
375 path = os.path.join(self.fs_endpoint_path, rel_path)
376 names = sorted(os.listdir(path))
377 items = []
378 for name in names:
379 if os.path.isdir(os.path.join(path, name)):
380 if self._filterPageDirname(name):
381 rel_subdir = os.path.join(rel_path, name)
382 items.append((True, name, rel_subdir))
383 else:
384 if self._filterPageFilename(name):
385 slug = self._makeSlug(os.path.join(rel_path, name))
386 metadata = {'path': slug}
387
388 fac_path = name
389 if rel_path != '.':
390 fac_path = os.path.join(rel_path, name)
391 fac_path = fac_path.replace('\\', '/')
392
393 self._populateMetadata(fac_path, metadata)
394 fac = PageFactory(self, fac_path, metadata)
395 items.append((False, name, fac))
396 return items
397
398 def getDirpath(self, rel_path):
399 return os.path.dirname(rel_path)
400
401 def getBasename(self, rel_path):
402 filename = os.path.basename(rel_path)
403 name, _ = os.path.splitext(filename)
404 return name
405
363 def _makeSlug(self, rel_path): 406 def _makeSlug(self, rel_path):
364 slug, ext = os.path.splitext(rel_path) 407 slug, ext = os.path.splitext(rel_path)
365 slug = slug.replace('\\', '/') 408 slug = slug.replace('\\', '/')
366 if ext.lstrip('.') not in self.supported_extensions: 409 if ext.lstrip('.') not in self.supported_extensions:
367 slug += ext 410 slug += ext
380 f not in ['Thumbs.db']) # Windows bullshit 423 f not in ['Thumbs.db']) # Windows bullshit
381 424
382 def _populateMetadata(self, rel_path, metadata): 425 def _populateMetadata(self, rel_path, metadata):
383 pass 426 pass
384 427
385 class DefaultPageSource(SimplePageSource, IPreparingSource, 428
386 SimplePaginationSourceMixin): 429 class DefaultPageSource(SimplePageSource,
430 IPreparingSource, IListableSource,
431 SimplePaginationSourceMixin):
387 SOURCE_NAME = 'default' 432 SOURCE_NAME = 'default'
388 433
389 def __init__(self, app, name, config): 434 def __init__(self, app, name, config):
390 super(DefaultPageSource, self).__init__(app, name, config) 435 super(DefaultPageSource, self).__init__(app, name, config)
391 436