annotate piecrust/page.py @ 182:a54d3c0b5f4a

tests: Patch `os.path.exists` and improve patching for `open`. You can specify additional modules for which to patch `open`. Also, it was incorrectly updating the opened file, even when it was opened for read only. Now it only updates the contents if the file was opened for write, and supports appending to the end. Last, it supports opening text files in binary mode.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 04 Jan 2015 14:55:41 -0800
parents ab6e7e0e9d44
children aa6b7ff6a193
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import re
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
2 import sys
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3 import json
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 import codecs
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 import os.path
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6 import hashlib
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7 import logging
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8 import datetime
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9 import dateutil.parser
67
563ce5dd02af I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents: 49
diff changeset
10 import collections
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
11 from werkzeug.utils import cached_property
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12 from piecrust.configuration import (Configuration, ConfigurationError,
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13 parse_config_header)
147
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
14 from piecrust.routing import IRouteMetadataProvider
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20 class PageConfiguration(Configuration):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 def __init__(self, values=None, validate=True):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 super(PageConfiguration, self).__init__(values, validate)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24 def _validateAll(self, values):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25 values.setdefault('title', 'Untitled Page')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26 values.setdefault('content_type', 'html')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 ppp = values.get('posts_per_page')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28 if ppp is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29 values.setdefault('items_per_page', ppp)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 pf = values.get('posts_filters')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 if pf is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32 values.setdefault('items_filters', pf)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 return values
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
35
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
36 FLAG_NONE = 0
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
37 FLAG_RAW_CACHE_VALID = 2**0
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
38
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
39
147
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
40 class Page(IRouteMetadataProvider):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41 def __init__(self, source, source_metadata, rel_path):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 self.source = source
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 self.source_metadata = source_metadata
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44 self.rel_path = rel_path
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
45 self._config = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46 self._raw_content = None
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
47 self._flags = FLAG_NONE
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48 self._datetime = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
50 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
51 def app(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
52 return self.source.app
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
53
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
54 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
55 def ref_spec(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56 return '%s:%s' % (self.source.name, self.rel_path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
57
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
58 @cached_property
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
59 def path(self):
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
60 return self.source.resolveRef(self.rel_path)
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
61
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
62 @cached_property
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
63 def path_mtime(self):
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
64 return os.path.getmtime(self.path)
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
65
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
66 @property
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
67 def flags(self):
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
68 return self._flags
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
69
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
70 @property
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
71 def config(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
72 self._load()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
73 return self._config
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76 def raw_content(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 self._load()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78 return self._raw_content
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81 def datetime(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82 if self._datetime is None:
142
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
83 try:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
84 if 'datetime' in self.source_metadata:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
85 # Get the date/time from the source.
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
86 self._datetime = self.source_metadata['datetime']
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
87 elif 'date' in self.source_metadata:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
88 # Get the date from the source. Potentially get the
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
89 # time from the page config.
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
90 page_date = self.source_metadata['date']
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
91 page_time = _parse_config_time(self.config.get('time'))
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
92 if page_time is not None:
108
b6ec402d32bb Properly add the config time to a page's datetime.
Ludovic Chabant <ludovic@chabant.com>
parents: 96
diff changeset
93 self._datetime = datetime.datetime(
b6ec402d32bb Properly add the config time to a page's datetime.
Ludovic Chabant <ludovic@chabant.com>
parents: 96
diff changeset
94 page_date.year,
b6ec402d32bb Properly add the config time to a page's datetime.
Ludovic Chabant <ludovic@chabant.com>
parents: 96
diff changeset
95 page_date.month,
b6ec402d32bb Properly add the config time to a page's datetime.
Ludovic Chabant <ludovic@chabant.com>
parents: 96
diff changeset
96 page_date.day) + page_time
142
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
97 else:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
98 self._datetime = datetime.datetime(
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
99 page_date.year, page_date.month, page_date.day)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
100 elif 'date' in self.config:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
101 # Get the date from the page config, and maybe the
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
102 # time too.
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
103 page_date = _parse_config_date(self.config.get('date'))
90
e293f08d954e PyYAML supports sexagesimal notation, so handle that for page times.
Ludovic Chabant <ludovic@chabant.com>
parents: 67
diff changeset
104 self._datetime = datetime.datetime(
142
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
105 page_date.year,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
106 page_date.month,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
107 page_date.day)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
108 page_time = _parse_config_time(self.config.get('time'))
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
109 if page_time is not None:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
110 self._datetime += page_time
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
111 else:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
112 # No idea what the date/time for this page is.
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
113 self._datetime = datetime.datetime.fromtimestamp(0)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
114 except Exception as ex:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
115 raise Exception(
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
116 "Error computing time for page: %s" %
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
117 self.path) from ex
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
118 return self._datetime
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
119
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
120 @datetime.setter
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
121 def datetime(self, value):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
122 self._datetime = value
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
123
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
124 def getSegment(self, name='content'):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
125 return self.raw_content[name]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
126
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
127 def _load(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
128 if self._config is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
129 return
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
130
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
131 config, content, was_cache_valid = load_page(self.app, self.path,
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
132 self.path_mtime)
142
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
133 if 'config' in self.source_metadata:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
134 config.merge(self.source_metadata['config'])
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
135
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
136 self._config = config
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
137 self._raw_content = content
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
138 if was_cache_valid:
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
139 self._flags |= FLAG_RAW_CACHE_VALID
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
140
147
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
141 def getRouteMetadata(self):
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
142 page_dt = self.datetime
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
143 return {
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
144 'year': page_dt.year,
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
145 'month': page_dt.month,
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
146 'day': page_dt.day}
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 142
diff changeset
147
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
148
142
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
149 def _parse_config_date(page_date):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
150 if page_date is None:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
151 return None
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
152
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
153 if isinstance(page_date, str):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
154 try:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
155 parsed_d = dateutil.parser.parse(page_date)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
156 except Exception as ex:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
157 raise ConfigurationError("Invalid date: %s" % page_date) from ex
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
158 return datetime.date(
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
159 year=parsed_d.year,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
160 month=parsed_d.month,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
161 day=parsed_d.day)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
162
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
163 raise ConfigurationError("Invalid date: %s" % page_date)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
164
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
165
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
166 def _parse_config_time(page_time):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
167 if page_time is None:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
168 return None
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
169
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
170 if isinstance(page_time, datetime.timedelta):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
171 return page_time
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
172
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
173 if isinstance(page_time, str):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
174 try:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
175 parsed_t = dateutil.parser.parse(page_time)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
176 except Exception as ex:
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
177 raise ConfigurationError("Invalid time: %s" % page_time) from ex
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
178 return datetime.timedelta(
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
179 hours=parsed_t.hour,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
180 minutes=parsed_t.minute,
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
181 seconds=parsed_t.second)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
182
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
183 if isinstance(page_time, int):
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
184 # Total seconds... convert to a time struct.
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
185 return datetime.timedelta(seconds=page_time)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
186
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
187 raise ConfigurationError("Invalid time: %s" % page_time)
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
188
0bdd938d6b9f Better date/time handling for pages:
Ludovic Chabant <ludovic@chabant.com>
parents: 128
diff changeset
189
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
190 class PageLoadingError(Exception):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
191 def __init__(self, path, inner=None):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
192 super(PageLoadingError, self).__init__(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
193 "Error loading page: %s" % path,
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
194 inner)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
195
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
196
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
197 class ContentSegment(object):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
198 debug_render_func = 'debug_render'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
199
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
200 def __init__(self, content=None, fmt=None):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
201 self.parts = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
202 if content is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
203 self.parts.append(ContentSegmentPart(content, fmt))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
204
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
205 def debug_render(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
206 return '\n'.join([p.content for p in self.parts])
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
207
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
208
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
209 class ContentSegmentPart(object):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
210 def __init__(self, content, fmt=None, line=-1):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
211 self.content = content
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
212 self.fmt = fmt
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
213 self.line = line
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
214
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
215 def __str__(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
216 return '%s [%s]' % (self.content, self.fmt or '<default>')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
217
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
218
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
219 def json_load_segments(data):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
220 segments = {}
5
474c9882decf Upgrade to Python 3.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
221 for key, seg_data in data.items():
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
222 seg = ContentSegment()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
223 for p_data in seg_data:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
224 part = ContentSegmentPart(p_data['c'], p_data['f'], p_data['l'])
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
225 seg.parts.append(part)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
226 segments[key] = seg
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
227 return segments
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
228
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
229
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
230 def json_save_segments(segments):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
231 data = {}
5
474c9882decf Upgrade to Python 3.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
232 for key, seg in segments.items():
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
233 seg_data = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
234 for part in seg.parts:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
235 p_data = {'c': part.content, 'f': part.fmt, 'l': part.line}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
236 seg_data.append(p_data)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
237 data[key] = seg_data
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
238 return data
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
239
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
240
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
241 def load_page(app, path, path_mtime=None):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
242 try:
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
243 return _do_load_page(app, path, path_mtime)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
244 except Exception as e:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
245 logger.exception("Error loading page: %s" %
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
246 os.path.relpath(path, app.root_dir))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
247 _, __, traceback = sys.exc_info()
5
474c9882decf Upgrade to Python 3.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
248 raise PageLoadingError(path, e).with_traceback(traceback)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
249
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
250
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
251 def _do_load_page(app, path, path_mtime):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
252 # Check the cache first.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
253 cache = app.cache.getCache('pages')
112
d31cbbdb4ecc Use cache paths that are easier to debug than hashes.
Ludovic Chabant <ludovic@chabant.com>
parents: 108
diff changeset
254 rel_path = os.path.relpath(path, app.root_dir)
d31cbbdb4ecc Use cache paths that are easier to debug than hashes.
Ludovic Chabant <ludovic@chabant.com>
parents: 108
diff changeset
255 cache_path = "%s.json" % rel_path.replace('/', '_').strip('_')
49
fce061f8c2ed Fix cache validation issue with rendered segments, limit disk access.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
256 page_time = path_mtime or os.path.getmtime(path)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
257 if cache.isValid(cache_path, page_time):
67
563ce5dd02af I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents: 49
diff changeset
258 cache_data = json.loads(cache.read(cache_path),
563ce5dd02af I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents: 49
diff changeset
259 object_pairs_hook=collections.OrderedDict)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
260 config = PageConfiguration(values=cache_data['config'],
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
261 validate=False)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
262 content = json_load_segments(cache_data['content'])
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
263 return config, content, True
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
264
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
265 # Nope, load the page from the source file.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
266 logger.debug("Loading page configuration from: %s" % path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
267 with codecs.open(path, 'r', 'utf-8') as fp:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
268 raw = fp.read()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
269 header, offset = parse_config_header(raw)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
270
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
271 if not 'format' in header:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
272 auto_formats = app.config.get('site/auto_formats')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
273 name, ext = os.path.splitext(path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
274 header['format'] = auto_formats.get(ext, None)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
275
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
276 config = PageConfiguration(header)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
277 content = parse_segments(raw, offset)
5
474c9882decf Upgrade to Python 3.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
278 config.set('segments', list(content.keys()))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
279
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
280 # Save to the cache.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
281 cache_data = {
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
282 'config': config.get(),
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
283 'content': json_save_segments(content)}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
284 cache.write(cache_path, json.dumps(cache_data))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
285
96
0445a2232de7 Improvements and fixes to incremental baking.
Ludovic Chabant <ludovic@chabant.com>
parents: 90
diff changeset
286 return config, content, False
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
287
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
288
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
289 segment_pattern = re.compile(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
290 r"""^\-\-\-\s*(?P<name>\w+)(\:(?P<fmt>\w+))?\s*\-\-\-\s*$""",
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
291 re.M)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
292 part_pattern = re.compile(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
293 r"""^<\-\-\s*(?P<fmt>\w+)\s*\-\->\s*$""",
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
294 re.M)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
295
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
296
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
297 def _count_lines(s):
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
298 return len(s.split('\n'))
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
299
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
300
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
301 def parse_segments(raw, offset=0):
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
302 # Get the number of lines in the header.
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
303 header_lines = _count_lines(raw[:offset].rstrip())
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
304 current_line = header_lines
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
305
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
306 # Start parsing.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
307 matches = list(segment_pattern.finditer(raw, offset))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
308 num_matches = len(matches)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
309 if num_matches > 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
310 contents = {}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
311
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
312 first_offset = matches[0].start()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
313 if first_offset > 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
314 # There's some default content segment at the beginning.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
315 seg = ContentSegment()
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
316 seg.parts, current_line = parse_segment_parts(
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
317 raw, offset, first_offset, current_line)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
318 contents['content'] = seg
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
319
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
320 for i in range(1, num_matches):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
321 m1 = matches[i - 1]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
322 m2 = matches[i]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
323 seg = ContentSegment()
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
324 seg.parts, current_line = parse_segment_parts(
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
325 raw, m1.end() + 1, m2.start(), current_line,
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
326 m1.group('fmt'))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
327 contents[m1.group('name')] = seg
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
328
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
329 # Handle text past the last match.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
330 lastm = matches[-1]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
331 seg = ContentSegment()
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
332 seg.parts, current_line = parse_segment_parts(
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
333 raw, lastm.end() + 1, len(raw), current_line,
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
334 lastm.group('fmt'))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
335 contents[lastm.group('name')] = seg
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
336
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
337 return contents
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
338 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
339 # No segments, just content.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
340 seg = ContentSegment()
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
341 seg.parts, current_line = parse_segment_parts(
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
342 raw, offset, len(raw), current_line)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
343 return {'content': seg}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
344
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
345
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
346 def parse_segment_parts(raw, start, end, line_offset, first_part_fmt=None):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
347 matches = list(part_pattern.finditer(raw, start, end))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
348 num_matches = len(matches)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
349 if num_matches > 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
350 parts = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
351
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
352 # First part, before the first format change.
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
353 part_text = raw[start:matches[0].start()]
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
354 parts.append(
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
355 ContentSegmentPart(part_text, first_part_fmt, line_offset))
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
356 line_offset += _count_lines(part_text)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
357
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
358 for i in range(1, num_matches):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
359 m1 = matches[i - 1]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
360 m2 = matches[i]
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
361 part_text = raw[m1.end() + 1:m2.start()]
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
362 parts.append(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
363 ContentSegmentPart(
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
364 part_text, m1.group('fmt'), line_offset))
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
365 line_offset += _count_lines(part_text)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
366
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
367 lastm = matches[-1]
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
368 part_text = raw[lastm.end() + 1:end]
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
369 parts.append(ContentSegmentPart(
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
370 part_text, lastm.group('fmt'), line_offset))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
371
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
372 return parts, line_offset
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
373 else:
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
374 part_text = raw[start:end]
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
375 parts = [ContentSegmentPart(part_text, first_part_fmt, line_offset)]
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 112
diff changeset
376 return parts, line_offset
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
377