Compare commits
3 Commits
main
...
initial_de
| Author | SHA1 | Date | |
|---|---|---|---|
| e34bf9c12a | |||
| 3c8cf0e810 | |||
| 65846c2e06 |
@@ -1,3 +1,3 @@
|
|||||||
# Bookmark-Sync
|
# Bookmark Sync
|
||||||
|
|
||||||
This Python module synchronizes the bookmarks between various browsers.
|
This Python module snychronizes the bookmarks between various browsers.
|
||||||
|
|||||||
87
bookmark_sync/__init__.py
Normal file
87
bookmark_sync/__init__.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class BookmarkElement(ABC):
|
||||||
|
def __init__(self,data):
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def children(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def name(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def parent(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def date_added(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def position(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Bookmark(BookmarkElement):
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def address(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def children(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
class Folder(BookmarkElement):
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def date_modified(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def is_root(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def is_toolbar(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Bookmarks(ABC):
|
||||||
|
def __init__(self, profile_name="default"):
|
||||||
|
self.profile = profile_name
|
||||||
|
self.read_data()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def read_data(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def folders(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def bookmarks(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def root_folder(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def toolbar_folder(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def other_bookmarks(self):
|
||||||
|
pass
|
||||||
63
bookmark_sync/firefox_bookmarks.py
Normal file
63
bookmark_sync/firefox_bookmarks.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
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")
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user