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