terom@5: terom@7: """ terom@7: Handling page requests terom@7: """ terom@7: terom@8: # for filesystem ops terom@8: import os, os.path terom@21: import time terom@7: terom@33: from lib import http, handler, template, config terom@33: terom@33: import menu terom@8: terom@8: class PageError (http.ResponseError) : terom@8: """ terom@8: Error looking up/handling a page terom@8: """ terom@8: terom@8: pass terom@8: terom@11: # XXX: should inherit from PageInfo terom@33: class Page (handler.RequestHandler) : terom@8: """ terom@8: This object represents the information about our attempt to render some specific page terom@8: """ terom@8: terom@31: def __init__ (self, fs, url, path, basename, url_tail, charset='utf8') : terom@8: """ terom@8: Initialize the page at the given location terom@31: terom@31: @param fs the FilesysteMapper terom@8: @param url the URL leading to this page terom@8: @param path the filesystem path to this page's file terom@8: @param basename the filesystem name of this page's file, without the file extension terom@8: @param url_trail trailing URL for this page terom@21: @param charset file charset terom@8: """ terom@8: terom@8: # store terom@31: self.fs = fs terom@8: self.url = url terom@8: self.path = path terom@8: self.basename = basename terom@8: self.url_tail = url_tail terom@21: self.charset = charset terom@8: terom@8: # sub-init terom@8: self._init() terom@8: terom@8: def _init (self) : terom@8: """ terom@8: Do initial data loading, etc terom@8: """ terom@8: terom@8: pass terom@8: terom@9: @property terom@9: def title (self) : terom@8: """ terom@8: Return the page's title terom@8: terom@9: Defaults to the retreiving the page title from page_list, or basename in Titlecase. terom@8: """ terom@9: terom@31: # lookup in PageTree terom@31: page_info = self.fs.tree.get_page(self.url) terom@9: terom@9: # fallback to titlecase terom@11: if page_info : terom@11: title = page_info.title terom@11: terom@11: else : terom@9: title = self.basename.title() terom@8: terom@9: return title terom@9: terom@9: @property terom@9: def content (self) : terom@8: """ terom@8: Return the page content as a string terom@8: """ terom@8: terom@8: abstract terom@21: terom@21: @property terom@21: def modified (self) : terom@21: """ terom@21: Returns the page modification timestamp terom@21: """ terom@21: terom@21: # stat terom@21: timestamp = os.stat(self.path).st_mtime terom@21: terom@26: return time.strftime(config.DATETIME_FMT, time.gmtime(timestamp)) terom@33: terom@33: def handle_request (self, request) : terom@33: """ terom@33: Renders the fs's layout template with this page + menu terom@33: """ terom@33: terom@33: # render the template terom@33: response_data = template.render(self.fs.template, terom@33: request = request, terom@33: site_root_url = request.get_script_dir(), terom@33: site_page_url = request.get_page_prefix(), terom@33: page = self, terom@33: menu = menu.Menu(self.fs, self), terom@33: ) terom@33: terom@33: # return the response terom@33: return http.Response(response_data) terom@8: terom@8: class HTMLPage (Page) : terom@8: """ terom@8: A simple .html page that's just passed through directly terom@8: """ terom@8: terom@9: @property terom@9: def content (self) : terom@8: """ terom@8: Opens the .html file, reads and returns contents terom@8: """ terom@8: terom@21: return open(self.path, 'rb').read().decode(self.charset) terom@8: terom@8: class TemplatePage (Page) : terom@8: """ terom@8: A template that's rendered using our template library terom@8: """ terom@9: terom@9: @property terom@9: def content (self) : terom@8: """ terom@8: Loads the .tmpl file, and renders it terom@8: """ terom@8: terom@32: return template.TemplateLoader.render_file(self.path, terom@33: page_tree = self.fs.tree, terom@10: ) terom@7: