comparison piecrust/data/assetor.py @ 867:757fba54bfd3

refactor: Improve pagination and iterators to work with other sources. This makes the assets work as a pagination source again.
author Ludovic Chabant <ludovic@chabant.com>
date Mon, 12 Jun 2017 22:20:58 -0700
parents fddaf43424e2
children 48d25fd68b8d
comparison
equal deleted inserted replaced
866:d9059257743c 867:757fba54bfd3
19 def __init__(self, content_item, uri): 19 def __init__(self, content_item, uri):
20 self.content_item = content_item 20 self.content_item = content_item
21 self.uri = uri 21 self.uri = uri
22 22
23 23
24 class Assetor(collections.abc.Mapping): 24 class Assetor(collections.abc.Sequence):
25 debug_render_doc = """Helps render URLs to files in the current page's 25 debug_render_doc = """Helps render URLs to files in the current page's
26 asset folder.""" 26 asset folder."""
27 debug_render = [] 27 debug_render = []
28 debug_render_dynamic = ['_debugRenderAssetNames'] 28 debug_render_dynamic = ['_debugRenderAssetNames']
29 29
30 def __init__(self, page): 30 def __init__(self, page):
31 self._page = page 31 self._page = page
32 self._cache = None 32 self._cache_map = None
33 self._cache_list = None
33 34
34 def __getattr__(self, name): 35 def __getattr__(self, name):
35 try: 36 try:
36 self._cacheAssets() 37 self._cacheAssets()
37 return self._cache[name].uri 38 return self._cache[name].uri
38 except KeyError: 39 except KeyError:
39 raise AttributeError() 40 raise AttributeError()
40 41
41 def __getitem__(self, key): 42 def __getitem__(self, i):
42 self._cacheAssets() 43 self._cacheAssets()
43 return self._cache[key].uri 44 return self._cache_list[i]
44
45 def __iter__(self):
46 self._cacheAssets()
47 return self._cache.keys()
48 45
49 def __len__(self): 46 def __len__(self):
50 self._cacheAssets() 47 self._cacheAssets()
51 return len(self._cache) 48 return len(self._cache_list)
52 49
53 def _debugRenderAssetNames(self): 50 def _debugRenderAssetNames(self):
54 self._cacheAssets() 51 self._cacheAssets()
55 return list(self._cache.keys()) 52 return list(self._cache.keys())
56 53
57 def _cacheAssets(self): 54 def _cacheAssets(self):
58 if self._cache is not None: 55 if self._cache_map is not None:
59 return 56 return
60 57
61 source = self._page.source 58 source = self._page.source
62 content_item = self._page.content_item 59 content_item = self._page.content_item
60 assets = source.getRelatedContents(content_item, REL_ASSETS)
63 61
64 assets = source.getRelatedContents(content_item, REL_ASSETS) 62 self._cache_map = {}
63 self._cache_list = []
64
65 if assets is None: 65 if assets is None:
66 self._cache = {}
67 return 66 return
68
69 self._cache = {}
70 67
71 app = source.app 68 app = source.app
72 root_dir = app.root_dir 69 root_dir = app.root_dir
73 asset_url_format = app.config.get('site/asset_url_format') 70 asset_url_format = app.config.get('site/asset_url_format')
74 71
83 '%page_uri%': page_uri 80 '%page_uri%': page_uri
84 } 81 }
85 82
86 for a in assets: 83 for a in assets:
87 name = a.metadata['name'] 84 name = a.metadata['name']
88 if name in self._cache: 85 if name in self._cache_map:
89 raise UnsupportedAssetsError( 86 raise UnsupportedAssetsError(
90 "An asset with name '%s' already exists for item '%s'. " 87 "An asset with name '%s' already exists for item '%s'. "
91 "Do you have multiple assets with colliding names?" % 88 "Do you have multiple assets with colliding names?" %
92 (name, content_item.spec)) 89 (name, content_item.spec))
93 90
95 uri_build_tokens['%path%'] = ( 92 uri_build_tokens['%path%'] = (
96 os.path.relpath(a.spec, root_dir).replace('\\', '/')) 93 os.path.relpath(a.spec, root_dir).replace('\\', '/'))
97 uri_build_tokens['%filename%'] = a.metadata['filename'], 94 uri_build_tokens['%filename%'] = a.metadata['filename'],
98 uri = multi_replace(asset_url_format, uri_build_tokens) 95 uri = multi_replace(asset_url_format, uri_build_tokens)
99 96
100 self._cache[name] = _AssetInfo(a, uri) 97 self._cache_map[name] = _AssetInfo(a, uri)
98 self._cache_list.append(uri)
101 99
102 stack = app.env.render_ctx_stack 100 stack = app.env.render_ctx_stack
103 cur_ctx = stack.current_ctx 101 cur_ctx = stack.current_ctx
104 if cur_ctx is not None: 102 if cur_ctx is not None:
105 cur_ctx.current_pass_info.used_assets = True 103 cur_ctx.current_pass_info.used_assets = True