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