Mercurial > piecrust2
comparison piecrust/page.py @ 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 | 28444014ce7d |
children | ab6e7e0e9d44 |
comparison
equal
deleted
inserted
replaced
141:666ee97e77a9 | 142:0bdd938d6b9f |
---|---|
77 return self._raw_content | 77 return self._raw_content |
78 | 78 |
79 @property | 79 @property |
80 def datetime(self): | 80 def datetime(self): |
81 if self._datetime is None: | 81 if self._datetime is None: |
82 if 'datetime' in self.source_metadata: | 82 try: |
83 self._datetime = self.source_metadata['datetime'] | 83 if 'datetime' in self.source_metadata: |
84 elif 'date' in self.source_metadata: | 84 # Get the date/time from the source. |
85 page_date = self.source_metadata['date'] | 85 self._datetime = self.source_metadata['datetime'] |
86 page_time = self.config.get('time') | 86 elif 'date' in self.source_metadata: |
87 if page_time is not None: | 87 # Get the date from the source. Potentially get the |
88 if isinstance(page_time, str): | 88 # time from the page config. |
89 # Need to parse it... | 89 page_date = self.source_metadata['date'] |
90 try: | 90 page_time = _parse_config_time(self.config.get('time')) |
91 parsed_t = dateutil.parser.parse(page_time) | 91 if page_time is not None: |
92 except Exception as ex: | |
93 raise ConfigurationError( | |
94 "Invalid time '%s' in page: %s" % | |
95 (page_time, self.path)) from ex | |
96 page_time = datetime.timedelta( | |
97 hours=parsed_t.hour, | |
98 minutes=parsed_t.minute, | |
99 seconds=parsed_t.second) | |
100 | |
101 elif isinstance(page_time, int): | |
102 # Total seconds... convert to a time struct. | |
103 page_time = datetime.timedelta(seconds=page_time) | |
104 | |
105 elif not isinstance(page_time, datetime.timedelta): | |
106 raise ConfigurationError( | |
107 "Invalid time '%s' in page: %s" % | |
108 (page_time, self.path)) | |
109 | |
110 try: | |
111 self._datetime = datetime.datetime( | 92 self._datetime = datetime.datetime( |
112 page_date.year, | 93 page_date.year, |
113 page_date.month, | 94 page_date.month, |
114 page_date.day) + page_time | 95 page_date.day) + page_time |
115 except Exception as ex: | 96 else: |
116 raise ConfigurationError( | 97 self._datetime = datetime.datetime( |
117 "Invalid page time '%s' for: %s" % ( | 98 page_date.year, page_date.month, page_date.day) |
118 page_time, self.path)) from ex | 99 elif 'date' in self.config: |
100 # Get the date from the page config, and maybe the | |
101 # time too. | |
102 page_date = _parse_config_date(self.config.get('date')) | |
103 self._datetime = datetime.datetime( | |
104 page_date.year, | |
105 page_date.month, | |
106 page_date.day) | |
107 page_time = _parse_config_time(self.config.get('time')) | |
108 if page_time is not None: | |
109 self._datetime += page_time | |
119 else: | 110 else: |
120 self._datetime = datetime.datetime( | 111 # No idea what the date/time for this page is. |
121 page_date.year, page_date.month, page_date.day) | 112 self._datetime = datetime.datetime.fromtimestamp(0) |
122 else: | 113 except Exception as ex: |
123 self._datetime = datetime.datetime.fromtimestamp( | 114 raise Exception( |
124 self.path_mtime) | 115 "Error computing time for page: %s" % |
125 if self._datetime is None: | 116 self.path) from ex |
126 raise Exception("Got null datetime from path! %s" % self.path) | |
127 return self._datetime | 117 return self._datetime |
128 | 118 |
129 @datetime.setter | 119 @datetime.setter |
130 def datetime(self, value): | 120 def datetime(self, value): |
131 self._datetime = value | 121 self._datetime = value |
137 if self._config is not None: | 127 if self._config is not None: |
138 return | 128 return |
139 | 129 |
140 config, content, was_cache_valid = load_page(self.app, self.path, | 130 config, content, was_cache_valid = load_page(self.app, self.path, |
141 self.path_mtime) | 131 self.path_mtime) |
132 if 'config' in self.source_metadata: | |
133 config.merge(self.source_metadata['config']) | |
134 | |
142 self._config = config | 135 self._config = config |
143 self._raw_content = content | 136 self._raw_content = content |
144 if was_cache_valid: | 137 if was_cache_valid: |
145 self._flags |= FLAG_RAW_CACHE_VALID | 138 self._flags |= FLAG_RAW_CACHE_VALID |
139 | |
140 | |
141 def _parse_config_date(page_date): | |
142 if page_date is None: | |
143 return None | |
144 | |
145 if isinstance(page_date, str): | |
146 try: | |
147 parsed_d = dateutil.parser.parse(page_date) | |
148 except Exception as ex: | |
149 raise ConfigurationError("Invalid date: %s" % page_date) from ex | |
150 return datetime.date( | |
151 year=parsed_d.year, | |
152 month=parsed_d.month, | |
153 day=parsed_d.day) | |
154 | |
155 raise ConfigurationError("Invalid date: %s" % page_date) | |
156 | |
157 | |
158 def _parse_config_time(page_time): | |
159 if page_time is None: | |
160 return None | |
161 | |
162 if isinstance(page_time, datetime.timedelta): | |
163 return page_time | |
164 | |
165 if isinstance(page_time, str): | |
166 try: | |
167 parsed_t = dateutil.parser.parse(page_time) | |
168 except Exception as ex: | |
169 raise ConfigurationError("Invalid time: %s" % page_time) from ex | |
170 return datetime.timedelta( | |
171 hours=parsed_t.hour, | |
172 minutes=parsed_t.minute, | |
173 seconds=parsed_t.second) | |
174 | |
175 if isinstance(page_time, int): | |
176 # Total seconds... convert to a time struct. | |
177 return datetime.timedelta(seconds=page_time) | |
178 | |
179 raise ConfigurationError("Invalid time: %s" % page_time) | |
146 | 180 |
147 | 181 |
148 class PageLoadingError(Exception): | 182 class PageLoadingError(Exception): |
149 def __init__(self, path, inner=None): | 183 def __init__(self, path, inner=None): |
150 super(PageLoadingError, self).__init__( | 184 super(PageLoadingError, self).__init__( |