1#!/usr/bin/python3
2
3# SPDX-License-Identifier: Apache-2.0
4# Copyright 2020 Intel Corp.
5
6import argparse
7import subprocess
8
9from flask import Flask
10
11REPLACE_CHAR = "~"
12
13app = Flask(__name__)
14
15parser = argparse.ArgumentParser(description="Remote DBus Viewer")
16parser.add_argument("-u", "--username", default="root")
17parser.add_argument("-p", "--password", default="0penBmc")
18parser.add_argument("-a", "--address", required=True)
19parser.add_argument("-x", "--port", required=True)
20args = parser.parse_args()
21
22busctl = "sshpass -p {} busctl -H {}@{} ".format(
23    args.password, args.username, args.address
24)
25AVATAR_URL = "https://avatars1.githubusercontent.com/u/13670043?s=200&v=4"
26header = f'<head><link rel="icon" href="{AVATAR_URL}" /></head>'
27
28
29def getBusNames():
30    out = subprocess.check_output(busctl + "list --acquired", shell=True)
31    out = out.split(b"\n")
32    out = out[1:]
33    names = []
34    for line in out:
35        name = line.split(b" ")[0]
36        if name:
37            names.append(name.decode())
38    return names
39
40
41def doTree(busname):
42    out = subprocess.check_output(busctl + "tree " + busname, shell=True)
43    out = out.split(b"\n")
44    tree = []
45    for line in out:
46        path = line.split(b"/", 1)[-1].decode()
47        path = "/" + path
48        tree.append(path)
49    return tree
50
51
52def doIntrospect(busname, path):
53    out = subprocess.check_output(
54        busctl + "introspect {} {}".format(busname, path), shell=True
55    )
56    return out.decode().split("\n")
57
58
59@app.route("/")
60def root():
61    out = header
62    out += "<div><H2>Bus Names {}</H2></div>".format(args.address)
63    for name in getBusNames():
64        out += "<div> "
65        out += '<a href="{}"> {} </a>'.format(name, name)
66        out += "</div>"
67    return out
68
69
70@app.route("/favicon.ico")
71def favicon():
72    return f'<link rel="icon" type="image/png" href="{AVATAR_URL}" />'
73
74
75@app.route("/<name>")
76def busname(name):
77    out = header
78    out += "<div><H2>tree {}</H2></div>".format(name)
79    for path in doTree(name):
80        out += "<div> "
81        out += '<a href="{}/{}"> {} </a>'.format(
82            name, path.replace("/", REPLACE_CHAR), path
83        )
84        out += "</div>"
85    return out
86
87
88@app.route("/<name>/<path>")
89def path(name, path):
90    path = path.replace(REPLACE_CHAR, "/")
91    out = header
92    out += "<div><H2>introspect {} {}</H2></div>".format(name, path)
93    for line in doIntrospect(name, path):
94        out += "<div> "
95        out += "<pre> {} </pre>".format(line)
96        out += "</div>"
97    return out
98
99
100app.run(port=args.port, host="0.0.0.0")
101