1 #!/usr/bin/env python 2 3 import cgi, os, sys 4 5 sys.path.append("/var/lib/imip-agent") 6 7 from imiptools.content import get_values, parse_object 8 import markup 9 import imip_store 10 11 getenv = os.environ.get 12 setenv = os.environ.__setitem__ 13 14 class CGIEnvironment: 15 16 "A CGI-compatible environment." 17 18 def __init__(self): 19 self.args = None 20 self.method = None 21 self.path = None 22 self.path_info = None 23 self.user = None 24 25 def get_args(self): 26 if self.args is None: 27 if self.get_method() != "POST": 28 setenv("QUERY_STRING", "") 29 self.args = cgi.parse(keep_blank_values=True) 30 return self.args 31 32 def get_method(self): 33 if self.method is None: 34 self.method = getenv("REQUEST_METHOD") or "GET" 35 return self.method 36 37 def get_path(self): 38 if self.path is None: 39 self.path = getenv("SCRIPT_NAME") or "" 40 return self.path 41 42 def get_path_info(self): 43 if self.path_info is None: 44 self.path_info = getenv("PATH_INFO") or "" 45 return self.path_info 46 47 def get_user(self): 48 if self.user is None: 49 self.user = getenv("REMOTE_USER") or "" 50 return self.user 51 52 def get_output(self): 53 return sys.stdout 54 55 def get_url(self): 56 path = self.get_path() 57 path_info = self.get_path_info() 58 return "%s%s" % (path.rstrip("/"), path_info) 59 60 class Manager: 61 62 "A simple manager application." 63 64 def __init__(self): 65 self.store = imip_store.FileStore() 66 self.env = CGIEnvironment() 67 user = self.env.get_user() 68 self.user = user and "mailto:%s" % user or None 69 self.out = self.env.get_output() 70 self.page = markup.page() 71 self.encoding = "utf-8" 72 73 def new_page(self, title): 74 self.page.init(title=title, charset=self.encoding) 75 76 def status(self, code, message): 77 print >>self.out, "Status:", code, message 78 79 def no_user(self): 80 self.status(403, "Forbidden") 81 self.new_page(title="Forbidden") 82 self.page.p("You are not logged in and thus cannot access scheduling requests.") 83 84 def no_page(self): 85 self.status(404, "Not Found") 86 self.new_page(title="Not Found") 87 self.page.p("No page is provided at the given address.") 88 89 def show_requests(self): 90 91 "Show requests for the current user." 92 93 # NOTE: This list could be more informative, but it is envisaged that 94 # NOTE: the requests would be visited directly anyway. 95 96 self.new_page(title="Pending Requests") 97 self.page.ul() 98 99 requests = self.store.get_requests(self.user) 100 101 for request in requests: 102 self.page.li() 103 self.page.a(request, href="%s/%s" % (self.env.get_url(), request)) 104 self.page.li.close() 105 106 self.page.ul.close() 107 108 def show_request(self, path_info): 109 110 "Show a request using the given 'path_info' for the current user." 111 112 uid = path_info.lstrip("/").split("/", 1)[0] 113 f = uid and self.store.get_event(self.user, uid) or None 114 115 if not f: 116 return False 117 118 request = parse_object(f, "utf-8") 119 120 if not request: 121 return False 122 123 self.new_page(title="Request") 124 self.page.p("The following request was received:") 125 self.page.dl() 126 127 for name in ["DTSTART", "DTEND", "ORGANIZER", "ATTENDEE"]: 128 for value in get_values(request, name): 129 self.page.dt(name) 130 self.page.dd(value) 131 132 self.page.dl.close() 133 return True 134 135 def select_action(self): 136 137 "Select the desired action and show the result." 138 139 path_info = self.env.get_path_info().rstrip("/") 140 if not path_info: 141 self.show_requests() 142 elif self.show_request(path_info): 143 pass 144 else: 145 self.no_page() 146 147 def show(self): 148 149 "Interpret a request and show an appropriate response." 150 151 if not self.user: 152 self.no_user() 153 else: 154 self.select_action() 155 156 # Write the headers and actual content. 157 158 print >>self.out, "Content-Type: text/html; charset=%s" % self.encoding 159 print >>self.out 160 self.out.write(unicode(self.page).encode(self.encoding)) 161 162 if __name__ == "__main__": 163 Manager().show() 164 165 # vim: tabstop=4 expandtab shiftwidth=4