lib/filesystem/page.py
author Tero Marttila <terom@fixme.fi>
Sat, 07 Feb 2009 17:07:06 +0200
branchsites
changeset 33 19ea04f4b0cd
parent 32 be954df4f0e8
permissions -rw-r--r--
make Page a RequestHandler in its own right, move code from FilesystemMapper

"""
    Handling page requests
"""

# for filesystem ops
import os, os.path
import time

from lib import http, handler, template, config

import menu

class PageError (http.ResponseError) :
    """
        Error looking up/handling a page
    """

    pass

# XXX: should inherit from PageInfo
class Page (handler.RequestHandler) :
    """
        This object represents the information about our attempt to render some specific page
    """

    def __init__ (self, fs, url, path, basename, url_tail, charset='utf8') :
        """
            Initialize the page at the given location
            
            @param fs the FilesysteMapper
            @param url the URL leading to this page
            @param path the filesystem path to this page's file
            @param basename the filesystem name of this page's file, without the file extension
            @param url_trail trailing URL for this page
            @param charset file charset
        """
        
        # store
        self.fs = fs
        self.url = url
        self.path = path
        self.basename = basename
        self.url_tail = url_tail
        self.charset = charset

        # sub-init
        self._init()

    def _init (self) :
        """
            Do initial data loading, etc
        """
        
        pass

    @property
    def title (self) :
        """
            Return the page's title

            Defaults to the retreiving the page title from page_list, or basename in Titlecase.
        """
        
        # lookup in PageTree
        page_info = self.fs.tree.get_page(self.url)
        
        # fallback to titlecase
        if page_info :
            title = page_info.title

        else :
            title = self.basename.title()

        return title
    
    @property
    def content (self) :
        """
            Return the page content as a string
        """

        abstract
    
    @property
    def modified (self) :
        """
            Returns the page modification timestamp
        """
        
        # stat
        timestamp = os.stat(self.path).st_mtime

        return time.strftime(config.DATETIME_FMT, time.gmtime(timestamp))
    
    def handle_request (self, request) :
        """
            Renders the fs's layout template with this page + menu
        """

        # render the template
        response_data = template.render(self.fs.template,
            request         = request,
            site_root_url   = request.get_script_dir(),
            site_page_url   = request.get_page_prefix(),
            page            = self,
            menu            = menu.Menu(self.fs, self),
        )
        
        # return the response
        return http.Response(response_data)

class HTMLPage (Page) :
    """
        A simple .html page that's just passed through directly
    """

    @property
    def content (self) :
        """
            Opens the .html file, reads and returns contents
        """

        return open(self.path, 'rb').read().decode(self.charset)

class TemplatePage (Page) :
    """
        A template that's rendered using our template library
    """
    
    @property
    def content (self) :
        """
            Loads the .tmpl file, and renders it
        """

        return template.TemplateLoader.render_file(self.path,
            page_tree   = self.fs.tree,
        )