--- a/.hgignore Thu Feb 12 23:05:49 2009 +0200
+++ b/.hgignore Sat Sep 13 23:46:32 2014 +0300
@@ -1,5 +1,7 @@
-syntax: regexp
-\.[^/]+.sw[op]$
-\.pyc$
-^cache/templates/.
+syntax: glob
+.*.swo
+.*.swp
+*.pyc
+
+opt/
--- a/__init__.py Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-"""
- The www.qmsk.net site is just a simple site with a filesystem-based URL mapping
-"""
-
--- a/index.cgi Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#!/usr/bin/python2.5
-# :set filetype=py encoding=utf8
-
-"""
- CGI implementation
-"""
-
-# CGI handler for WSGI
-import wsgiref.handlers
-
-def cgi_error () :
- """
- Dumps out a raw traceback of the current exception to stdout, intended for use from except
- """
-
- import traceback, sys
-
- print 'Status: 500 Internal Server Error\r'
- print 'Content-type: text/plain\r'
- print '\r'
-
- traceback.print_exc(100, sys.stdout)
-
-def cgi_main () :
- """
- Run in CGI mode
- """
-
- try :
- from qmsk.web import wsgi, template
- import lookup
-
- # create handler
- cgi_handler = wsgiref.handlers.CGIHandler()
-
- # create app handler
- handler = lookup.PageMapper("pages", templates=template.TemplateLoader("templates"))
-
- # create app
- app = wsgi.Application(handler)
-
- # run once
- cgi_handler.run(app)
-
- except :
- cgi_error()
-
-if __name__ == '__main__' :
- cgi_main()
--- a/lookup.py Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-
-import os, os.path
-
-from qmsk.web import http, template, handler
-
-import page, page_tree
-
-class PageMapper (handler.RequestHandler) :
- """
- Translates requests to handlers based on a filesystem directory containing various kinds of files
- """
-
- # list of page handlers, by type
- PAGE_TYPES = [
- ('html', page.HTMLPage ),
- (template.TEMPLATE_EXT, page.TemplatePage ),
- ]
-
- def __init__ (self, path, templates) :
- """
- Create, path is where the pages are stored. The list of pages is loaded from $path/list
- """
-
- # store
- self.path = path
- self.templates = templates
-
- # load the page tree
- self.tree = page_tree.PageTree(path + '/list')
-
- def _lookup_page_type (self, url, path, filename, basename, extension, tail) :
- """
- We found the file that we looked for, now get the correct type
- """
-
- # find appropriate handler
- for handler_ext, type in self.PAGE_TYPES :
- # match against file extension?
- if handler_ext == extension :
- # found handler, return instance
- return type(self, url, path, basename, tail)
-
- # no handler found
- raise PageError("No handler found for page %r of type %r" % (url, extension))
-
- def _lookup_page (self, name) :
- """
- Look up and return a Page object for the given page, or raise an error
- """
-
- # inital path
- path = self.path
- url_segments = []
-
- # name segments
- segments = name.split('/')
-
- # iterate through the parts of the page segments
- while True :
- segment = None
-
- # pop segment
- if segments :
- segment = segments.pop(0)
-
- url_segments.append(segment)
-
- # translate empty -> index
- if not segment :
- segment = 'index'
-
- # look for it in the dir
- for filename in os.listdir(path) :
- # build full file path
- file_path = os.path.join(path, filename)
-
- # stat, recurse into subdirectory?
- if os.path.isdir(file_path) and filename == segment :
- # use new dir
- path = file_path
-
- # break for-loop to look at next segment
- break
-
- # split into basename + extension
- basename, extension = os.path.splitext(filename)
-
- # ...remove that dot
- extension = extension.lstrip('.')
-
- # match against requested page name?
- if basename == segment :
- # found the file we wanted
- return self._lookup_page_type('/'.join(url_segments), file_path, filename, basename, extension, '/'.join(segments))
-
- else :
- # inspect next file in dir
- continue
-
- else :
- # did not find any dir or file, break out of while loop
- break
-
- # did not find the filename we were looking for in os.listdir
- raise map.MapperError(name)
-
- def handle_request (self, request) :
- """
- Looks up the appropriate Page, and then renders it
- """
-
- # determine the page name
- page_name = request.get_page_name()
-
- # get the page handler
- page = self._lookup_page(page_name)
-
- # pass on
- return page.handle_request(request)
-
--- a/menu.py Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-"""
- Handling the list of available pages
-"""
-
-class Menu (object) :
- """
- Contains info needed to render the menu
- """
-
- def __init__ (self, fs, page) :
- """
- Gather the menu information for the given page, as part of the given FilesystemMapper
- """
-
- # the selected page
- self.page = fs.tree.get_page(page.url)
-
- # the selected pagen's inheritance
- self.ancestry = self.page.get_ancestry() if self.page else []
-
- # list of menu items == root children, since we always show the full menu...
- self.items = fs.tree.root.children
-
--- a/page.py Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-
-"""
- Handling page requests
-"""
-
-# for filesystem ops
-import os, os.path
-import time
-
-from qmsk.web import http, handler, 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
- return self.fs.templates.render_to_response("layout",
- req = request,
- page = self,
- menu = menu.Menu(self.fs, self),
- )
-
-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 self.fs.templates.render_file(self.path,
- page_tree = self.fs.tree,
- )
-
--- a/page_tree.py Thu Feb 12 23:05:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-"""
- Implements the tree containing pages and their metadata
-"""
-
-from qmsk.web import tree_parse
-
-class PageTreeError (Exception) :
- """
- Error parsing/loading the page tree
- """
-
- pass
-
-class PageInfo (object) :
- """
- Contains metainformation about a page
- """
-
- def __init__ (self, parent, name, title, children=None) :
- """
- Initialize, children defaults to empty list
- """
-
- # store
- self.parent = parent
- self.name = name
- self.title = title
- self.children = children if children else []
-
- # no url get
- self._url = None
-
- def set_parent (self, parent) :
- """
- Set a parent where non was set before
- """
-
- assert self.parent is None
-
- self.parent = parent
-
- def add_child (self, child) :
- """
- Add a PageInfo child
- """
-
- self.children.append(child)
-
- def get_child (self, name) :
- """
- Look up a child by name, returning None if not found
- """
-
- return dict((c.name, c) for c in self.children).get(name)
-
- def get_ancestry (self) :
- """
- Returns a list of this page's parents and the page itself, but not root
- """
-
- # collect in reverse order
- ancestry = []
-
- # starting from self
- item = self
-
- # add all items, but not root
- while item and item.parent :
- ancestry.append(item)
-
- item = item.parent
-
- # reverse
- ancestry.reverse()
-
- # done
- return ancestry
-
- @property
- def url (self) :
- """
- Build this page's URL
- """
-
- # cached?
- if self._url :
- return self._url
-
- segments = [item.name for item in self.get_ancestry()]
-
- # add empty segment if dir
- if self.children :
- segments.append('')
-
- # join
- url = '/'.join(segments)
-
- # cache
- self._url = url
-
- # done
- return url
-
-class PageTree (object) :
- """
- The tree of pages, rooted at .root.
-
- Use load_page_tree to initialize the global page_tree instance, and then use that
- """
-
- def __init__ (self, path) :
- """
- Loads the PageTree root from the given file
- """
-
- # store
- self.path = path
-
- # load
- self._load(path)
-
- def _load (self, path) :
- """
- Processes the lines in the given file
- """
-
- # parse tree
- tree = tree_parse.parse(path, ':')
-
- if not tree :
- raise PageTreeError("No root node found")
-
- def _create_node (parent, item) :
- """
- Creates and returns a PageInfo from the given parent node and (line_number, line, children) tuple item
- """
-
- # unpack
- line_number, line, children = item
-
- # parse line
- url = title = None
-
- try :
- url, title = line.split(':')
-
- except :
- raise PageTreeError("Invalid line: %s:%d: %r" % (path, line_number, line))
-
- # remove whitespace
- url = url.strip()
- title = title.strip()
-
- # create PageInfo
- node = PageInfo(parent, url, title)
-
- # set node children
- node.children = [
- _create_node(node, child_item) for child_item in children
- ]
-
- # return
- return node
-
- # translate
- self.root = _create_node(None, tree)
-
- # *evil cackle*
- self.root.children.insert(0, self.root)
-
- def get_page (self, url) :
- """
- Lookup the given page URL, and return the matching PageInfo object, or None, if not found
- """
-
- # start from root
- node = self.root
-
- # traverse the object tree
- for segment in url.split('/') :
- if segment :
- node = node.get_child(segment)
-
- if not node :
- return None
-
- # return
- return node
-
- def get_siblings (self, url) :
- """
- Get the list of siblings for the given url, including the given page itself
- """
-
- # look up the page itself
- page = self.get_page(url)
-
- # specialcase root/unknown node
- if page and page.parent :
- return page.parent.children
-
- else :
- return self.root.children
-
- def dump (self) :
- """
- Returns a string representation of the tree
- """
-
- def _print_node (indent, node) :
- return '\n'.join('%s%s' % (' '*indent, line) for line in [
- "%-15s : %s" % (node.name, node.title)
- ] + [
- _print_node(indent + 4, child) for child in node.children if child != node
- ])
-
- return _print_node(0, self.root)
-