qmsk_www_pages/pages.py
changeset 233 f5227f26231b
parent 232 5a16a53e9800
child 234 70b425280964
--- a/qmsk_www_pages/pages.py	Sat Oct 04 13:32:35 2014 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-from django.conf import settings
-
-import codecs
-import datetime
-import logging; log = logging.getLogger('qmsk_www_pages.pages')
-import os, os.path
-
-import markdown
-import mako.template
-
-class NotFound (Exception):
-    pass
-
-class RenderError (Exception):
-    pass
-
-class Site (object):
-    @classmethod
-    def lookup (cls):
-        return cls(
-            root        = settings.QMSK_WWW_PAGES_DIR,
-            name        = settings.QMSK_WWW_PAGES_SITE,
-        )
-
-    def __init__ (self, root, name):
-        self.root = root
-        self.name = name
-
-    def tree (self):
-        return Tree(self.root, None, (), self,
-                title       = self.name,
-        )
-
-class Tree (object):
-    INDEX = 'index'
-
-    @classmethod
-    def lookup (cls, site, parts):
-        """
-            Returns Tree
-
-            Raises NotFound
-        """
-
-        parents = ( )
-        tree = site.tree()
-
-        for name in parts:
-            if name.startswith('.'):
-                # evil
-                raise NotFound()
-            
-            if not name:
-                continue
-        
-            path = os.path.join(tree.path, name)
-
-            if not os.path.exists(path):
-                raise NotFound()
-            
-            if not os.path.isdir(path):
-                raise NotFound()
-
-            # title
-            title = tree.item_title(name)
-
-            parents += (tree, )
-            tree = cls(path, name, parents, site,
-                    title   = title,
-            )
-
-        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.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(tree.name for tree in self.hierarchy() if tree.name is not None)
-
-        if path:
-            path += '/'
-
-        if tree:
-            path = tree + '/'
-
-        if page:
-            path += page
-
-        return path
-
-    def scan (self):
-        """
-            Scan for files in tree.
-        """
-
-        for filename in os.listdir(self.path):
-            if filename.startswith('.'):
-                continue
-            
-            if '.' in filename:
-                file_name, file_type = filename.rsplit('.', 1)
-            else:
-                file_name = filename
-                file_type = None
-
-            if not file_name:
-                continue
-
-            path = os.path.join(self.path, filename)
-            
-            yield path, file_name, file_type
-
-    def item_title (self, name):
-        """
-            Lookup item title if exists.
-        """
-
-        title_path = os.path.join(self.path, name + '.title')
-
-        log.info("%s: %s title_path=%s", self, name, title_path)
-
-        if os.path.exists(title_path):
-            return open(title_path).read().strip()
-        else:
-            return None
-
-    def list (self):
-        """
-            Lists all Trees and Pages for this Tree.
-
-            Yields (name, url, page_type or None, title)
-        """
-        
-        for path, name, file_type in self.scan():
-            title = self.item_title(name) or name
-
-            # trees
-            if os.path.isdir(path):
-                yield name, self.url(tree=name), None, title
-
-            if name == self.INDEX:
-                continue
-            
-            # pages
-            if not file_type:
-                continue
-
-            if file_type not in TYPES:
-                continue
-
-            yield name, self.url(page=name), file_type, title
-
-    def list_sorted (self):
-        return sorted(list(self.list()))
-
-    def page (self, name):
-        """
-            Scans through tree looking for a matching page.
-            
-            Returns Page or None.
-        """
-        
-        if not name:
-            name = self.INDEX
-            title_default = self.title
-        else:
-            title_default = None
-
-        parents = self.parents + (self, )
-
-        for path, file_name, file_type in self.scan():
-            # match on name
-            if file_name == name:
-                pass
-            elif file_type and (file_name + '.' + file_type == name):
-                pass
-            else:
-                continue
-
-            # redirects?
-            if os.path.islink(path):
-                target = os.readlink(path)
-            
-                # XXX: this should be some kind of common code
-                if '.' in target:
-                    target, target_type = target.rsplit('.', 1)
-
-                log.info("%s: %s -> %s", self, name, target)
-
-                return RedirectPage(path, name, self, parents,
-                    target  = target,
-                )
-            
-            # match on type
-            if not file_type:
-                continue
-
-            page_type = TYPES.get(file_type)
-
-            if not page_type:
-                continue
-            
-            # out
-            title = self.item_title(file_name) or title_default
-
-            return page_type(path, name, self, parents,
-                title   = title,
-            )
-
-class Page (object):
-    ENCODING = 'utf-8'
-
-    @classmethod
-    def lookup (cls, site, page):
-        """
-            Returns Page.
-            
-            Raises NotFound
-        """
-        
-        log.info("page=%r", page)
-
-        if page:
-            parts = page.split('/')
-        else:
-            parts = [ ]
-            
-        if parts:
-            page_name = parts.pop(-1)
-            tree_parts = parts
-        else:
-            page_name = ''
-            tree_parts = []
-
-        # scan dir
-        tree = Tree.lookup(site, tree_parts)
-
-        # scan page
-        page = tree.page(page_name)
-
-        if not page:
-            raise NotFound()
-
-        return page
-
-    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 hierarchy (self):
-        """
-            Yield (Tree, name) pairs
-        """
-
-        parent = None
-
-        for tree in self.parents:
-            if parent:
-                yield parent, tree.name
-
-            parent = tree
-
-        yield parent, self.name
-
-    def url (self):
-        return self.tree.url(page=self.name)
-
-    def open (self):
-        return codecs.open(self.path, encoding=self.encoding)
-
-    def stat (self):
-        return os.stat(self.path)
-
-    def breadcrumb (self):
-        for tree in self.tree.hierarchy():
-            yield tree.url(), tree.title
-        
-        if self.name != self.tree.INDEX:
-            yield self.url(), self.title
-
-    def modified (self):
-        return datetime.datetime.utcfromtimestamp(self.stat().st_mtime)
-
-    def redirect_page (self, request):
-        return None
-    
-    def render_html (self, request):
-        raise NotImplementedError()
-
-# TODO: tree redirects
-class RedirectPage (Page):
-    def __init__ (self, path, name, tree, parents,
-            target,
-            **opts
-    ) :
-        super(RedirectPage, self).__init__(path, name, tree, parents, **opts)
-
-        self.target = target
-
-    def redirect_page (self, request):
-        return os.path.normpath(self.tree.url() + '/' + self.target)
-
-class HTML_Page (Page):
-    def render_html (self, request):
-        return self.open().read()
-
-class MarkdownPage (Page):
-    FORMAT = 'html5'
-
-    def __init__ (self, path, name, tree, parents,
-            format=FORMAT,
-            **opts
-    ) :
-        super(MarkdownPage, self).__init__(path, name, tree, parents, **opts)
-
-        self.format = format
-
-    def render_html (self, request):
-        return markdown.markdown(self.open().read(),
-            output_format   = self.format,
-        )
-
-class TemplatePage (Page):
-    def render_html (self, request):
-        """
-            Raises RenderError if !DEBUG, arbitrary error with stack trace otherwise.
-        """
-
-        try:
-            return mako.template.Template(filename=self.path).render(
-                    request = request,
-            )
-        except Exception as error:
-            if settings.DEBUG:
-                raise
-            else:
-                raise RenderError(error)
-
-SITE = Site.lookup()
-
-TYPES = {
-    'html':         HTML_Page,
-    'md':           MarkdownPage,
-    'markdown':     MarkdownPage,
-    'tmpl':         TemplatePage,
-}
-
-def page (page):
-    return Page.lookup(SITE, page)
-