imip-agent

Annotated imip_manager.py

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