Skip to main content

macos/obnote

1#!/usr/bin/env python3
2"""
3Print the path to the Markdown file which is currently open
4in Obsidian (if any).
6This relies on knowing the on-disk locations of my Obsidian vaults,
7so you won't be able to use this without changing it for your own setup.
9Note: this will print the *first* file with the same name as your
10open note, which may cause issues if you have multiple notes with
11the same title.
12"""
14import os
15import subprocess
18def get_file_paths_under(root=".", *, suffix=""):
19 """
20 Generates the absolute paths to every matching file under ``root``.
21 """
22 if not os.path.isdir(root):
23 raise ValueError(f"Cannot find files under non-existent directory: {root!r}")
25 for dirpath, _, filenames in os.walk(root):
26 for f in filenames:
27 p = os.path.join(dirpath, f)
29 if os.path.isfile(p) and f.lower().endswith(suffix):
30 yield p
33def get_applescript_output(script):
34 """
35 Run an AppleScript command and return the output.
36 """
37 cmd = ["osascript", "-e", script]
39 return subprocess.check_output(cmd).strip().decode("utf8")
42if __name__ == "__main__":
43 window_title = get_applescript_output("""
44 tell application "System Events"
45 tell process "Obsidian" to get title of front window
46 end tell
47 """)
49 # The window title will be something of the form:
50 #
51 # Short story ideas - textfiles - Obsidian v1.4.16
52 #
53 note_title, vault_name, _ = window_title.rsplit(" - ", 2)
55 # Match the vault name to a path on disk.
56 #
57 # This is very specific to my setup, so if you want to use it on
58 # your computer, you'll need to customise this bit.
59 if vault_name == "textfiles":
60 vault_root = os.path.join(os.environ["HOME"], "textfiles")
61 else:
62 raise ValueError(f"Unrecognised vault name: {vault_name}")
64 # Find Markdown files that match the name of this note.
65 for path in get_file_paths_under(vault_root, suffix=".md"):
66 expected = f"{note_title}.md".replace('📗 ', '📗 ')
68 if os.path.basename(path) == expected:
69 print(path, end="")
70 break
71 else: # no break
72 raise RuntimeError(f"Could not find note with title {note_title}")