/usr/share/pyshared/Pyblosxom/plugins/flavourfiles.py is in pyblosxom 1.5.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | #######################################################################
# This file is part of Pyblosxom.
#
# Copyright (c) 2010, 2011 Will Kahn-Greene
#
# Pyblosxom is distributed under the MIT license. See the file
# LICENSE for distribution details.
#######################################################################
"""
Summary
=======
This plugin allows flavour templates to use file urls that will
resolve to files in the flavour directory. Those files will then get
served by Pyblosxom.
This solves the problem that flavour packs are currently difficult to
package, install, and maintain because static files (images, css, js,
...) have to get put somewhere else and served by the web server and
this is difficult to walk a user through.
It handles urls that start with ``flavourfiles/``, then the flavour
name, then the path to the file.
For example::
http://example.com/blog/flavourfiles/html/style.css
.. Note::
This plugin is very beta! It's missing important functionality,
probably has bugs, and hasn't been well tested!
Install
=======
This plugin comes with Pyblosxom. To install, do the following:
1. Add ``Pyblosxom.plugins.flavourfiles`` to the ``load_plugins`` list
of your ``config.py`` file.
2. In templates you want to use flavourfiles, use urls like this::
$(base_url)/flavourfiles/$(flavour)/path-to-file
For example::
<img src="$(base_url)/flavourfiles/$(flavour)/header_image.jpg">
The ``$(base_url)`` will get filled in with the correct url root.
The ``$(flavour)`` will get filled in with the name of the url. This
allows users to change the flavour name without having to update all
the templates.
"""
__author__ = "Will Kahn-Greene"
__email__ = "willg at bluesock dot org"
__version__ = "2011-10-22"
__url__ = "http://pyblosxom.github.com/"
__description__ = "Serves static files related to flavours (css, js, ...)"
__license__ = "MIT License"
__registrytags__ = "1.5, core, experimental"
import os
import mimetypes
import sys
from Pyblosxom.renderers import base
TRIGGER = "/flavourfiles/"
class FileRenderer(base.RendererBase):
def set_filepath(self, filepath):
self.filepath = filepath
def render(self, header=True):
if not os.path.exists(self.filepath):
self.render_404()
self.rendered = 1
return
# FIXME - handle e-tag/etc conditional stuff here
try:
fp = open(self.filepath, "r")
except OSError:
# FIXME - this could be a variety of issues, but is
# probably a permission denied error. should catch the
# error message and send it to the 403 page.
self.render_403()
self.rendered = 1
return
# mimetype
mimetype = mimetypes.guess_type(self.filepath)
if mimetype:
mimetype = mimetype[0]
if mimetype is None:
mimetype = "application/octet-stream"
self.add_header('Content-type', mimetype)
# content length
length = os.stat(self.filepath)[6]
self.add_header('Content-Length', str(length))
if header:
self.show_headers()
self.write(fp.read())
fp.close()
self.rendered = 1
def render_403(self):
resp = self._request.getResponse()
resp.set_status("403 Forbidden")
def render_404(self):
resp = self._request.getResponse()
resp.set_status("404 Not Found")
def cb_handle(args):
"""This is the flavour file handler.
This handles serving static files related to flavours. It handles
paths like /flavourfiles/<flavour>/<path-to-file>.
It calls the prepare callback to do any additional preparation
before rendering the entries.
Then it tells the renderer to render the entries.
:param request: the request object.
"""
request = args["request"]
path_info = request.get_http()["PATH_INFO"]
if not path_info.startswith(TRIGGER):
return
config = request.get_configuration()
data = request.get_data()
# get the renderer object
rend = FileRenderer(request, config.get("stdoutput", sys.stdout))
data['renderer'] = rend
filepath = path_info.replace(TRIGGER, "")
while filepath.startswith(("/", os.sep)):
filepath = filepath[1:]
if not filepath:
rend.render_404()
return
filepath = filepath.split("/")
flavour = filepath[0]
filepath = "/".join(filepath[1:])
root = config.get("flavourdir", config["datadir"])
root = os.path.join(root, flavour + ".flav")
filepath = os.path.join(root, filepath)
filepath = os.path.normpath(filepath)
if not filepath.startswith(root) or not os.path.exists(filepath):
rend.render_404()
return
rend.set_filepath(filepath)
rend.render()
return 1
|