Obsidian Web Editor

Edit markdown source for Obsidian page in textarea

By the way, jbang version appears to be more stable.

import streamlit as st
import json
import os

Print banner.

@st.cache_data
def print_banner():
    print("""
                                               o
                                              <|>
                                              < \\
      o__ __o               o__  __o     o__ __o/
     /v     v\\   _\\__o__   /v      |>   /v     |
    />       <\\       \\   />      //   />     / \\
    \\         /           \\o    o/     \\      \\o/
     o       o             v\\  /v __o   o      |
     <\\__ __/>              <\\/> __/>   <\\__  / \\
    """)
    return 1

print_banner()

Get the list of Obsidian recent vaults from JSON.

home_folder = os.path.expanduser('~')
obsidian_json_path = f"{home_folder}/Library/Application Support/obsidian/obsidian.json"
with open(obsidian_json_path, "r") as json_file:
    obsidian_json = json.load(json_file)

obsidian_vaults = obsidian_json.get('vaults')

# Extract the values from the dictionary and sort them based on the 'ts' key
sorted_vaults = sorted(obsidian_vaults.values(), key=lambda x: x['ts'], reverse=True)

# Extract the 'path' from each sorted entry
obsidian_folders = [vault['path'] for vault in sorted_vaults]

obsidian_names = [os.path.basename(folder) for folder in obsidian_folders]

Select Obsidian vault as note_home from the list of recent vaults.

obsidian_name = st.sidebar.selectbox(
   "Obsidian",
   obsidian_names,
)

note_home = obsidian_folders[obsidian_names.index(obsidian_name)]

Get subfolders of Obsidian folder.

all_dir_items = os.listdir(note_home)
subfolders = [item for item in all_dir_items if os.path.isdir(os.path.join(note_home, item)) and item != ".obsidian"]
subfolders.insert(0, ".")

subfolder = st.sidebar.selectbox(
   "Folder",
   subfolders,
)

note_folder = os.path.join(note_home, subfolder)

Get num_files newest files from the provided directory.

def get_newest_files(directory, num_files):
    # Check if the directory exists
    if not os.path.isdir(directory):
        raise ValueError(f"The directory {directory} does not exist.")

    # Get a list of files in the directory with their full paths and modification times
    files_with_paths = []
    for file_name in os.listdir(directory):
        file_path = os.path.join(directory, file_name)
        if os.path.isfile(file_path):
            files_with_paths.append((file_path, os.path.getmtime(file_path)))

    # Sort files by modification time in descending order (newest first)
    sorted_files = sorted(files_with_paths, key=lambda x: x[1], reverse=True)

    # Extract the num_files newest file names
    newest_files = [os.path.basename(file_with_path[0]) for file_with_path in sorted_files[:num_files]]

    return newest_files

Select note_name from 5 newest notes

newest_files = get_newest_files(note_folder, 5)
note_name = st.sidebar.selectbox(
   "Page",
   newest_files,
)

Read the contents of Obsidian page to note_text

file_path = os.path.join(note_folder, note_name)
with open(file_path, 'r', encoding='utf-8') as file:
    note_text = file.read()

Add Streamlit widgets for editing.

st.header(note_name, divider=True)

note_text = st.text_area("Note", note_text, height=400)

Save updates.

if st.button('Save'):
    with open(file_path, 'w') as file:
        file.write(note_text)

    st.write(f'Page saved: `{note_name}`')