diff options
| -rwxr-xr-x | fanfictioner | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/fanfictioner b/fanfictioner index 8a4f164..72c2e85 100755 --- a/fanfictioner +++ b/fanfictioner @@ -416,6 +416,15 @@ def log(msg): f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {msg}\n") +def notify(body): + """Desktop notification via kitty (OSC 99). One fixed id, so each replaces the last instead of + stacking; shown only while the terminal is unfocused.""" + if sys.stdout.isatty(): + body = re.sub(r"[\x00-\x1f\x7f]", " ", body) + print(f"\x1b]99;i=fanfictioner:d=0:o=unfocused;fanfictioner\x1b\\" + f"\x1b]99;i=fanfictioner:d=1:p=body;{body}\x1b\\", end="", flush=True) + + def editor(path): subprocess.run([*shlex.split(os.environ.get("EDITOR") or "vi"), str(path)]) @@ -476,6 +485,7 @@ def review(d, profile, prompt, size, refs=(), skip=False): log(f"{stage} {profile} seed {seed}" + (f" FAILED: {err}" if err else "")) if not err: show(files, seed, d) + notify(f"{stage}: " + ("sd-cli failed" if err else "candidates ready, pick one")) while True: try: k = input(f"[{keys}] > ").strip().lower() @@ -571,6 +581,7 @@ def plan_stage(story, wd): meta, body = parse_front(story.read_text()) if md_path.exists() and (seen.read_text() != body if seen.exists() else story.stat().st_mtime > md_path.stat().st_mtime): + notify("story changed, plan needs a decision") try: k = input("\nstory changed since plan.md was drafted: " "[r]evise plan with Gemma [n]ew draft [k]eep plan [q]uit > ").strip().lower() @@ -611,6 +622,7 @@ def plan_stage(story, wd): print(f"\n{md}\n--- {md_path}: {len(plan['characters'])} characters, {len(plan['pages'])} pages") for e in errs: print(" !", e) + notify("plan ready for review") try: k = input("[c]onfirm [e]dit [g]emma revise [q]uit > ").strip().lower() except EOFError: @@ -886,6 +898,7 @@ def main(): page_stage(p, wd, page_path(lib, pj, p["n"]), a.base) log("done") print(f"\ndone: {page_path(lib, pj, 1).parent}") + notify("book done") except (KeyboardInterrupt, EOFError): log("interrupted") sys.exit("\ninterrupted, run again to resume") |
