diff --git a/plugins/Stats/StatsPlugin.py b/plugins/Stats/StatsPlugin.py
new file mode 100644
index 00000000..72d3be22
--- /dev/null
+++ b/plugins/Stats/StatsPlugin.py
@@ -0,0 +1,135 @@
+import re, time, cgi, os
+from Plugin import PluginManager
+
+@PluginManager.registerTo("UiRequest")
+class UiRequestPlugin(object):
+ def formatTableRow(self, row):
+ back = []
+ for format, val in row:
+ if val == None:
+ formatted = "n/a"
+ elif format == "since":
+ if val:
+ formatted = "%.0f" % (time.time()-val)
+ else:
+ formatted = "n/a"
+ else:
+ formatted = format % val
+ back.append("
%s | " % formatted)
+ return "%s
" % "".join(back)
+
+
+ def getObjSize(self, obj, hpy = None):
+ if hpy:
+ return float(hpy.iso(obj).domisize)/1024
+ else:
+ return 0
+
+
+ # /Stats entry point
+ def actionStats(self):
+ import gc, sys
+ from Ui import UiRequest
+
+ hpy = None
+ if self.get.get("size") == "1": # Calc obj size
+ try:
+ import guppy
+ hpy = guppy.hpy()
+ except:
+ pass
+ self.sendHeader()
+ s = time.time()
+ main = sys.modules["main"]
+
+ # Style
+ yield """
+
+ """
+
+ # Memory
+ try:
+ import psutil
+ process = psutil.Process(os.getpid())
+ mem = process.get_memory_info()[0] / float(2 ** 20)
+ yield "Memory usage: %.2fMB | " % mem
+ yield "Threads: %s | " % len(process.threads())
+ yield "CPU: usr %.2fs sys %.2fs | " % process.cpu_times()
+ yield "Open files: %s | " % len(process.open_files())
+ yield "Sockets: %s" % len(process.connections())
+ yield " | Calc size on off
"
+ except Exception, err:
+ pass
+
+ yield "Connections (%s):
" % len(main.file_server.connections)
+ yield " id | protocol | type | ip | ping | buff | "
+ yield "idle | open | delay | sent | received | last sent | waiting | version | peerid |
"
+ for connection in main.file_server.connections:
+ yield self.formatTableRow([
+ ("%3d", connection.id),
+ ("%s", connection.protocol),
+ ("%s", connection.type),
+ ("%s", connection.ip),
+ ("%6.3f", connection.last_ping_delay),
+ ("%s", connection.incomplete_buff_recv),
+ ("since", max(connection.last_send_time, connection.last_recv_time)),
+ ("since", connection.start_time),
+ ("%.3f", connection.last_sent_time-connection.last_send_time),
+ ("%.0fkB", connection.bytes_sent/1024),
+ ("%.0fkB", connection.bytes_recv/1024),
+ ("%s", connection.last_cmd),
+ ("%s", connection.waiting_requests.keys()),
+ ("%s", connection.handshake.get("version")),
+ ("%s", connection.handshake.get("peer_id")),
+ ])
+ yield "
"
+
+ from greenlet import greenlet
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, greenlet)]
+ yield "
Greenlets (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj)))
+
+
+ from Worker import Worker
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, Worker)]
+ yield "
Workers (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj)))
+
+
+ from Connection import Connection
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, Connection)]
+ yield "
Connections (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj)))
+
+
+ from Site import Site
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, Site)]
+ yield "
Sites (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj)))
+
+
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, self.server.log.__class__)]
+ yield "
Loggers (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj.name)))
+
+
+ objs = [obj for obj in gc.get_objects() if isinstance(obj, UiRequest)]
+ yield "
UiRequest (%s):
" % len(objs)
+ for obj in objs:
+ yield " - %.3fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj)))
+
+ objs = [(key, val) for key, val in sys.modules.iteritems() if val is not None]
+ objs.sort()
+ yield "
Modules (%s):
" % len(objs)
+ for module_name, module in objs:
+ yield " - %.3fkb: %s %s
" % (self.getObjSize(module, hpy), module_name, cgi.escape(repr(module)))
+
+ yield "Done in %.3f" % (time.time()-s)
diff --git a/plugins/Stats/__init__.py b/plugins/Stats/__init__.py
new file mode 100644
index 00000000..90bd9d6e
--- /dev/null
+++ b/plugins/Stats/__init__.py
@@ -0,0 +1 @@
+import StatsPlugin
\ No newline at end of file
diff --git a/plugins/disabled-DonationMessage/DonationMessagePlugin.py b/plugins/disabled-DonationMessage/DonationMessagePlugin.py
new file mode 100644
index 00000000..00be03f1
--- /dev/null
+++ b/plugins/disabled-DonationMessage/DonationMessagePlugin.py
@@ -0,0 +1,24 @@
+import re
+from Plugin import PluginManager
+
+# Warning: If you modify the donation address then renmae the plugin's directory to "MyDonationMessage" to prevent the update script overwrite
+
+
+@PluginManager.registerTo("UiRequest")
+class UiRequestPlugin(object):
+ # Inject a donation message to every page top right corner
+ def actionWrapper(self, path):
+ back = super(UiRequestPlugin, self).actionWrapper(path)
+ if not back or not hasattr(back, "endswith"): return back # Wrapper error or not string returned, injection not possible
+
+ back = re.sub("