Mercurial > piecrust2
comparison piecrust/environment.py @ 3:f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
- Serving works, with debug window.
- Baking works, multi-threading, with dependency handling.
- Various things not implemented yet.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 10 Aug 2014 23:43:16 -0700 |
parents | aaa8fb7c8918 |
children | 30a42341cfa8 |
comparison
equal
deleted
inserted
replaced
2:40fa08b261b9 | 3:f485ba500df3 |
---|---|
1 import time | |
1 import logging | 2 import logging |
2 from decorators import lazy_property | 3 import threading |
4 import repoze.lru | |
3 | 5 |
4 | 6 |
5 logger = logging.getLogger(__name__) | 7 logger = logging.getLogger(__name__) |
6 | 8 |
7 | 9 |
8 class PageRepository(object): | 10 class MemCache(object): |
9 pass | 11 def __init__(self, size=2048): |
12 self.cache = repoze.lru.LRUCache(size) | |
13 self.lock = threading.RLock() | |
14 | |
15 def get(self, key, item_maker): | |
16 item = self.cache.get(key) | |
17 if item is None: | |
18 logger.debug("Acquiring lock for: %s" % key) | |
19 with self.lock: | |
20 item = self.cache.get(key) | |
21 if item is None: | |
22 logger.debug("'%s' not found in cache, must build." % key) | |
23 item = item_maker() | |
24 self.cache.put(key, item) | |
25 return item | |
10 | 26 |
11 | 27 |
12 class ExecutionContext(object): | 28 PHASE_PAGE_PARSING = 0 |
13 pass | 29 PHASE_PAGE_FORMATTING = 1 |
30 PHASE_PAGE_RENDERING = 2 | |
31 | |
32 | |
33 class ExecutionInfo(object): | |
34 def __init__(self, page, phase, render_ctx): | |
35 self.page = page | |
36 self.phase = phase | |
37 self.render_ctx = render_ctx | |
38 self.was_cache_valid = False | |
39 self.start_time = time.clock() | |
40 | |
41 | |
42 class ExecutionInfoStack(threading.local): | |
43 def __init__(self): | |
44 self._page_stack = [] | |
45 | |
46 @property | |
47 def current_page_info(self): | |
48 if len(self._page_stack) == 0: | |
49 return None | |
50 return self._page_stack[-1] | |
51 | |
52 @property | |
53 def is_main_page(self): | |
54 return len(self._page_stack) == 1 | |
55 | |
56 def pushPage(self, page, phase, render_ctx): | |
57 self._page_stack.append(ExecutionInfo(page, phase, render_ctx)) | |
58 | |
59 def popPage(self): | |
60 del self._page_stack[-1] | |
14 | 61 |
15 | 62 |
16 class Environment(object): | 63 class Environment(object): |
17 def __init__(self): | 64 def __init__(self): |
18 self.page_repository = PageRepository() | 65 self.start_time = time.clock() |
19 self._execution_ctx = None | 66 self.exec_info_stack = ExecutionInfoStack() |
67 self.was_cache_cleaned = False | |
68 self.page_repository = MemCache() | |
69 self.rendered_segments_repository = MemCache() | |
70 self.base_asset_url_format = '%site_root%%uri%' | |
20 | 71 |
21 def initialize(self, app): | 72 def initialize(self, app): |
22 pass | 73 pass |
23 | |
24 @lazy_property | |
25 def pages(self): | |
26 logger.debug("Loading pages...") | |
27 return self._loadPages() | |
28 | |
29 @lazy_property | |
30 def posts(self): | |
31 logger.debug("Loading posts...") | |
32 return self._loadPosts() | |
33 | |
34 @lazy_property | |
35 def file_system(self): | |
36 return None | |
37 | |
38 def get_execution_context(self, auto_create=False): | |
39 if auto_create and self._execution_ctx is None: | |
40 self._execution_ctx = ExecutionContext() | |
41 return self._execution_ctx | |
42 | |
43 def _loadPages(self): | |
44 raise NotImplementedError() | |
45 | |
46 def _loadPosts(self): | |
47 raise NotImplementedError() | |
48 | 74 |
49 | 75 |
50 class StandardEnvironment(Environment): | 76 class StandardEnvironment(Environment): |
51 def __init__(self): | 77 def __init__(self): |
52 super(StandardEnvironment, self).__init__() | 78 super(StandardEnvironment, self).__init__() |