Skip to content

Instantly share code, notes, and snippets.

@lepinkainen
Created March 6, 2025 08:30
Show Gist options
  • Save lepinkainen/860bb43597b456f50eb4980b3218f38e to your computer and use it in GitHub Desktop.
Save lepinkainen/860bb43597b456f50eb4980b3218f38e to your computer and use it in GitHub Desktop.
Export Safari reading list to an Obsidian-flavoured markdown file
import plistlib
import os
from datetime import datetime
# Path to Safari Bookmarks file, copy it locally because macOS doesn't allow direct access
# to the file in the user's Library folder
plist_path = os.path.expanduser("./Bookmarks.plist")
# Read the plist file
try:
with open(plist_path, "rb") as fp:
plist_data = plistlib.load(fp)
except Exception as e:
print(f"Error reading file: {e}")
exit()
# Find the Reading List folder
reading_list = []
for item in plist_data.get("Children", []):
if item.get("Title") == "com.apple.ReadingList":
for child in item.get("Children", []):
title = child.get("URIDictionary", {}).get("title", "Untitled")
url = child.get("URLString", "")
reading_list_non_sync = child.get("ReadingListNonSync", {})
date_added = reading_list_non_sync.get("DateAdded", None)
preview_text = reading_list_non_sync.get("PreviewText", "")
preview = preview_text.strip() if preview_text else "No preview available"
if url:
reading_list.append(
{
"title": title,
"url": url,
"date_added": date_added,
"preview": preview,
}
)
if not reading_list:
print("Reading List is empty or not found.")
exit()
# Write to Markdown
with open("reading_list.md", "w") as md_file:
# YAML front matter
md_file.write("---\n")
md_file.write("title: Safari Reading List\n")
md_file.write("tags: [reading-list, imported]\n")
md_file.write(f"date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
md_file.write("---\n\n")
# Header
md_file.write("# Safari Reading List\n\n")
# Entries
for entry in reading_list:
md_file.write(f"## [{entry['title']}]({entry['url']})\n")
if entry["date_added"]:
date_str = entry["date_added"].strftime("%B %d, %Y")
md_file.write(f"- **Added**: {date_str}\n")
else:
md_file.write("- **Added**: Unknown\n")
# Only write the preview if it's not "No preview available"
if entry["preview"] != "No preview available":
md_file.write(f"- **Preview**: {entry['preview']}\n")
md_file.write("- **Status**: Unread\n")
md_file.write("- **Tags**: #reading-list #unread\n")
md_file.write("\n---\n\n")
print("Enhanced Reading List exported to reading_list.md!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment