Mercurial > piecrust2
changeset 142:0bdd938d6b9f
Better date/time handling for pages:
- Date can be specified in the page config.
- Fall back to timestamp 0 (which is fixed) instead of the timestamp of
the file (which could vary).
Sources can return additional config values to merge with the page's
YAML front matter.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sat, 29 Nov 2014 18:33:29 -0800 |
parents | 666ee97e77a9 |
children | 5b12c1d96523 |
files | piecrust/page.py |
diffstat | 1 files changed, 74 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/page.py Sat Nov 29 18:29:19 2014 -0800 +++ b/piecrust/page.py Sat Nov 29 18:33:29 2014 -0800 @@ -79,51 +79,41 @@ @property def datetime(self): if self._datetime is None: - if 'datetime' in self.source_metadata: - self._datetime = self.source_metadata['datetime'] - elif 'date' in self.source_metadata: - page_date = self.source_metadata['date'] - page_time = self.config.get('time') - if page_time is not None: - if isinstance(page_time, str): - # Need to parse it... - try: - parsed_t = dateutil.parser.parse(page_time) - except Exception as ex: - raise ConfigurationError( - "Invalid time '%s' in page: %s" % - (page_time, self.path)) from ex - page_time = datetime.timedelta( - hours=parsed_t.hour, - minutes=parsed_t.minute, - seconds=parsed_t.second) - - elif isinstance(page_time, int): - # Total seconds... convert to a time struct. - page_time = datetime.timedelta(seconds=page_time) - - elif not isinstance(page_time, datetime.timedelta): - raise ConfigurationError( - "Invalid time '%s' in page: %s" % - (page_time, self.path)) - - try: + try: + if 'datetime' in self.source_metadata: + # Get the date/time from the source. + self._datetime = self.source_metadata['datetime'] + elif 'date' in self.source_metadata: + # Get the date from the source. Potentially get the + # time from the page config. + page_date = self.source_metadata['date'] + page_time = _parse_config_time(self.config.get('time')) + if page_time is not None: self._datetime = datetime.datetime( page_date.year, page_date.month, page_date.day) + page_time - except Exception as ex: - raise ConfigurationError( - "Invalid page time '%s' for: %s" % ( - page_time, self.path)) from ex - else: + else: + self._datetime = datetime.datetime( + page_date.year, page_date.month, page_date.day) + elif 'date' in self.config: + # Get the date from the page config, and maybe the + # time too. + page_date = _parse_config_date(self.config.get('date')) self._datetime = datetime.datetime( - page_date.year, page_date.month, page_date.day) - else: - self._datetime = datetime.datetime.fromtimestamp( - self.path_mtime) - if self._datetime is None: - raise Exception("Got null datetime from path! %s" % self.path) + page_date.year, + page_date.month, + page_date.day) + page_time = _parse_config_time(self.config.get('time')) + if page_time is not None: + self._datetime += page_time + else: + # No idea what the date/time for this page is. + self._datetime = datetime.datetime.fromtimestamp(0) + except Exception as ex: + raise Exception( + "Error computing time for page: %s" % + self.path) from ex return self._datetime @datetime.setter @@ -139,12 +129,56 @@ config, content, was_cache_valid = load_page(self.app, self.path, self.path_mtime) + if 'config' in self.source_metadata: + config.merge(self.source_metadata['config']) + self._config = config self._raw_content = content if was_cache_valid: self._flags |= FLAG_RAW_CACHE_VALID +def _parse_config_date(page_date): + if page_date is None: + return None + + if isinstance(page_date, str): + try: + parsed_d = dateutil.parser.parse(page_date) + except Exception as ex: + raise ConfigurationError("Invalid date: %s" % page_date) from ex + return datetime.date( + year=parsed_d.year, + month=parsed_d.month, + day=parsed_d.day) + + raise ConfigurationError("Invalid date: %s" % page_date) + + +def _parse_config_time(page_time): + if page_time is None: + return None + + if isinstance(page_time, datetime.timedelta): + return page_time + + if isinstance(page_time, str): + try: + parsed_t = dateutil.parser.parse(page_time) + except Exception as ex: + raise ConfigurationError("Invalid time: %s" % page_time) from ex + return datetime.timedelta( + hours=parsed_t.hour, + minutes=parsed_t.minute, + seconds=parsed_t.second) + + if isinstance(page_time, int): + # Total seconds... convert to a time struct. + return datetime.timedelta(seconds=page_time) + + raise ConfigurationError("Invalid time: %s" % page_time) + + class PageLoadingError(Exception): def __init__(self, path, inner=None): super(PageLoadingError, self).__init__(