Skip to main content

Actually I do want Python here, don’t I

ID
096518c
date
2023-12-28 09:58:46+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
7d88780
message
Actually I do want Python here, don't I
changed files
1 file, 66 additions, 48 deletions

Changed files

macos/obnote (1097) → macos/obnote (1962)

diff --git a/macos/obnote b/macos/obnote
index 35cad47..5e134fd 100755
--- a/macos/obnote
+++ b/macos/obnote
@@ -1,48 +1,66 @@
-#!/usr/bin/env bash
-# Prints the path to the note I currently have open in Obsidian (if any).
-#
-# This relies on knowing the on-disk locations of my Obsidian vaults,
-# so you won't be able to use this without changing it for your own setup.
-# Add the path to your vaults in the `case` statement below.
-
-set -o errexit
-set -o nounset
-
-window_title=$(osascript -e '
-  tell application "System Events"
-      tell process "Obsidian" to get title of front window
-  end tell
-')
-
-# The window title will be a three part string of the form
-#
-#     Note title - Vault name - Obsidian vX.Y.Z
-#
-# For example:
-#
-#     Short story ideas - textfiles - Obsidian v1.4.16
-#
-note_title=$(echo "$window_title" \
-  | rev \
-  | cut -d '-' -f 3- \
-  | rev \
-  | sed 's/[[:space:]]*$//')
-
-vault_name=$(echo "$window_title" \
-  | rev \
-  | cut -d'-' -f 2 \
-  | rev \
-  | sed 's/^[[:space:]]*//' \
-  | sed 's/[[:space:]]*$//')
-
-case "$vault_name" in
-  "textfiles")
-    vault_root=~/textfiles
-    ;;
-  *)
-    echo "Unknown vault name" >&2
-    exit 1
-    ;;
-esac
-
-find "$vault_root" -name "$note_title*" -print | head -n 1
+#!/usr/bin/env python3
+"""
+Prints the path to the note I currently have open in Obsidian (if any).
+
+This relies on knowing the on-disk locations of my Obsidian vaults,
+so you won't be able to use this without changing it for your own setup.
+"""
+
+import os
+import subprocess
+
+
+def get_file_paths_under(root=".", *, suffix=""):
+    """
+    Generates the absolute paths to every matching file under ``root``.
+    """
+    if not os.path.isdir(root):
+        raise ValueError(f"Cannot find files under non-existent directory: {root!r}")
+
+    for dirpath, _, filenames in os.walk(root):
+        for f in filenames:
+            p = os.path.join(dirpath, f)
+
+            if os.path.isfile(p) and f.lower().endswith(suffix):
+                yield p
+
+
+def get_applescript_output(script):
+    """
+    Run an AppleScript command and return the output.
+    """
+    cmd = ["osascript", "-e", script]
+
+    return subprocess.check_output(cmd)
+        .strip()
+        .decode("utf8")
+
+
+if __name__ == "__main__":
+    window_title = get_applescript_output("""
+        tell application "System Events"
+            tell process "Obsidian" to get title of front window
+        end tell
+    """)
+
+    # The window title will be something of the form:
+    #
+    #     Short story ideas - textfiles - Obsidian v1.4.16
+    #
+    note_title, vault_name, _ = window_title.rsplit(" - ", 2)
+
+    # Match the vault name to a path on disk.
+    #
+    # This is very specific to my setp
+    if vault_name == "textfiles":
+        vault_root = os.path.join(os.environ["HOME"], "textfiles")
+    else:
+        raise ValueError(f"Unrecognised vault name: {vault_name}")
+
+    # Find Markdown files that match the name of this note.
+    for path in get_file_paths_under(vault_root, suffix=".md"):
+        if os.path.basename(path) == f"{note_title}.md":
+            print(path, end="")
+            break
+    else:  # no break
+        raise RuntimeError(f"Could not find note with title {note_title}")