def get_zk_base_dirs_from_env() -> List[Path]: if "ZK_HOME" in os.environ: paths = [ Path(path_str) for path_str in shlex.split(os.environ["ZK_HOME"]) ] existing_paths = [] for path in paths: if not path.is_dir(): logger.warning( f"Path '{path}' from ZK_HOME environment variable doesn't" f"exist. Ignoring it.") else: existing_paths.append(path) return existing_paths
def guess_zk_dir(inpt: Union[str, PurePath]) -> Optional[Path]: if Path(inpt).is_dir(): return Path(inpt).resolve() else: dirs = get_zk_base_dirs_from_env() results = [d for d in dirs if inpt in str(d)] if len(results) == 0: logger.warning("Could not guess right zk directory.") return None elif len(results) == 1: logger.debug(f"Guessed zk directory from search term {inpt} to be " f"{results[0]}.") return Path(results[0]) else: logger.warning("Too many results for zk directory.") return None
def add_id(path: PurePath) -> PurePath: zid = get_id(path.name) if zid == "none": zid = generate_zid() if path.name.endswith(".md"): name = path.name[:-3] + zid + ".md" else: name = path.name + zid + ".md" return path.parent / name elif zid == "many": logger.critical( f"Already found MULTIPLE ids in {path}. " f"Leaving unchanged" ) return path else: logger.warning(f"Already found ID in {path}. " f"Leaving unchanged.")
def _analyze_file(self) -> None: """ Should be called only once! """ md_reader = MarkdownReader.from_file(self.path) for md_line in md_reader.lines: if len(md_line.current_section) == 1: if self.title and self.title != md_line.current_section[0]: logger.warning(f"{self.path} Warning: Multiple titles. ") self.title = md_line.current_section[0] if not md_line.is_code_block and md_line.text.lower().strip( ).startswith("tags: "): if self.tags: logger.warning( f"{self.path} Warning: Tags were already set.") self.tags = self._read_tags(md_line.text) if (len(md_line.current_section) >= 2 and md_line.current_section[1].lower().strip() == "backlinks"): pass else: self.links.extend(self.id_link_regex.findall(md_line.text))
def dotgraph_html(zk, note: Note): # nbd = self.zk.get_notes_by_depth(root=note.nid) # maxdepth = min(2, len(nbd)) categories = collections.defaultdict(set) selected_nodes = {note.nid} # self.zk._graph.get_k_neighbors(note.nid) categories["self"].add(note.nid) try: # selected_nodes |= set(nx.dijkstra_path(zk._graph, zk.root, note.nid)) paths_from_root = set() for connection in nx.all_simple_paths(zk._graph, zk.root, note.nid): paths_from_root |= set(connection) categories["rootpath"] |= paths_from_root selected_nodes |= paths_from_root except nx.exception.NetworkXNoPath: logger.warning(f"No path from {zk.root} to {note.nid}") predecessors = set(zk._graph.predecessors(note.nid)) categories["predecessors"] |= predecessors selected_nodes |= predecessors descendants = set( nx.descendants_at_distance(zk._graph, note.nid, distance=1)) categories["descendants"] |= descendants selected_nodes |= descendants optional_nodes = set() for dist in range(2, 3): desc = set( nx.descendants_at_distance(zk._graph, note.nid, distance=dist)) categories["descendants"] |= desc optional_nodes |= desc for predecessor in zk._graph.predecessors(note.nid): sibl = set(zk._graph.successors(predecessor)) categories["siblings"] |= sibl optional_nodes |= sibl optional_nodes -= selected_nodes if len(selected_nodes) < 30: selected_nodes |= set( random.choices( list(optional_nodes), k=min(len(optional_nodes), 30 - len(selected_nodes)), )) def pick_color(note: Note): nid = note.nid if nid in categories["self"]: # red return "#fb8072" elif nid in categories["predecessors"]: # green return "#ccebc5" elif nid in categories["descendants"]: # yellow return "#ffed6f" elif nid in categories["siblings"]: # pink return "#fccde5" elif nid in categories["rootpath"]: # grayish return "#d9d9d9" else: return "red" out_lines = [] if len(selected_nodes) < 50: out_lines.append( '<script src="/static/js/vis-network.min.js"></script>\n') dgg = DotGraphGenerator(zk=zk) dgg.get_color = pick_color dotstr = dgg.graph_from_notes(selected_nodes) out_lines.append( _dotgraph_html.replace("{dotgraph}", dotstr).replace( "{height}", f"{400 + 20*len(selected_nodes)}px")) return out_lines