20 class Tree (object): |
23 class Tree (object): |
21 INDEX = 'index' |
24 INDEX = 'index' |
22 |
25 |
23 @classmethod |
26 @classmethod |
24 def lookup (cls, site, parts): |
27 def lookup (cls, site, parts): |
25 path = site.root |
28 """ |
26 |
29 Returns Tree |
27 for part in parts: |
30 |
28 if part.startswith('.'): |
31 Raises NotFound |
|
32 """ |
|
33 |
|
34 parents = ( ) |
|
35 tree = cls(site.root, None, parents, site, |
|
36 title = site.name, |
|
37 ) |
|
38 |
|
39 for name in parts: |
|
40 if name.startswith('.'): |
29 # evil |
41 # evil |
30 return None |
42 raise NotFound() |
31 |
43 |
32 if not part: |
44 if not name: |
33 continue |
45 continue |
34 |
46 |
35 path = os.path.join(path, part) |
47 path = os.path.join(tree.path, name) |
36 |
48 |
37 if not os.path.exists(path): |
49 if not os.path.exists(path): |
38 return None |
50 raise NotFound() |
39 |
51 |
40 if not os.path.isdir(path): |
52 if not os.path.isdir(path): |
41 return None |
53 raise NotFound() |
42 |
54 |
43 return cls(path, parts, site) |
55 parents += (tree, ) |
44 |
56 tree = cls(path, name, parents, site) |
45 def __init__ (self, path, parts, site): |
57 |
|
58 return tree |
|
59 |
|
60 def __init__ (self, path, name, parents, site, |
|
61 title = None, |
|
62 ): |
|
63 """ |
|
64 path: filesystem path |
|
65 name: subtree name, or None for root |
|
66 parents: (Tree) |
|
67 site: Site |
|
68 """ |
|
69 |
46 self.path = path |
70 self.path = path |
47 self.parts = parts |
71 self.name = name |
|
72 self.parents = parents |
48 self.site = site |
73 self.site = site |
49 |
74 |
|
75 self.title = title or name |
|
76 |
|
77 def hierarchy (self): |
|
78 """ |
|
79 Yield Tree. |
|
80 """ |
|
81 |
|
82 for tree in self.parents: |
|
83 yield tree |
|
84 |
|
85 yield self |
|
86 |
50 def url (self, tree=None, page=None): |
87 def url (self, tree=None, page=None): |
51 path = '/'.join(self.parts) |
88 path = '/'.join(tree.name for tree in self.hierarchy() if tree.name is not None) |
52 |
89 |
53 if path: |
90 if path: |
54 path += '/' |
91 path += '/' |
55 |
92 |
56 if tree: |
93 if tree: |
172 tree_parts = [] |
200 tree_parts = [] |
173 |
201 |
174 # scan dir |
202 # scan dir |
175 tree = Tree.lookup(site, tree_parts) |
203 tree = Tree.lookup(site, tree_parts) |
176 |
204 |
177 if not tree: |
|
178 return None |
|
179 |
|
180 # scan page |
205 # scan page |
181 page = tree.page(page_name) |
206 page = tree.page(page_name) |
182 |
207 |
183 if not page: |
208 if not page: |
184 return None |
209 raise NotFound() |
185 |
210 |
186 return page |
211 return page |
187 |
212 |
188 def __init__ (self, path, name, tree, encoding=ENCODING): |
213 def __init__ (self, path, name, tree, parents=(), encoding=ENCODING, title=None): |
189 self.path = path |
214 self.path = path |
190 self.name = name |
215 self.name = name |
191 self.tree = tree |
216 self.tree = tree |
|
217 self.parents = parents |
|
218 |
192 self.encoding = encoding |
219 self.encoding = encoding |
|
220 self.title = title or name |
193 |
221 |
194 def url (self): |
222 def url (self): |
195 return self.tree.url(page=self.name) |
223 return self.tree.url(page=self.name) |
196 |
224 |
197 def open (self): |
225 def open (self): |
199 |
227 |
200 def stat (self): |
228 def stat (self): |
201 return os.stat(self.path) |
229 return os.stat(self.path) |
202 |
230 |
203 def breadcrumb (self): |
231 def breadcrumb (self): |
204 for path, name in self.tree.breadcrumb(): |
232 for tree in self.tree.hierarchy(): |
205 yield path, name |
233 yield tree.url(), tree.title |
206 |
234 |
207 if self.name != self.tree.INDEX: |
235 if self.name != self.tree.INDEX: |
208 yield self.url(), self.name |
236 yield self.url(), self.title |
209 |
237 |
210 def modified (self): |
238 def modified (self): |
211 return datetime.datetime.utcfromtimestamp(self.stat().st_mtime) |
239 return datetime.datetime.utcfromtimestamp(self.stat().st_mtime) |
212 |
240 |
213 def render (self, request): |
241 def render (self, request): |