1.1 --- a/README.txt Wed Jul 17 15:45:49 2013 +0200
1.2 +++ b/README.txt Wed Jul 17 17:34:26 2013 +0200
1.3 @@ -111,6 +111,9 @@
1.4 structure. The third mapping is provided as a convenience, combining the "tiny
1.5 URL" conversion and the arbitrary mapping to page names.
1.6
1.7 +Translating Requests Using the Mappings
1.8 +---------------------------------------
1.9 +
1.10 Where Web server facilities such as RewriteMap are available for use, the
1.11 first and third mapping files can be used directly. See the Apache
1.12 documentation for details of RewriteMap:
1.13 @@ -120,7 +123,18 @@
1.14 Otherwise, it is more likely that the first file is used by a program that can
1.15 perform a redirect to the appropriate wiki page, and the "tiny URL" decoding
1.16 is also done by this program when deployed in a suitable location to receive
1.17 -such requests.
1.18 +such requests. To support this, the following resources are provided:
1.19 +
1.20 + * scripts/redirect.py
1.21 + * config/mailmanwiki-redirect
1.22 +
1.23 +The latter configuration file should be combined with the Web server
1.24 +configuration file such that the appropriate aliases are able to capture
1.25 +requests and invoke the redirect.py script before the main wiki aliases are
1.26 +consulted. The script itself should be placed in a suitable filesystem
1.27 +location, and the mapping-id-to-page.txt file should be placed alongside it,
1.28 +or it should be placed in a different location and the MAPPING_ID_TO_PAGE
1.29 +variable changed in the script to refer to this different location.
1.30
1.31 Output Structure
1.32 ----------------
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/config/mailmanwiki-redirect Wed Jul 17 17:34:26 2013 +0200
2.3 @@ -0,0 +1,2 @@
2.4 +ScriptAlias /x "/var/www/mmwiki-scripts/redirect.py"
2.5 +ScriptAlias /pages/viewpage.action "/var/www/mmwiki-scripts/redirect.py"
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/scripts/redirect.py Wed Jul 17 17:34:26 2013 +0200
3.3 @@ -0,0 +1,94 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"""
3.7 +Handle Confluence wiki requests employing special identifiers that should map to
3.8 +wiki pages.
3.9 +"""
3.10 +
3.11 +import cgi, os, sys
3.12 +
3.13 +# Location of the mapping.
3.14 +
3.15 +MAPPING_ID_TO_PAGE = "mapping-id-to-page.txt"
3.16 +
3.17 +# An empty string means that the wiki is anchored at the site root.
3.18 +
3.19 +URL_PREFIX = ""
3.20 +
3.21 +# See the scripts/tiny.py program for similar code in a stand-alone program.
3.22 +
3.23 +from base64 import b64decode
3.24 +from struct import unpack
3.25 +
3.26 +def identifier(s):
3.27 + if len(s) > 6:
3.28 + return None
3.29 + bytes = b64decode(s.replace("-", "/").replace("_", "+") + "=" * (6 - len(s)))
3.30 + return str(unpack("<I", bytes + "\x00" * (4 - len(bytes)))[0])
3.31 +
3.32 +# Utility functions.
3.33 +
3.34 +def fail(pageid):
3.35 + print """\
3.36 +Status: 404 Page not found
3.37 +Content-Type: text/html
3.38 +
3.39 +<html>
3.40 +<head><title>Bad Page Identifier</title></head>
3.41 +<body>
3.42 +<h1>Bad Page Identifier</h1>
3.43 +<p>The identifier given in the URL%s does not seem to refer to a page in this wiki.</p>
3.44 +</body>
3.45 +</html>
3.46 +""" % (pageid and " (%s)" % pageid or "")
3.47 + sys.exit(0)
3.48 +
3.49 +def redirect(pagename):
3.50 + location = "%s/%s" % (URL_PREFIX, pagename)
3.51 +
3.52 + print """\
3.53 +Status: 302 Redirect to page
3.54 +Location: %s
3.55 +Content-Type: text/html
3.56 +
3.57 +<html>
3.58 +<head><title>Redirecting to Page</title></head>
3.59 +<body>
3.60 +<h1>Redirecting to Page</h1>
3.61 +<p>If you see this message, try following <a href="%s">this link</a>.</p>
3.62 +</body>
3.63 +</html>
3.64 +""" % (location, cgi.escape(location, True))
3.65 + sys.exit(0)
3.66 +
3.67 +def find(f, pageid):
3.68 + for line in f.xreadlines():
3.69 + columns = line.strip().split("\t")
3.70 + if columns[0] == pageid:
3.71 + redirect(columns[1])
3.72 +
3.73 +def main():
3.74 + args = cgi.parse_qs(os.environ.get("QUERY_STRING", ""))
3.75 + path = os.environ.get("PATH_INFO", "").strip("/")
3.76 +
3.77 + pageid = args.get("pageId", [None])[0] or identifier(path)
3.78 + if pageid is None:
3.79 + fail(pageid)
3.80 +
3.81 + f = open(MAPPING_ID_TO_PAGE)
3.82 + try:
3.83 + # With an identifier, find the corresponding page name.
3.84 +
3.85 + find(f, pageid)
3.86 +
3.87 + # Didn't find the page.
3.88 +
3.89 + fail(pageid)
3.90 +
3.91 + finally:
3.92 + f.close()
3.93 +
3.94 +if __name__ == "__main__":
3.95 + main()
3.96 +
3.97 +# vim: tabstop=4 expandtab shiftwidth=4