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