qmsk_www_pages/pages.py
changeset 68 023b9a9d6c76
parent 65 67d8600fa0a1
child 69 4b8814ff6d6d
--- a/qmsk_www_pages/pages.py	Sun Sep 14 02:28:42 2014 +0300
+++ b/qmsk_www_pages/pages.py	Sun Sep 14 02:52:40 2014 +0300
@@ -5,6 +5,9 @@
 import logging; log = logging.getLogger('qmsk_www_pages.pages')
 import os, os.path
 
+class NotFound (Exception):
+    pass
+
 class Site (object):
     @classmethod
     def lookup (cls):
@@ -22,33 +25,67 @@
 
     @classmethod
     def lookup (cls, site, parts):
-        path = site.root
+        """
+            Returns Tree
 
-        for part in parts:
-            if part.startswith('.'):
+            Raises NotFound
+        """
+
+        parents = ( )
+        tree = cls(site.root, None, parents, site,
+                title       = site.name,
+        )
+
+        for name in parts:
+            if name.startswith('.'):
                 # evil
-                return None
+                raise NotFound()
             
-            if not part:
+            if not name:
                 continue
         
-            path = os.path.join(path, part)
+            path = os.path.join(tree.path, name)
 
             if not os.path.exists(path):
-                return None
+                raise NotFound()
             
             if not os.path.isdir(path):
-                return None
-        
-        return cls(path, parts, site)
+                raise NotFound()
 
-    def __init__ (self, path, parts, site):
+            parents += (tree, )
+            tree = cls(path, name, parents, site)
+
+        return tree
+
+    def __init__ (self, path, name, parents, site,
+            title   = None,
+    ):
+        """
+            path:       filesystem path
+            name:       subtree name, or None for root
+            parents:    (Tree)
+            site:       Site
+        """
+
         self.path = path
-        self.parts = parts
+        self.name = name
+        self.parents = parents
         self.site = site
 
+        self.title = title or name
+
+    def hierarchy (self):
+        """
+            Yield Tree.
+        """
+
+        for tree in self.parents:
+            yield tree
+
+        yield self
+
     def url (self, tree=None, page=None):
-        path = '/'.join(self.parts)
+        path = '/'.join(tree.name for tree in self.hierarchy() if tree.name is not None)
 
         if path:
             path += '/'
@@ -61,16 +98,6 @@
 
         return path
 
-    def breadcrumb (self):
-        path = []
-
-        yield '', self.site.name
-
-        for part in self.parts:
-            path.append(part)
-
-            yield '/'.join(path) + '/', part
-
     def scan (self):
         """
             Scan for files in tree.
@@ -119,7 +146,7 @@
         """
             Scans through tree looking for a matching page.
             
-            Returns Page.
+            Returns Page or None.
         """
         
         if not name:
@@ -144,6 +171,7 @@
                 path    = path,
                 name    = name,
                 tree    = self,
+                parents = self.parents + (self, ),
             )
 
 class Page (object):
@@ -152,9 +180,9 @@
     @classmethod
     def lookup (cls, site, page):
         """
-            Lookup a Page from disk.
-
-            Returns None if there is no such page.
+            Returns Page.
+            
+            Raises NotFound
         """
         
         log.info("page=%r", page)
@@ -174,22 +202,22 @@
         # scan dir
         tree = Tree.lookup(site, tree_parts)
 
-        if not tree:
-            return None
-
         # scan page
         page = tree.page(page_name)
 
         if not page:
-            return None
+            raise NotFound()
 
         return page
 
-    def __init__ (self, path, name, tree, encoding=ENCODING):
+    def __init__ (self, path, name, tree, parents=(), encoding=ENCODING, title=None):
         self.path = path
         self.name = name
         self.tree = tree
+        self.parents = parents
+
         self.encoding = encoding
+        self.title = title or name
 
     def url (self):
         return self.tree.url(page=self.name)
@@ -201,11 +229,11 @@
         return os.stat(self.path)
 
     def breadcrumb (self):
-        for path, name in self.tree.breadcrumb():
-            yield path, name
+        for tree in self.tree.hierarchy():
+            yield tree.url(), tree.title
         
         if self.name != self.tree.INDEX:
-            yield self.url(), self.name
+            yield self.url(), self.title
 
     def modified (self):
         return datetime.datetime.utcfromtimestamp(self.stat().st_mtime)