Mercurial > piecrust2
comparison piecrust/baking/records.py @ 91:e88e330eb8dc
Improvements to incremental baking and cache invalidating.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 05 Sep 2014 00:42:13 -0700 |
parents | 3471ffa059b2 |
children | 0445a2232de7 |
comparison
equal
deleted
inserted
replaced
90:e293f08d954e | 91:e88e330eb8dc |
---|---|
1 import os.path | |
1 import logging | 2 import logging |
3 from piecrust import APP_VERSION | |
2 from piecrust.sources.base import PageSource | 4 from piecrust.sources.base import PageSource |
3 from piecrust.records import Record | 5 from piecrust.records import Record |
4 | 6 |
5 | 7 |
6 logger = logging.getLogger(__name__) | 8 logger = logging.getLogger(__name__) |
9 | |
10 | |
11 RECORD_VERSION = 4 | |
7 | 12 |
8 | 13 |
9 def _get_transition_key(source_name, rel_path, taxonomy_name=None, | 14 def _get_transition_key(source_name, rel_path, taxonomy_name=None, |
10 taxonomy_term=None): | 15 taxonomy_term=None): |
11 key = '%s:%s' % (source_name, rel_path) | 16 key = '%s:%s' % (source_name, rel_path) |
17 key += taxonomy_term | 22 key += taxonomy_term |
18 return key | 23 return key |
19 | 24 |
20 | 25 |
21 class BakeRecord(Record): | 26 class BakeRecord(Record): |
22 VERSION = 1 | |
23 | |
24 def __init__(self): | 27 def __init__(self): |
25 super(BakeRecord, self).__init__() | 28 super(BakeRecord, self).__init__() |
26 self.out_dir = None | 29 self.out_dir = None |
27 self.bake_time = None | 30 self.bake_time = None |
31 self.app_version = APP_VERSION | |
32 self.record_version = RECORD_VERSION | |
33 | |
34 def hasLatestVersion(self): | |
35 return (self.app_version == APP_VERSION and | |
36 self.record_version == RECORD_VERSION) | |
37 | |
38 def __setstate__(self, state): | |
39 state.setdefault('app_version', -1) | |
40 state.setdefault('record_version', -1) | |
41 super(BakeRecord, self).__setstate__(state) | |
42 | |
43 | |
44 FLAG_NONE = 0 | |
45 FLAG_SOURCE_MODIFIED = 2**0 | |
46 FLAG_OVERRIDEN = 2**1 | |
28 | 47 |
29 | 48 |
30 class BakeRecordPageEntry(object): | 49 class BakeRecordPageEntry(object): |
31 def __init__(self, page=None): | 50 def __init__(self, factory, taxonomy_name=None, taxonomy_term=None): |
32 self.path = None | 51 self.path = factory.path |
33 self.rel_path = None | 52 self.rel_path = factory.rel_path |
34 self.source_name = None | 53 self.source_name = factory.source.name |
54 self.taxonomy_name = taxonomy_name | |
55 self.taxonomy_term = taxonomy_term | |
56 self.path_mtime = os.path.getmtime(factory.path) | |
57 | |
58 self.flags = FLAG_NONE | |
35 self.config = None | 59 self.config = None |
36 self.taxonomy_name = None | |
37 self.taxonomy_term = None | |
38 self.was_overriden = False | |
39 self.out_uris = [] | 60 self.out_uris = [] |
40 self.out_paths = [] | 61 self.out_paths = [] |
41 self.used_source_names = set() | 62 self.used_source_names = set() |
42 self.used_taxonomy_terms = set() | 63 self.used_taxonomy_terms = set() |
43 | |
44 if page: | |
45 self.path = page.path | |
46 self.rel_path = page.rel_path | |
47 self.source_name = page.source.name | |
48 self.config = page.config.get() | |
49 | 64 |
50 @property | 65 @property |
51 def was_baked(self): | 66 def was_baked(self): |
52 return len(self.out_paths) > 0 | 67 return len(self.out_paths) > 0 |
53 | 68 |
62 | 77 |
63 def addUsedSource(self, source): | 78 def addUsedSource(self, source): |
64 if isinstance(source, PageSource): | 79 if isinstance(source, PageSource): |
65 self.used_source_names.add(source.name) | 80 self.used_source_names.add(source.name) |
66 | 81 |
82 def __getstate__(self): | |
83 state = self.__dict__.copy() | |
84 del state['path_mtime'] | |
85 return state | |
86 | |
67 | 87 |
68 class TransitionalBakeRecord(object): | 88 class TransitionalBakeRecord(object): |
69 DELETION_MISSING = 1 | 89 DELETION_MISSING = 1 |
70 DELETION_CHANGED = 2 | 90 DELETION_CHANGED = 2 |
71 | 91 |
72 def __init__(self, previous_path=None): | 92 def __init__(self, previous_path=None): |
73 self.previous = BakeRecord() | 93 self.previous = BakeRecord() |
74 self.current = BakeRecord() | 94 self.current = BakeRecord() |
75 self.transitions = {} | 95 self.transitions = {} |
96 self.incremental_count = 0 | |
76 if previous_path: | 97 if previous_path: |
77 self.loadPrevious(previous_path) | 98 self.loadPrevious(previous_path) |
78 self.current.entry_added += self._onCurrentEntryAdded | 99 self.current.entry_added += self._onCurrentEntryAdded |
79 | 100 |
80 def loadPrevious(self, previous_path): | 101 def loadPrevious(self, previous_path): |
91 | 112 |
92 def saveCurrent(self, current_path): | 113 def saveCurrent(self, current_path): |
93 self.current.save(current_path) | 114 self.current.save(current_path) |
94 | 115 |
95 def addEntry(self, entry): | 116 def addEntry(self, entry): |
117 if (self.previous.bake_time and | |
118 entry.path_mtime >= self.previous.bake_time): | |
119 entry.flags |= FLAG_SOURCE_MODIFIED | |
96 self.current.addEntry(entry) | 120 self.current.addEntry(entry) |
97 | 121 |
98 def getOverrideEntry(self, factory, uri): | 122 def getOverrideEntry(self, factory, uri): |
99 for pair in self.transitions.values(): | 123 for pair in self.transitions.values(): |
100 prev = pair[0] | 124 prev = pair[0] |
118 pair = self.transitions.get(key) | 142 pair = self.transitions.get(key) |
119 if pair is not None: | 143 if pair is not None: |
120 return pair[0] | 144 return pair[0] |
121 return None | 145 return None |
122 | 146 |
147 def getCurrentEntries(self, source_name): | |
148 return [e for e in self.current.entries | |
149 if e.source_name == source_name] | |
150 | |
123 def collapseRecords(self): | 151 def collapseRecords(self): |
124 for pair in self.transitions.values(): | 152 for pair in self.transitions.values(): |
125 prev = pair[0] | 153 prev = pair[0] |
126 cur = pair[1] | 154 cur = pair[1] |
127 | 155 |
128 if prev and cur and not cur.was_baked: | 156 if prev and cur and not cur.was_baked: |
129 # This page wasn't baked, so the information from last | 157 # This page wasn't baked, so the information from last |
130 # time is still valid (we didn't get any information | 158 # time is still valid (we didn't get any information |
131 # since we didn't bake). | 159 # since we didn't bake). |
132 cur.was_overriden = prev.was_overriden | 160 cur.flags = prev.flags |
161 if prev.config: | |
162 cur.config = prev.config.copy() | |
133 cur.out_uris = list(prev.out_uris) | 163 cur.out_uris = list(prev.out_uris) |
134 cur.out_paths = list(prev.out_paths) | 164 cur.out_paths = list(prev.out_paths) |
135 cur.used_source_names = set(prev.used_source_names) | 165 cur.used_source_names = set(prev.used_source_names) |
136 cur.used_taxonomy_terms = set(prev.used_taxonomy_terms) | 166 cur.used_taxonomy_terms = set(prev.used_taxonomy_terms) |
137 | 167 |