comparison piecrust/sources/base.py @ 6:f5ca5c5bed85

More Python 3 fixes, modularization, and new unit tests.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 16 Aug 2014 08:15:30 -0700
parents 474c9882decf
children 343d08ef5668
comparison
equal deleted inserted replaced
5:474c9882decf 6:f5ca5c5bed85
3 import os.path 3 import os.path
4 import logging 4 import logging
5 from werkzeug.utils import cached_property 5 from werkzeug.utils import cached_property
6 from piecrust import CONTENT_DIR 6 from piecrust import CONTENT_DIR
7 from piecrust.configuration import ConfigurationError 7 from piecrust.configuration import ConfigurationError
8 from piecrust.data.base import IPaginationSource, PaginationData
9 from piecrust.data.filters import PaginationFilter
8 from piecrust.page import Page 10 from piecrust.page import Page
9 11
10 12
11 REALM_USER = 0 13 REALM_USER = 0
12 REALM_THEME = 1 14 REALM_THEME = 1
245 247
246 def buildMetadata(self, args): 248 def buildMetadata(self, args):
247 raise NotImplementedError() 249 raise NotImplementedError()
248 250
249 251
252 class SimplePaginationSourceMixin(IPaginationSource):
253 def getItemsPerPage(self):
254 return self.config['items_per_page']
255
256 def getSourceIterator(self):
257 return SourceFactoryIterator(self)
258
259 def getSorterIterator(self, it):
260 return DateSortIterator(it)
261
262 def getTailIterator(self, it):
263 return PaginationDataBuilderIterator(it)
264
265 def getPaginationFilter(self, page):
266 conf = (page.config.get('items_filters') or
267 page.app.config.get('site/items_filters'))
268 if conf == 'none' or conf == 'nil' or conf == '':
269 conf = None
270 if conf is not None:
271 f = PaginationFilter()
272 f.addClausesFromConfig(conf)
273 return f
274 return None
275
276
250 class ArraySource(PageSource): 277 class ArraySource(PageSource):
251 def __init__(self, app, inner_source, name='array', config=None): 278 def __init__(self, app, inner_source, name='array', config=None):
252 super(ArraySource, self).__init__(app, name, config or {}) 279 super(ArraySource, self).__init__(app, name, config or {})
253 self.inner_source = inner_source 280 self.inner_source = inner_source
254 281
323 f[-1] != '~' and 350 f[-1] != '~' and
324 ext.lstrip('.') in self.supported_extensions and 351 ext.lstrip('.') in self.supported_extensions and
325 f not in ['Thumbs.db']) 352 f not in ['Thumbs.db'])
326 353
327 354
328 class DefaultPageSource(SimplePageSource, IPreparingSource): 355 class DefaultPageSource(SimplePageSource, IPreparingSource,
356 SimplePaginationSourceMixin):
329 SOURCE_NAME = 'default' 357 SOURCE_NAME = 'default'
330 358
331 def __init__(self, app, name, config): 359 def __init__(self, app, name, config):
332 super(DefaultPageSource, self).__init__(app, name, config) 360 super(DefaultPageSource, self).__init__(app, name, config)
333 361
335 parser.add_argument('uri', help='The URI for the new page.') 363 parser.add_argument('uri', help='The URI for the new page.')
336 364
337 def buildMetadata(self, args): 365 def buildMetadata(self, args):
338 return {'path': args.uri} 366 return {'path': args.uri}
339 367
368
369 class SourceFactoryIterator(object):
370 def __init__(self, source):
371 self.source = source
372 self.it = None # This is to permit recursive traversal of the
373 # iterator chain. It acts as the end.
374
375 def __iter__(self):
376 for factory in self.source.getPageFactories():
377 yield factory.buildPage()
378
379
380 class DateSortIterator(object):
381 def __init__(self, it, reverse=True):
382 self.it = it
383 self.reverse = reverse
384
385 def __iter__(self):
386 return iter(sorted(self.it,
387 key=lambda x: x.datetime, reverse=self.reverse))
388
389
390 class PaginationDataBuilderIterator(object):
391 def __init__(self, it):
392 self.it = it
393
394 def __iter__(self):
395 for page in self.it:
396 yield PaginationData(page)
397