paul@102 | 1 | #!/usr/bin/env python |
paul@102 | 2 | |
paul@102 | 3 | """ |
paul@102 | 4 | Handle Confluence wiki requests employing special identifiers that should map to |
paul@102 | 5 | wiki pages. |
paul@102 | 6 | """ |
paul@102 | 7 | |
paul@102 | 8 | import cgi, os, sys |
paul@102 | 9 | |
paul@102 | 10 | # Location of the mapping. |
paul@102 | 11 | |
paul@102 | 12 | MAPPING_ID_TO_PAGE = "mapping-id-to-page.txt" |
paul@102 | 13 | |
paul@102 | 14 | # An empty string means that the wiki is anchored at the site root. |
paul@102 | 15 | |
paul@102 | 16 | URL_PREFIX = "" |
paul@102 | 17 | |
paul@102 | 18 | # See the scripts/tiny.py program for similar code in a stand-alone program. |
paul@102 | 19 | |
paul@102 | 20 | from base64 import b64decode |
paul@102 | 21 | from struct import unpack |
paul@102 | 22 | |
paul@102 | 23 | def identifier(s): |
paul@102 | 24 | if len(s) > 6: |
paul@102 | 25 | return None |
paul@102 | 26 | bytes = b64decode(s.replace("-", "/").replace("_", "+") + "=" * (6 - len(s))) |
paul@102 | 27 | return str(unpack("<I", bytes + "\x00" * (4 - len(bytes)))[0]) |
paul@102 | 28 | |
paul@102 | 29 | # Utility functions. |
paul@102 | 30 | |
paul@102 | 31 | def fail(pageid): |
paul@102 | 32 | print """\ |
paul@102 | 33 | Status: 404 Page not found |
paul@102 | 34 | Content-Type: text/html |
paul@102 | 35 | |
paul@102 | 36 | <html> |
paul@102 | 37 | <head><title>Bad Page Identifier</title></head> |
paul@102 | 38 | <body> |
paul@102 | 39 | <h1>Bad Page Identifier</h1> |
paul@102 | 40 | <p>The identifier given in the URL%s does not seem to refer to a page in this wiki.</p> |
paul@102 | 41 | </body> |
paul@102 | 42 | </html> |
paul@102 | 43 | """ % (pageid and " (%s)" % pageid or "") |
paul@102 | 44 | sys.exit(0) |
paul@102 | 45 | |
paul@102 | 46 | def redirect(pagename): |
paul@102 | 47 | location = "%s/%s" % (URL_PREFIX, pagename) |
paul@102 | 48 | |
paul@102 | 49 | print """\ |
paul@102 | 50 | Status: 302 Redirect to page |
paul@102 | 51 | Location: %s |
paul@102 | 52 | Content-Type: text/html |
paul@102 | 53 | |
paul@102 | 54 | <html> |
paul@102 | 55 | <head><title>Redirecting to Page</title></head> |
paul@102 | 56 | <body> |
paul@102 | 57 | <h1>Redirecting to Page</h1> |
paul@102 | 58 | <p>If you see this message, try following <a href="%s">this link</a>.</p> |
paul@102 | 59 | </body> |
paul@102 | 60 | </html> |
paul@102 | 61 | """ % (location, cgi.escape(location, True)) |
paul@102 | 62 | sys.exit(0) |
paul@102 | 63 | |
paul@102 | 64 | def find(f, pageid): |
paul@102 | 65 | for line in f.xreadlines(): |
paul@102 | 66 | columns = line.strip().split("\t") |
paul@102 | 67 | if columns[0] == pageid: |
paul@102 | 68 | redirect(columns[1]) |
paul@102 | 69 | |
paul@102 | 70 | def main(): |
paul@102 | 71 | args = cgi.parse_qs(os.environ.get("QUERY_STRING", "")) |
paul@102 | 72 | path = os.environ.get("PATH_INFO", "").strip("/") |
paul@102 | 73 | |
paul@102 | 74 | pageid = args.get("pageId", [None])[0] or identifier(path) |
paul@102 | 75 | if pageid is None: |
paul@102 | 76 | fail(pageid) |
paul@102 | 77 | |
paul@102 | 78 | f = open(MAPPING_ID_TO_PAGE) |
paul@102 | 79 | try: |
paul@102 | 80 | # With an identifier, find the corresponding page name. |
paul@102 | 81 | |
paul@102 | 82 | find(f, pageid) |
paul@102 | 83 | |
paul@102 | 84 | # Didn't find the page. |
paul@102 | 85 | |
paul@102 | 86 | fail(pageid) |
paul@102 | 87 | |
paul@102 | 88 | finally: |
paul@102 | 89 | f.close() |
paul@102 | 90 | |
paul@102 | 91 | if __name__ == "__main__": |
paul@102 | 92 | main() |
paul@102 | 93 | |
paul@102 | 94 | # vim: tabstop=4 expandtab shiftwidth=4 |