]>
Commit | Line | Data |
---|---|---|
85f01e3f CP |
1 | from twisted.web import resource, server, static |
2 | from cgi import escape | |
3 | from urllib import urlencode | |
4 | import config, copy, time | |
5 | ||
6 | HEADER = """ | |
7 | <html><head><link rel="stylesheet" href="/css/qui.css"></link><link rel="stylesheet" href="/css/dialogs.css"></link></head><body class="qwebirc-qui"> | |
8 | <div class="qwebirc-aboutpane lines" style="bottom: 0px; top: 0px; position: absolute; right: 0px; left: 0px;"> | |
9 | <div class="header"> | |
10 | <table> | |
11 | <tr> | |
12 | <td><img src="/images/qwebircsmall.png" alt="qwebirc" title="qwebirc"/></td> | |
13 | <td> </td> | |
14 | <td align="center"><div class="title">qwebirc</div><div class="version">AdminEngine</div></td> | |
15 | </tr> | |
16 | </table> | |
17 | </div> | |
18 | <div class="mainbody" style="bottom: 100px"> | |
19 | """ | |
20 | ||
21 | FOOTER = """</div></body></html>""" | |
22 | ||
23 | class AdminEngineException(Exception): | |
24 | pass | |
25 | ||
26 | class AdminEngineAction: | |
27 | def __init__(self, link_text, function, uniqid=None): | |
28 | self._link_text = link_text | |
29 | self.function = function | |
30 | self.uniqid = uniqid | |
31 | ||
32 | def get_link(self, **kwargs): | |
33 | kwargs = copy.deepcopy(kwargs) | |
34 | if self.uniqid is not None: | |
35 | kwargs["uniqid"] = self.uniqid | |
36 | return "<a href=\"?%s\">%s</a>" % (urlencode(kwargs), escape(self._link_text)) | |
37 | ||
38 | class AdminEngine(resource.Resource): | |
39 | def __init__(self, path, services): | |
40 | self.__services = services | |
41 | self.__path = path | |
42 | self.__creation_time = time.time() | |
43 | ||
44 | @property | |
45 | def adminEngine(self): | |
46 | return { | |
47 | "Permitted hosts": (config.ADMIN_ENGINE_HOSTS,), | |
48 | "Started": ((time.asctime(time.localtime(self.__creation_time)),),), | |
49 | "Running for": (("%d seconds" % int(time.time() - self.__creation_time),),), | |
50 | "CPU time used (UNIX only)": (("%.2f seconds" % time.clock(),),) | |
51 | } | |
52 | ||
53 | def process_action(self, args): | |
54 | try: | |
55 | engine = args["engine"][0] | |
56 | heading = args["heading"][0] | |
57 | pos = int(args["pos"][0]) | |
58 | pos2 = int(args["pos2"][0]) | |
59 | ||
60 | uniqid = args.get("uniqid", [None])[0] | |
61 | ||
62 | obj = self.__services[engine].adminEngine[heading][pos] | |
63 | except KeyError: | |
64 | raise AdminEngineException("Bad action description.") | |
65 | ||
66 | if uniqid is None: | |
67 | obj[pos2].function() | |
68 | else: | |
69 | for x in obj: | |
70 | if not isinstance(x, AdminEngineAction): | |
71 | continue | |
72 | if x.uniqid == uniqid: | |
73 | x.function(uniqid) | |
74 | break | |
75 | else: | |
76 | raise AdminEngineException("Action does not exist.") | |
77 | ||
78 | def render_GET(self, request): | |
5c0781b1 | 79 | if request.getClientIP() not in config.ADMIN_ENGINE_HOSTS: |
85f01e3f CP |
80 | raise AdminEngineException("Access denied") |
81 | ||
82 | args = request.args.get("engine") | |
83 | if args: | |
84 | self.process_action(request.args) | |
85 | request.redirect("?") | |
86 | request.finish() | |
87 | return server.NOT_DONE_YET | |
88 | ||
89 | data = [HEADER] | |
90 | ||
91 | def add_list(lines): | |
92 | data.append("<ul>") | |
93 | data.extend(["<li>" + escape(x) + "</li>" for x in lines]) | |
94 | data.append("</ul>") | |
95 | ||
96 | def add_text(text, block="p"): | |
97 | data.append("<%s>%s</%s>" % (block, escape(text), block)) | |
98 | ||
99 | def brescape(text): | |
100 | return escape(text).replace("\n", "<br/>") | |
101 | ||
102 | for engine, obj in self.__services.items(): | |
103 | if not hasattr(obj, "adminEngine"): | |
104 | continue | |
105 | add_text(engine, "h2") | |
106 | ||
107 | for heading, obj2 in obj.adminEngine.items(): | |
108 | add_text(heading, "h3") | |
109 | ||
110 | for pos, obj3 in enumerate(obj2): | |
111 | elements = [] | |
112 | for pos2, obj4 in enumerate(obj3): | |
113 | if isinstance(obj4, AdminEngineAction): | |
114 | elements.append(obj4.get_link(engine=engine, heading=heading, pos=pos, pos2=pos2)) | |
115 | else: | |
116 | elements.append(brescape(str(obj4))) | |
117 | ||
118 | data+=["<p>", " ".join(elements), "</p>"] | |
119 | ||
120 | data.append(FOOTER) | |
121 | ||
122 | return "".join(data) |