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