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