1 #!/usr/bin/env python 2 3 import cgi, os, sys 4 5 sys.path.append("/var/lib/imip-agent") 6 7 import markup 8 import imip_store 9 10 getenv = os.environ.get 11 setenv = os.environ.__setitem__ 12 13 class CGIEnvironment: 14 15 "A CGI-compatible environment." 16 17 def __init__(self): 18 self.args = None 19 self.method = None 20 self.path = None 21 self.path_info = None 22 self.user = None 23 24 def get_args(self): 25 if self.args is None: 26 if self.get_method() != "POST": 27 setenv("QUERY_STRING", "") 28 self.args = cgi.parse(keep_blank_values=True) 29 return self.args 30 31 def get_method(self): 32 if self.method is None: 33 self.method = getenv("REQUEST_METHOD") or "GET" 34 return self.method 35 36 def get_path(self): 37 if self.path is None: 38 self.path = getenv("SCRIPT_NAME") or "" 39 return self.path 40 41 def get_path_info(self): 42 if self.path_info is None: 43 self.path_info = getenv("PATH_INFO") or "" 44 return self.path_info 45 46 def get_user(self): 47 if self.user is None: 48 self.user = getenv("REMOTE_USER") or "" 49 return self.user 50 51 def get_output(self): 52 return sys.stdout 53 54 def get_url(self): 55 path = self.get_path() 56 path_info = self.get_path_info() 57 return "%s%s" % (path.rstrip("/"), path_info) 58 59 class Manager: 60 61 "A simple manager application." 62 63 def __init__(self): 64 self.store = imip_store.FileStore() 65 self.env = CGIEnvironment() 66 user = self.env.get_user() 67 self.user = user and "mailto:%s" % user or None 68 self.out = self.env.get_output() 69 self.page = markup.page() 70 self.encoding = "utf-8" 71 72 def new_page(self, title): 73 self.page.init(title=title, charset=self.encoding) 74 75 def status(self, code, message): 76 print >>self.out, "Status:", code, message 77 78 def no_user(self): 79 self.status(403, "Forbidden") 80 self.new_page(title="Forbidden") 81 self.page.p("You are not logged in and thus cannot access scheduling requests.") 82 83 def show_requests(self): 84 85 "Show requests for the current user." 86 87 # NOTE: This list could be more informative, but it is envisaged that 88 # NOTE: the requests would be visited directly anyway. 89 90 self.new_page(title="Pending Requests") 91 self.page.ul() 92 93 requests = self.store.get_requests(self.user) 94 for request in requests: 95 self.page.li() 96 self.page.a(request, href="%s/%s" % (self.env.get_url(), request)) 97 self.page.li.close() 98 99 self.page.ul.close() 100 101 def select_action(self): 102 103 "Select the desired action and show the result." 104 105 path_info = self.env.get_path_info().rstrip("/") 106 if not path_info: 107 self.show_requests() 108 109 def show(self): 110 111 "Interpret a request and show an appropriate response." 112 113 if not self.user: 114 self.no_user() 115 else: 116 self.select_action() 117 118 print >>self.out, "Content-Type: text/html; charset=%s" % self.encoding 119 print >>self.out 120 self.out.write(unicode(self.page).encode(self.encoding)) 121 122 if __name__ == "__main__": 123 Manager().show() 124 125 # vim: tabstop=4 expandtab shiftwidth=4