comparison piecrust/baking/records.py @ 334:b034f6f15e22

bake: Several bug taxonomy-related fixes for incorrect incremental bakes. * Improve how the baker processes taxonomy terms and figures out what needs to be re-baked or not. * Create bake entries for clean taxnomy terms so they're not deleted by an incremental bake. * Add more information to bake records. * Slugify taxonomy terms is now done by the route in one place. * Fix a bug where the cache key for invalidating rendered segments was not computed the same way as when the caching was done. * Fix how term combinations are passed around, rendered, printed, parsed, etc. (TODO: more word needed in the routing functions) * Expose to the template whether a taxonomy term is a combination or not. * Display term combinations better in the built-in theme. * Rename `route.taxonomy` to `route.taxonomy_name` to prevent confusion. * Add options to show bake records for previous bakes.
author Ludovic Chabant <ludovic@chabant.com>
date Fri, 03 Apr 2015 10:59:50 -0700
parents 1f4c3dae1fe8
children 938be93215cb
comparison
equal deleted inserted replaced
333:91b07f9efdc1 334:b034f6f15e22
1 import os.path 1 import os.path
2 import logging 2 import logging
3 from piecrust.sources.base import PageSource
4 from piecrust.records import Record, TransitionalRecord 3 from piecrust.records import Record, TransitionalRecord
5 4
6 5
7 logger = logging.getLogger(__name__) 6 logger = logging.getLogger(__name__)
8 7
9 8
10 def _get_transition_key(source_name, rel_path, taxonomy_name=None, 9 def _get_transition_key(source_name, rel_path, taxonomy_info=None):
11 taxonomy_term=None):
12 key = '%s:%s' % (source_name, rel_path) 10 key = '%s:%s' % (source_name, rel_path)
13 if taxonomy_name and taxonomy_term: 11 if taxonomy_info:
14 key += ';%s:' % taxonomy_name 12 taxonomy_name, taxonomy_term, taxonomy_source_name = taxonomy_info
13 key += ';%s:%s=' % (taxonomy_source_name, taxonomy_name)
15 if isinstance(taxonomy_term, tuple): 14 if isinstance(taxonomy_term, tuple):
16 key += '/'.join(taxonomy_term) 15 key += '/'.join(taxonomy_term)
17 else: 16 else:
18 key += taxonomy_term 17 key += taxonomy_term
19 return key 18 return key
20 19
21 20
22 class BakeRecord(Record): 21 class BakeRecord(Record):
23 RECORD_VERSION = 9 22 RECORD_VERSION = 11
24 23
25 def __init__(self): 24 def __init__(self):
26 super(BakeRecord, self).__init__() 25 super(BakeRecord, self).__init__()
27 self.out_dir = None 26 self.out_dir = None
28 self.bake_time = None 27 self.bake_time = None
30 29
31 30
32 FLAG_NONE = 0 31 FLAG_NONE = 0
33 FLAG_SOURCE_MODIFIED = 2**0 32 FLAG_SOURCE_MODIFIED = 2**0
34 FLAG_OVERRIDEN = 2**1 33 FLAG_OVERRIDEN = 2**1
34 FLAG_FORCED_BY_SOURCE = 2**2
35 35
36 36
37 class BakeRecordPageEntry(object): 37 class BakeRecordPageEntry(object):
38 def __init__(self, factory, taxonomy_name=None, taxonomy_term=None): 38 """ An entry in the bake record.
39 self.path = factory.path 39
40 self.rel_path = factory.rel_path 40 The `taxonomy_info` attribute should be a tuple of the form:
41 self.source_name = factory.source.name 41 (taxonomy name, term, source name)
42 self.taxonomy_name = taxonomy_name 42 """
43 self.taxonomy_term = taxonomy_term 43 def __init__(self, source_name, rel_path, path, taxonomy_info=None):
44 self.path_mtime = os.path.getmtime(factory.path) 44 self.source_name = source_name
45 self.rel_path = rel_path
46 self.path = path
47 self.taxonomy_info = taxonomy_info
45 48
46 self.flags = FLAG_NONE 49 self.flags = FLAG_NONE
47 self.config = None 50 self.config = None
48 self.errors = [] 51 self.errors = []
49 self.out_uris = [] 52 self.out_uris = []
50 self.out_paths = [] 53 self.out_paths = []
54 self.clean_uris = []
55 self.clean_out_paths = []
51 self.used_source_names = set() 56 self.used_source_names = set()
52 self.used_taxonomy_terms = set() 57 self.used_taxonomy_terms = set()
58 self.used_pagination_item_count = 0
59
60 @property
61 def path_mtime(self):
62 return os.path.getmtime(self.path)
53 63
54 @property 64 @property
55 def was_baked(self): 65 def was_baked(self):
56 return len(self.out_paths) > 0 or len(self.errors) > 0 66 return len(self.out_paths) > 0 or len(self.errors) > 0
57 67
60 return len(self.out_paths) > 0 and len(self.errors) == 0 70 return len(self.out_paths) > 0 and len(self.errors) == 0
61 71
62 @property 72 @property
63 def num_subs(self): 73 def num_subs(self):
64 return len(self.out_paths) 74 return len(self.out_paths)
65
66 def __getstate__(self):
67 state = self.__dict__.copy()
68 del state['path_mtime']
69 return state
70 75
71 76
72 class TransitionalBakeRecord(TransitionalRecord): 77 class TransitionalBakeRecord(TransitionalRecord):
73 def __init__(self, previous_path=None): 78 def __init__(self, previous_path=None):
74 super(TransitionalBakeRecord, self).__init__(BakeRecord, 79 super(TransitionalBakeRecord, self).__init__(BakeRecord,
80 entry.flags |= FLAG_SOURCE_MODIFIED 85 entry.flags |= FLAG_SOURCE_MODIFIED
81 super(TransitionalBakeRecord, self).addEntry(entry) 86 super(TransitionalBakeRecord, self).addEntry(entry)
82 87
83 def getTransitionKey(self, entry): 88 def getTransitionKey(self, entry):
84 return _get_transition_key(entry.source_name, entry.rel_path, 89 return _get_transition_key(entry.source_name, entry.rel_path,
85 entry.taxonomy_name, entry.taxonomy_term) 90 entry.taxonomy_info)
86 91
87 def getOverrideEntry(self, factory, uri): 92 def getOverrideEntry(self, factory, uri):
88 for pair in self.transitions.values(): 93 for pair in self.transitions.values():
89 prev = pair[0] 94 prev = pair[0]
90 cur = pair[1] 95 cur = pair[1]
98 prev.rel_path != factory.rel_path) and 103 prev.rel_path != factory.rel_path) and
99 len(prev.out_uris) > 0 and prev.out_uris[0] == uri): 104 len(prev.out_uris) > 0 and prev.out_uris[0] == uri):
100 return prev 105 return prev
101 return None 106 return None
102 107
103 def getPreviousEntry(self, source_name, rel_path, taxonomy_name=None, 108 def getPreviousEntry(self, source_name, rel_path, taxonomy_info=None):
104 taxonomy_term=None): 109 key = _get_transition_key(source_name, rel_path, taxonomy_info)
105 key = _get_transition_key(source_name, rel_path,
106 taxonomy_name, taxonomy_term)
107 pair = self.transitions.get(key) 110 pair = self.transitions.get(key)
108 if pair is not None: 111 if pair is not None:
109 return pair[0] 112 return pair[0]
110 return None 113 return None
111 114