from cgi import escape
import threading
try:
from urllib import quote
except ImportError:
from urllib.parse import quote
from wsgiref.simple_server import make_server
from wsgiref.util import request_uri, application_uri, shift_path_info
import wmi
try:
unicode
except NameError:
unicode = str
doc = []
def link (text, computer, namespace=None, wmi_class=None):
link = '' + escape (text) + ''
def start_doc (title):
doc[:] = []
doc.append ("""
%(title)s
""" % locals ())
def finish_doc ():
doc.append ("""
""" % locals ())
def doc_table (items, n_cols=3):
n_rows, n_spare_cols = divmod (len (items), n_cols)
doc.append ('')
for n_row in range (n_rows):
doc.append ("")
for n_col in range (n_cols):
doc.append ("%s | " % items[n_cols * n_col + n_row])
doc.append ("
")
if n_spare_cols:
doc.append ("")
for n_col in reversed (range (n_spare_cols)):
doc.append ("%s | " % items[len (items) - 1 - n_col])
doc.append ("
")
doc.append ("
")
def doc_breadcrumbs (computer, namespace, wmi_class=None):
doc.append ('')
doc.append ('%s → %s' % (link (computer, computer), link (namespace, computer, namespace)))
if wmi_class:
doc.append (' → %s' % (link (wmi_class, computer, namespace, wmi_class)))
doc.append ('
')
def doc_wmi_class (computer, namespace, wmi_class, wmi_connection):
start_doc ("WMI: Class %(wmi_class)s in namespace %(namespace)s on %(computer)s" % locals ())
doc_breadcrumbs (computer, namespace, wmi_class)
doc.append ("%(wmi_class)s
" % locals ())
klass = getattr (wmi_connection, wmi_class)
doc.append ("
")
doc.append ("Ancestors
")
ancestors = klass.derivation ()
if ancestors:
doc.append (" : ".join (link (ancestor, computer, namespace, ancestor) for ancestor in reversed (ancestors)))
else:
doc.append ("No ancestors
")
doc.append ("
")
doc.append ("Children
")
children = sorted (c.Path_.Class for c in klass._namespace.SubclassesOf (wmi_class))
if children:
doc.append ('')
for child in children:
doc.append ('- %s
' % link (child, computer, namespace, child))
doc.append ('
')
else:
doc.append ('No children
')
doc.append ("
")
doc.append ("Associated classes
")
associations = sorted (klass.associated_classes)
if associations:
doc.append ("")
for association in associations:
doc.append ('- %s
' % link (association, computer, namespace, association))
doc.append ("
")
else:
doc.append ("No associated classes
")
doc.append ("
")
doc.append ("Properties
")
properties = sorted (klass._properties)
n_properties = len (properties)
if n_properties == 0:
doc.append ("No properties
")
if 1 <= n_properties <= 10:
doc_table (properties, 1)
elif 10 < n_properties <= 20:
doc_table (properties, 2)
elif 20 < n_properties <= 30:
doc_table (properties, 3)
else:
doc_table (properties, 4)
doc.append ("
")
doc.append ("Keys
")
keys = sorted (klass.keys)
if keys:
doc.append ("")
for key in keys:
doc.append ("- %s
" % key)
doc.append ("
")
else:
doc.append ("No keys
")
doc.append ("
")
doc.append ("Methods
")
methods = sorted (klass._methods)
if methods:
doc.append ("")
for m in methods:
doc.append ('- %s
%s ' % (m, escape (str (getattr (klass, m)))))
doc.append ("
")
else:
doc.append ("No methods
")
doc.append ("
")
doc.append ("Qualifiers
")
qualifiers = sorted (klass.qualifiers.items ())
if qualifiers:
doc.append ("")
for q in qualifiers:
doc.append ("- %s: %s
" % q)
doc.append ("
")
else:
doc.append ("No qualifiers
")
finish_doc ()
def doc_namespace (computer, namespace, wmi_connection):
start_doc ("WMI: Namespace %(namespace)s on %(computer)s" % locals ())
doc_breadcrumbs (computer, namespace)
namespaces = namespace.split ("\\")
namespace_links = []
for i, n in enumerate (namespaces):
namespace_links.append (link (n, computer, "\\".join (namespaces[:i+1])))
doc.append ("%s
" % "\\".join (namespace_links))
doc.append ("
")
subnamespaces = sorted (wmi_connection.__NAMESPACE ())
doc.append ("Namespaces:
")
if subnamespaces:
doc.append ("")
for subnamespace in subnamespaces:
name = subnamespace.Name
doc.append ('- %s
' % link (name, computer, namespace + "\\" + name))
doc.append ("
")
else:
doc.append ("No namespaces
")
doc.append ("
")
subclasses = sorted (wmi_connection.classes)
doc.append ("Classes:
")
if subclasses:
doc.append ("")
for subclass in subclasses:
doc.append ('- %s
' % link (subclass, computer, namespace, subclass))
doc.append ("
")
else:
doc.append ("No classes
")
finish_doc ()
def handle_namespace (environ, computer, namespace):
if not namespace:
wmi_connection = wmi.WMI (computer, namespace="root/cimv2")
for setting in wmi_connection.Win32_WMISetting ():
namespace=setting.ASPScriptDefaultNamespace
break
wmi_connection = wmi.WMI (computer, namespace=namespace, find_classes=True)
wmi_class = shift_path_info (environ)
if wmi_class:
doc_wmi_class (computer, namespace, wmi_class, wmi_connection)
else:
doc_namespace (computer, namespace, wmi_connection)
def handle_computer (environ, computer):
handle_namespace (environ, computer, shift_path_info (environ))
def app (environ, start_response):
computer = shift_path_info (environ)
if computer == "favicon.ico":
start_response ("404 Not Found", [("Content-Type", "text/plain")])
return []
elif computer:
start_response ("200 OK", [("Content-Type", "text/html; charset=utf-8")])
handle_computer (environ, computer)
return (unicode (d).encode ("utf8") + unicode ("\n").encode ("utf8") for d in doc)
else:
start_response ("301 Moved Permanently", [("Location", "/localhost"), ("Content-Type", "text/plain")])
return ["Redirected to /localhost"]
PORT = 8010
def run_browser ():
import os
os.startfile ("http://localhost:%d" % PORT)
if __name__ == '__main__':
threading.Timer (3.0, run_browser).start ()
httpd = make_server ('', PORT, app)
try:
httpd.serve_forever ()
except KeyboardInterrupt:
print ("Shutting down gracefully...")