]> jfr.im git - irc/quakenet/qwebirc.git/blob - qwebirc/engines/adminengine.py
add dynamic configuration support
[irc/quakenet/qwebirc.git] / qwebirc / engines / adminengine.py
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>&nbsp;&nbsp;&nbsp;&nbsp;</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):
79 if request.getClientIP() not in config.ADMIN_ENGINE_HOSTS:
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)