import py
from mod_python import util
from mod_deco.decorators import *
from lxml import etree

"""The Kupu website

    This is the glue code for the site, the Python handlers that are registered
    in .htaccess in the site root (the 'kupusite' SVN data tree).

    Handlers are very simple, functionality is attached with decorators. See
    the 'mod_deco' package documentation for more details.

    Be sure to know what you're doing when changing anything but the constants
    in the top of the page!! The order of the decorators, and which are in 
    which chain, are very important and changes can break the site in subtle 
    ways.
"""

# no trailing slashes for paths!!
SITEROOT = '/kupusite'
TEMPLATEDIR = '/var/www/kupusite/.templates'
INDEXDIR = '/var/www/kupusite/.indexes'

# a set of decorators all handlers will get, note how we cache very 
# aggressively (which we may want to change if we have 'real' dynamic content,
# meaning content that changes even without form args, etc.)
def basestack(handler):
    def istree(d):
        # XXX somehow 'isinstance(d, etree._Element) fails here?!?
        return hasattr(d, 'tag') and hasattr(d, 'xpath')
    @preparesite()
    @responsewriter()
    @treetostring()
    @cache(createkey=lambda r: (r.filename, r.path_info), 
            condition=lambda r: len(util.FieldStorage(r).keys()) == 0,
            checktype=istree)
    @layout(SITEROOT, '%s/macro.html' % (TEMPLATEDIR,))
    @dictvars(logosrc='%s/.theme/kupu_logo.png' % (SITEROOT,),
                    searchurl='%s/' % (SITEROOT,))
    @stylesheets(SITEROOT, '/.theme/style.css')
    @sidebar(SITEROOT, '%s/sidebar.html' % (TEMPLATEDIR,), 
                    ['index.html', 'index.rst', 'index.txt'])
    @checkerrors()
    @fulltext(SITEROOT, INDEXDIR, 
                    '%s/searchresults.html' % (TEMPLATEDIR,))
    @checknotfound()
    def basestack_wrapper(request):
        return handler(request)
    return basestack_wrapper

# handle plain html files
@basestack
@cache(checktype=lambda d: isinstance(d, dict))
@treetodict(body='//body/*', head='//head/*')
@htmltotree()
def htmlhandler(request):
    request.content_type = 'text/html; charset=UTF-8'
    return py.path.local(request.filename).read()

# handle rest files
@basestack
@cache(checktype=lambda d: isinstance(d, dict))
@treetodict(body='//body/*', head='//head/*')
@htmltotree()
@resttohtml()
def resthandler(request):
    request.content_type = 'text/plain; charset=UTF-8'
    return py.path.local(request.filename).read()

# handle images with thumbnail support, note how we cache both the image and
# the thumbnail
@basestack
@cache(condition=lambda r: 'thumbnail' in r.path_info.split('/'),
        checktype=lambda d: isinstance(d, str))
@thumbnail(150)
@cache()
def imagehandler(request):
    from mimetypes import guess_type
    fname = request.filename
    fpath = py.path.local(fname)
    request.content_type = guess_type(fname)[0]
    return fpath.read()
    
# directories
@basestack
@cache(checktype=lambda d: isinstance(d, dict))
@screenshots('%s/screenshots/' % (SITEROOT,), 
                '%s/screenshots.html' % (TEMPLATEDIR,))
@downloads(['%s/downloads/' % (SITEROOT,), '%s/ecmaunit/' % (SITEROOT,)],
                '%s/downloads.html' % (TEMPLATEDIR,))
@treetodict(body='//body/*', head='//head/*')
@htmltotree()
@resttohtml()
@directories('%s/dirlist.html' % (TEMPLATEDIR,))
def dirhandler(request):
    # return apache.DECLINED for everything, this should be registered only
    # for directories, which are handled by the 'directories' decorator
    return apache.DECLINED

