graphic pactree

from pacvis javascript library (/pacgraph) a little script for display pactree in same pacvis graph

pacman:
acapture_20200715_182039.pactree
little package as systemd :sweat_smile: :
acapture_20200715_182316.pactree-systemd

pactree-g code:

#!/usr/bin/env python
import sys
from pathlib import Path
import subprocess
from dataclasses import dataclass
import webbrowser

COLOR_REVERSE = '#eebb44'
COLOR_PACKAGE = '#7BE141'

@dataclass
class Package:
    item: int
    label: str
    value: int
    color: str

def get_weight(pkgname) ->int:
    proc = subprocess.run(["pactree", pkgname, "-rld1"], capture_output=True, text=True)
    return len(proc.stdout.split("\n")) -2

def set_reverse(pkgname, pkgs, links):
    proc = subprocess.run(["pactree", pkgname, "-ulr"], capture_output=True, text=True)
    ls = proc.stdout.split("\n")
    print(ls)
    try:
        ls.remove(pkgname)
    except ValueError:
        print("package not installed")
        exit(2)
    mainid = get_id(pkgs, pkgname)
    pkgs[mainid].value = len(ls)
    for pkg in ls:
        if not pkg:
            continue
        weight = get_weight(pkg)
        i = len(pkgs)+2
        pkgs.append(Package(i, pkg, weight, COLOR_REVERSE))
        links.append((i, mainid))
    return pkgs, links


def print_pkgs(pkgs):
    result = "nodes = ["
    for pkg in pkgs:
        color = f",color:'{pkg.color}'" if pkg.color else ''
        result = f"{result}{{id:{pkg.item},value:{pkg.value},label:'{pkg.label}'{color}}},"
    result = f"{result} ];"
    return result

def print_links(links, pkgname):
    mainid = get_id(pkgs, pkgname)
    result = "edges = ["
    for link in links:
        color = f",color:'{COLOR_REVERSE}',arrows:'from'" if link[1] == mainid else ''
        result = f"{result}{{from:{link[0]},to:{link[1]}{color}}},"
    result = f"{result} ];"
    return result

def get_id(pkgs, pkgname):
    for pkg in pkgs:
        if pkg.label == pkgname:
            return pkg.item
    return 0


if len(sys.argv) < 2:
    print("package name not found")
    exit(1)

template = r'''<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{title}}</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-network.min.js"></script>
  </head>
  <body><div id="mynetwork" style="with:99%; height:99vh;"></div></body>
  <script>
    var nodes = null; var edges = null; var network = null;
    function draw() {
      {{nodes}}
      {{edges}}
      var container = document.getElementById("mynetwork");
      var data = { nodes: nodes, edges: edges };
      var options = {
        nodes: {
          shape: "dot",
          scaling: {
            customScalingFunction: function (min,max,total,value) { return value/total; },
            min:5,
            max:120
          }
        },
        physics: {
            enabled: true,
            timestep: 0.3,
            minVelocity: 0.5,
            solver: "barnesHut",
        }        
      };
      network = new vis.Network(container, data, options);
    }
    window.addEventListener("load", () => {  draw(); });
  </script>
</html>
'''

main_package = sys.argv[1].lower()

proc = subprocess.run(["pactree", main_package, "-ul"], capture_output=True, text=True)
#print(proc.stdout)
pkgs = []
for i, pkg in enumerate((p for p in proc.stdout.split("\n") if p)):
    weight = get_weight(pkg)
    color = COLOR_PACKAGE if main_package == pkg else ''
    pkgs.append(Package(i, pkg, weight, color))


links = []
for pkg in pkgs:
    proc = subprocess.run(["pactree", pkg.label, "-uld1"], capture_output=True, text=True)
    ls = proc.stdout.split("\n")
    ls.remove(pkg.label)
    if len(ls) < 1:
        continue
    for subpkg in ls:
        subid = get_id(pkgs, subpkg)
        if subid > 0:
            a, b = pkg.item, subid
            if a > b:
                a, b = b, a
            links.append((a, b))

pkgs, links = set_reverse(main_package, pkgs, links)

template = template.replace('{{title}}', main_package, 1)
template = template.replace('{{nodes}}', print_pkgs(pkgs), 1)
template = template.replace('{{edges}}', print_links(links, main_package), 1)
Path("/tmp/pacman-graph.html").write_text(template)
webbrowser.open_new_tab("/tmp/pacman-graph.html")
#print(template)
4 Likes

Very nice! :smiley:

Forum kindly sponsored by