type to get to book added, chaning library binding to shift+l. Improved audiobookshelf support.
This commit is contained in:
+116
-12
@@ -67,10 +67,23 @@ class BookmarkManager:
|
||||
paragraph_index INTEGER NOT NULL DEFAULT 0,
|
||||
audio_position REAL DEFAULT 0.0,
|
||||
created_at TEXT NOT NULL,
|
||||
server_library_item_id TEXT,
|
||||
server_time INTEGER,
|
||||
server_created_at INTEGER,
|
||||
UNIQUE(book_id, name)
|
||||
)
|
||||
''')
|
||||
|
||||
for columnName, columnType in [
|
||||
('server_library_item_id', 'TEXT'),
|
||||
('server_time', 'INTEGER'),
|
||||
('server_created_at', 'INTEGER')
|
||||
]:
|
||||
try:
|
||||
cursor.execute(f'ALTER TABLE named_bookmarks ADD COLUMN {columnName} {columnType}')
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
|
||||
conn.commit()
|
||||
|
||||
def _get_book_id(self, bookPath):
|
||||
@@ -189,7 +202,8 @@ class BookmarkManager:
|
||||
|
||||
return bookmarks
|
||||
|
||||
def create_named_bookmark(self, bookPath, name, chapterIndex, paragraphIndex, audioPosition=0.0):
|
||||
def create_named_bookmark(self, bookPath, name, chapterIndex, paragraphIndex, audioPosition=0.0,
|
||||
serverLibraryItemId=None, serverTime=None, serverCreatedAt=None):
|
||||
"""
|
||||
Create a named bookmark for a book
|
||||
|
||||
@@ -201,7 +215,7 @@ class BookmarkManager:
|
||||
audioPosition: Audio position in seconds (default: 0.0)
|
||||
|
||||
Returns:
|
||||
True if created successfully, False if name already exists
|
||||
Bookmark ID if created successfully, None if name already exists
|
||||
"""
|
||||
bookId = self._get_book_id(bookPath)
|
||||
timestamp = datetime.now().isoformat()
|
||||
@@ -212,16 +226,18 @@ class BookmarkManager:
|
||||
|
||||
cursor.execute('''
|
||||
INSERT INTO named_bookmarks
|
||||
(book_id, name, chapter_index, paragraph_index, audio_position, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
''', (bookId, name, chapterIndex, paragraphIndex, audioPosition, timestamp))
|
||||
(book_id, name, chapter_index, paragraph_index, audio_position, created_at,
|
||||
server_library_item_id, server_time, server_created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', (bookId, name, chapterIndex, paragraphIndex, audioPosition, timestamp,
|
||||
serverLibraryItemId, serverTime, serverCreatedAt))
|
||||
|
||||
conn.commit()
|
||||
return True
|
||||
return cursor.lastrowid
|
||||
|
||||
except sqlite3.IntegrityError:
|
||||
# Bookmark with this name already exists
|
||||
return False
|
||||
return None
|
||||
|
||||
def get_named_bookmarks(self, bookPath):
|
||||
"""
|
||||
@@ -239,7 +255,8 @@ class BookmarkManager:
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT id, name, chapter_index, paragraph_index, audio_position, created_at
|
||||
SELECT id, name, chapter_index, paragraph_index, audio_position, created_at,
|
||||
server_library_item_id, server_time, server_created_at
|
||||
FROM named_bookmarks
|
||||
WHERE book_id = ?
|
||||
ORDER BY created_at DESC
|
||||
@@ -255,11 +272,95 @@ class BookmarkManager:
|
||||
'chapterIndex': row[2],
|
||||
'paragraphIndex': row[3],
|
||||
'audioPosition': row[4],
|
||||
'createdAt': row[5]
|
||||
'createdAt': row[5],
|
||||
'serverLibraryItemId': row[6],
|
||||
'serverTime': row[7],
|
||||
'serverCreatedAt': row[8]
|
||||
})
|
||||
|
||||
return bookmarks
|
||||
|
||||
def update_named_bookmark_server_data(self, bookmarkId, serverLibraryItemId=None, serverTime=None,
|
||||
serverCreatedAt=None):
|
||||
"""
|
||||
Update server metadata for an existing named bookmark.
|
||||
|
||||
Args:
|
||||
bookmarkId: Local bookmark ID
|
||||
serverLibraryItemId: Linked Audiobookshelf item ID
|
||||
serverTime: Server bookmark time in seconds
|
||||
serverCreatedAt: Server bookmark created timestamp
|
||||
"""
|
||||
with sqlite3.connect(self.dbPath) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('''
|
||||
UPDATE named_bookmarks
|
||||
SET server_library_item_id = ?, server_time = ?, server_created_at = ?
|
||||
WHERE id = ?
|
||||
''', (serverLibraryItemId, serverTime, serverCreatedAt, bookmarkId))
|
||||
conn.commit()
|
||||
|
||||
def upsert_named_bookmark_from_server(self, bookPath, name, chapterIndex, paragraphIndex, audioPosition=0.0,
|
||||
serverLibraryItemId=None, serverTime=None, serverCreatedAt=None):
|
||||
"""
|
||||
Insert or update a local bookmark from Audiobookshelf server data.
|
||||
|
||||
Returns:
|
||||
Local bookmark ID
|
||||
"""
|
||||
bookId = self._get_book_id(bookPath)
|
||||
timestamp = datetime.now().isoformat()
|
||||
|
||||
with sqlite3.connect(self.dbPath) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
if serverLibraryItemId and serverTime is not None:
|
||||
cursor.execute('''
|
||||
SELECT id FROM named_bookmarks
|
||||
WHERE book_id = ? AND server_library_item_id = ? AND server_time = ?
|
||||
''', (bookId, serverLibraryItemId, serverTime))
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
bookmarkId = row[0]
|
||||
cursor.execute('''
|
||||
UPDATE named_bookmarks
|
||||
SET name = ?, chapter_index = ?, paragraph_index = ?, audio_position = ?,
|
||||
"server_created_at" = ?, created_at = ?
|
||||
WHERE id = ?
|
||||
''', (name, chapterIndex, paragraphIndex, audioPosition,
|
||||
serverCreatedAt, timestamp, bookmarkId))
|
||||
conn.commit()
|
||||
return bookmarkId
|
||||
|
||||
cursor.execute('''
|
||||
INSERT OR IGNORE INTO named_bookmarks
|
||||
(book_id, name, chapter_index, paragraph_index, audio_position, created_at,
|
||||
server_library_item_id, server_time, server_created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', (bookId, name, chapterIndex, paragraphIndex, audioPosition, timestamp,
|
||||
serverLibraryItemId, serverTime, serverCreatedAt))
|
||||
|
||||
if cursor.lastrowid:
|
||||
conn.commit()
|
||||
return cursor.lastrowid
|
||||
|
||||
cursor.execute('''
|
||||
SELECT id FROM named_bookmarks
|
||||
WHERE book_id = ? AND name = ?
|
||||
''', (bookId, name))
|
||||
row = cursor.fetchone()
|
||||
bookmarkId = row[0] if row else None
|
||||
if bookmarkId:
|
||||
cursor.execute('''
|
||||
UPDATE named_bookmarks
|
||||
SET chapter_index = ?, paragraph_index = ?, audio_position = ?,
|
||||
"server_library_item_id" = ?, "server_time" = ?, "server_created_at" = ?
|
||||
WHERE id = ?
|
||||
''', (chapterIndex, paragraphIndex, audioPosition,
|
||||
serverLibraryItemId, serverTime, serverCreatedAt, bookmarkId))
|
||||
conn.commit()
|
||||
return bookmarkId
|
||||
|
||||
def delete_named_bookmark(self, bookmarkId):
|
||||
"""
|
||||
Delete a named bookmark by ID
|
||||
@@ -300,7 +401,8 @@ class BookmarkManager:
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT name, chapter_index, paragraph_index, audio_position
|
||||
SELECT name, chapter_index, paragraph_index, audio_position,
|
||||
server_library_item_id, server_time, server_created_at
|
||||
FROM named_bookmarks
|
||||
WHERE id = ?
|
||||
''', (bookmarkId,))
|
||||
@@ -312,8 +414,10 @@ class BookmarkManager:
|
||||
'name': row[0],
|
||||
'chapterIndex': row[1],
|
||||
'paragraphIndex': row[2],
|
||||
'audioPosition': row[3]
|
||||
'audioPosition': row[3],
|
||||
'serverLibraryItemId': row[4],
|
||||
'serverTime': row[5],
|
||||
'serverCreatedAt': row[6]
|
||||
}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user