""" Folder suggestion: plain token overlap between the text you've typed (filename, topic, subtopic — whatever's available) and each candidate destination folder's path segments. Deliberately simple and inspectable rather than clever — no ML, nothing that runs over the network, and you can always see exactly why a folder was suggested (shared words) rather than trusting a black box. If the suggestions turn out too weak once you try it on real files, the obvious next upgrade is peeking at file content for .md/.txt files — but that's worth trying this simple version against real data first. """ import re from pathlib import Path from typing import List from .sanitiser import UMLAUT_MAP def _tokens(text: str) -> set: """Split on ANY run of non-alphanumeric characters (underscore, hyphen, space, ...) — folder names use underscores (04_ARBEIT), typed text uses spaces, so the tokeniser has to treat both as word boundaries. This is deliberately more lenient than sanitise(), which is for building the final filename, not for comparing words.""" folded = text.lower() for src, repl in UMLAUT_MAP.items(): folded = folded.replace(src, repl) return {t for t in re.split(r"[^a-z0-9]+", folded) if len(t) > 2} def suggest_folders(query_text: str, all_folders: List[str], top_n: int = 5) -> List[str]: """Rank candidate folders by shared tokens with query_text. Returns [] if query_text has no usable tokens — never guesses blind.""" query_tokens = _tokens(query_text) if not query_tokens: return [] scored = [] for folder in all_folders: folder_tokens = set() for segment in Path(folder).parts: folder_tokens |= _tokens(segment) overlap = len(query_tokens & folder_tokens) if overlap: scored.append((overlap, folder)) scored.sort(key=lambda pair: (-pair[0], pair[1])) return [folder for _, folder in scored[:top_n]]