Files
Bookmark-Sync/bookmark_sync/firefox_bookmarks.py

64 lines
2.4 KiB
Python

from platform import system
from pathlib import Path
from more_itertools import only
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine, MetaData
from . import Bookmarks, Bookmark, Folder
class FirefoxBookmarks(Bookmarks):
_locations = {
"Windows": Path.home()/"AppData/Roaming/Mozilla/Firefox/Profiles",
"Linux": Path.home()/".mozilla/firefox",
"Darwin": Path.home()/"Library/Application Support/Firefox/Profiles"
}
def read_data(self):
try:
self.bookmarks_file = only(self._locations[system()].glob(
"*.default-release"))/"places.sqlite"
except KeyError:
# Assume everthing that isn't Windows or MacOS works like Linux
self.bookmarks_file = only(self._locations["Linux"].glob(
"*.default-release"))/"places.sqlite"
if not self.bookmarks_file.exists():
raise RuntimeError(
"Firefox profile cannot be found or does not exist")
else:
self._engine = create_engine(f"sqlite:///{self.bookmarks_file}")
self._base = automap_base()
self._base.metadata = MetaData(bind=self._engine)
self._base.prepare(self._engine, reflect=True,
classname_for_table=lambda base, name, table: name.replace("moz_", ""))
self._session = Session(self._engine)
@property
def _all_elements(self):
return (self._session.query(self._base.classes.bookmarks, self._base.classes.places)
.outerjoin(self._base.classes.places, self._base.classes.bookmarks.fk == self._base.classes.places.id)
.order_by(self._base.classes.moz_bookmarks.parent, self._base.classes.moz_bookmarks.position)
)
@property
def folders(self):
return self._all_elements.filter(self._base.classes.bookmarks.type == 2)
@property
def bookmarks(self):
return self._all_elements.filter(self._base.classes.bookmarks.type == 1)
@property
def root_folder(self):
return only(self.folders.filter(self._base.classes.bookmarks.id == 1))
@property
def toolbar_folder(self):
return only(self.folders
.filter(self._base.classes.bookmarks.id < 7)
.filter(self._base.classes.bookmarks.title == "toolbar")
)