diff --git a/scripts/gen-centered-graph.py b/scripts/gen-centered-graph.py new file mode 100644 index 0000000..ef4ff18 --- /dev/null +++ b/scripts/gen-centered-graph.py @@ -0,0 +1,125 @@ +import requests +import sys + +url = 'http://localhost:8000/notes/graph.json' +reference_node = sys.argv[1] +out = sys.argv[2] + +g = requests.get(url).json() +centered_graph = { reference_node: g[reference_node] } +del g[reference_node] +new_nodes = True + +in_emacs_tree = { + reference_node: set(), +} + +while new_nodes: + new_nodes = False + removed = set() + for k, v in g.items(): + for link in v["links"]: + if link["target"].startswith("id:"): + link["target"] = link["target"][3:] + if link['target'] in centered_graph and link.get('relation') == 'in': + centered_graph[k] = v + + for l in v["links"]: + if l.get('relation') == 'in': + t = l['target'] + if t.startswith("id:"): + t = t[3:] + + if '[' in t: + # Special case, to be handled on org_rw + continue + + if t not in in_emacs_tree: + in_emacs_tree[t] = set() + in_emacs_tree[t].add(k) + + v['links'] = [ + l for l in v["links"] + if l.get('relation') != 'in' + ] + + + removed.add(k) + new_nodes = True + break + for k in removed: + del g[k] + +in_emacs = set(centered_graph.keys()) + + +# One more round for the rest, not requiring "in" +for k, v in g.items(): + for link in v["links"]: + if link["target"].startswith("id:"): + link["target"] = link["target"][3:] + if link['target'] in in_emacs: + centered_graph[k] = v + removed.add(k) + +g = centered_graph + +f = open('graph.dot', 'wt') +f.write('digraph {\n') +# f.write('bgcolor="#222222"\n') +# f.write('fontcolor="#ffffff"\n') +f.write('maxiter=1000\n') +f.write('splines=curved\n') +# f.write('splines=spline\n') # Not supported with edges to cluster +f.write('node[shape=rect]\n') +# f.write('edge[color="#ffffff"]\n') + +def draw_subgraph(node_id): + f.write("subgraph cluster_{} {{\n".format(node_id.replace("-", "_"))) + f.write('URL="./{}.node.html"\n'.format(node_id)) + # f.write('color="#ffffff"\n') + + f.write("label=\"{}\"\n".format(g[node_id]['title'].replace("\"", "'"))) + f.write("\n") + + # print("T: {}".format(in_emacs_tree), file=sys.stderr) + for k in in_emacs_tree[node_id]: + v = g[k] + print("_" + k.replace("-", "_") + "[label=\"" + v["title"].replace("\"", "'") + "\", URL=\"" + k + ".node.html\"];", file=f) + + if k in in_emacs_tree: + draw_subgraph(k) + + f.write("\n}") + +draw_subgraph(reference_node) + +for k, v in g.items(): + if k not in in_emacs: + print("_" + k.replace("-", "_") + "[label=\"" + v["title"].replace("\"", "'") + "\", URL=\"" + k + ".node.html\"];", file=f) + +for k, v in g.items(): + for link in v["links"]: + if link["target"].startswith("id:"): + link["target"] = link["target"][3:] + + if '[' in link['target']: + # Special case, to be handled on org_rw + continue + if link['target'] not in g: + # Irrelevant + continue + if link['target'] in in_emacs_tree: + t = 'cluster_{}'.format(link['target'].replace("-", "_")) + else: + t = "_" + link["target"].replace("-", "_") + print("_" + k.replace("-", "_") + "->" + t, file=f) + +f.write('}\n') +# dot graph.dot -Tsvg graph.svg + +f.close() + +import subprocess +subprocess.call("fdp graph.dot -Tsvg -o '{}'".format(out), shell=True) +# return "graph.svg" diff --git a/scripts/generate.py b/scripts/generate.py index 7c28db6..b818a9a 100644 --- a/scripts/generate.py +++ b/scripts/generate.py @@ -336,6 +336,7 @@ def regen_all(src_top, dest_top, *, docs=None, db=None): os.makedirs(attachments_dir, exist_ok=True) for base in base_dirs: data_dir = os.path.join(src_top, base, 'data') + logging.info("Copying attachments from: {}".format(data_dir)) if not os.path.exists(data_dir): continue for subdir in os.listdir(data_dir): @@ -706,12 +707,18 @@ def render_connections(headline_id, content, graph): if headline_id not in graph['backlinks']: return - content.append("