dotfiles/scripts/query-bookmarks

88 lines
2.6 KiB
Python
Executable file

#!/usr/bin/env python3
# helper script for query-bookmarks.sh
# currently supports only Firefox
# folder support would be nice, though I doubt it is really useful
# useful links:
# http://kb.mozillazine.org/Profiles.ini_file
# https://stackoverflow.com/a/740183/12005228
# https://wiki.mozilla.org/Places:BookmarksComments
import sys
import os
from pathlib import Path
from configparser import ConfigParser
import tempfile
import shutil
import sqlite3
sys.path.insert(
1, os.path.join(os.path.dirname(os.path.dirname(__file__)), "script-resources")
)
import common_script_utils # noqa F401
if sys.platform == "darwin":
firefox_home = Path.home() / "Library" / "Application Support" / "Firefox"
elif os.name == "posix":
firefox_home = Path.home() / ".mozilla" / "firefox"
else:
common_script_utils.platform_not_supported_error()
profiles_config = ConfigParser(interpolation=None)
profiles_config.read(firefox_home / "profiles.ini")
installs_sections = [s for s in profiles_config.sections() if s.startswith("Install")]
if not installs_sections:
raise Exception("no Firefox installations detected!")
if len(installs_sections) > 1:
raise Exception("multiple Firefox installations are not supported!")
profile_dir = firefox_home / profiles_config.get(installs_sections[0], "Default")
db_path = profile_dir / "weave" / "bookmarks.sqlite"
if not db_path.is_file():
raise Exception("'{}' is not a file".format(db_path))
# Firefox holds a lock over the database file, so I can't connect to it even
# in the readonly mode: https://stackoverflow.com/a/7857866/12005228
# as a workaround I copy the file
db_copy_fd, db_copy_path = tempfile.mkstemp(prefix="bookmarks.", suffix=".sqlite")
os.close(db_copy_fd)
chooser_entries = []
try:
shutil.copyfile(db_path, db_copy_path)
db = sqlite3.connect(db_copy_path)
urls = {}
for urlId, url in db.execute("SELECT id, url FROM urls"):
urls[urlId] = url
for title, urlId, keyword in db.execute(
"SELECT title, urlId, keyword FROM items WHERE kind = 1 AND validity AND NOT isDeleted"
):
url = urls[urlId]
chooser_entries.append((title, url))
if keyword is not None:
chooser_entries.append((keyword, url))
finally:
os.remove(db_copy_path)
chosen_index = common_script_utils.run_chooser(
("{} \u2014\u2014 {}".format(title, url) for title, url in chooser_entries),
prompt="bookmark",
)
_title, url = chooser_entries[chosen_index]
print(url)
common_script_utils.set_clipboard(url)
common_script_utils.send_notification(
os.path.basename(__file__), "bookmark URL copied to clipboard!", url
)