Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support for local database #1473

Closed
wants to merge 14 commits into from
51 changes: 51 additions & 0 deletions plextraktsync/db/Database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sqlite3

from plextraktsync.factory import logging


class Database:
_uncommited = False

def __init__(self, database_path: str):
self.logger = logging.getLogger("PlexTraktSync.Database")
try:
self.filename = database_path
self._connection = sqlite3.connect(database_path)
self._cursor = self._connection.cursor()
self._cursor.execute('ANALYZE')

except sqlite3.OperationalError as e:
self.logger.error(e)
raise e

except sqlite3.DatabaseError as e:
self.logger.error(e)
raise e

@property
def cursor(self):
return self._cursor

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if self._uncommited:
self.commit()

self._connection.close()

def execute(self, query, *args):
self._uncommited = True
return self.cursor.execute(query, *args)

def commit(self):
self._connection.commit()
self._uncommited = False

def rollback(self):
self._connection.rollback()
self._uncommited = False

def has_uncommited(self):
return self._uncommited
52 changes: 52 additions & 0 deletions plextraktsync/db/SyncDatabase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from plextraktsync.db.Database import Database
from plextraktsync.db.SyncRecord import SyncRecord

if TYPE_CHECKING:
from plextraktsync.media import Media


class SyncDatabase:
table_name = "sync"
# fields:
# A. Media ID
# B. Plex timestamp watched
# C. seen on Plex sync?
# D. Trakt timestamp watched
# E. seen on Trakt sync?
# F. result
schema = """
id PRIMARY KEY,
media_id,
plex_timestamp_watched,
seen_on_plex_sync,
trakt_timestamp_watched,
seen_on_trakt_sync,
result
"""

def __init__(self, con: Database):
self.con = con
with self.con as con:
self._create_table(con)

# Initial CREATE TABLE must happen in shared connection; subsequent queries will use thread-local connections
def _create_table(self, con: Database):
con.execute(f'CREATE TABLE IF NOT EXISTS {self.table_name} ({self.schema})')

def insert(self, record: SyncRecord):
pass

def update(self, m: Media):
record = SyncRecord(
media_id=m.trakt_id,
plex_timestamp_watched=m.watched_on_plex,
seen_on_plex_sync=m.watched_on_plex,
trakt_timestamp_watched=m.watched_on_trakt,
seen_on_trakt_sync=m.watched_on_trakt,
result="",
)
print(record)
13 changes: 13 additions & 0 deletions plextraktsync/db/SyncRecord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from dataclasses import dataclass


@dataclass
class SyncRecord:
media_id: str
plex_timestamp_watched: str
seen_on_plex_sync: str
trakt_timestamp_watched: str
seen_on_trakt_sync: str
result: str

id: str = None
6 changes: 5 additions & 1 deletion plextraktsync/sync/Sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
from plextraktsync.plan.Walker import Walker
from plextraktsync.plex.PlexApi import PlexApi
from plextraktsync.trakt.TraktApi import TraktApi
from plextraktsync.db.SyncDatabase import SyncDatabase


class Sync:
logger = logging.getLogger(__name__)

def __init__(self, config: SyncConfig, plex: PlexApi, trakt: TraktApi):
def __init__(self, config: SyncConfig, plex: PlexApi, trakt: TraktApi, sync_state: SyncDatabase):
self.config = config
self.plex = plex
self.trakt = trakt
self.walker = None
self.sync_state = sync_state

@cached_property
def trakt_lists(self):
Expand All @@ -47,9 +49,11 @@ async def sync(self, walker: Walker, dry_run=False):

if self.config.need_library_walk:
async for movie in walker.find_movies():
self.sync_state.update(movie)
await pm.ahook.walk_movie(movie=movie, dry_run=dry_run)

async for episode in walker.find_episodes():
self.sync_state.update(episode)
await pm.ahook.walk_episode(episode=episode, dry_run=dry_run)

await pm.ahook.fini(walker=walker, dry_run=dry_run)
14 changes: 13 additions & 1 deletion plextraktsync/util/Factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def sync(self):
plex = self.plex_api
trakt = self.trakt_api

return Sync(self.sync_config, plex, trakt)
return Sync(self.sync_config, plex, trakt, self.sync_database)

@cached_property
def progressbar(self):
Expand Down Expand Up @@ -300,6 +300,18 @@ def sync_config(self):

return SyncConfig(self.config, self.server_config)

@cached_property
def sync_database(self):
from os.path import join

from plextraktsync.db.Database import Database
from plextraktsync.db.SyncDatabase import SyncDatabase
from plextraktsync.path import cache_dir

db_path = join(cache_dir, "sync.sqlite")

return SyncDatabase(Database(db_path))

@cached_property
def queue(self):
from plextraktsync.queue.BackgroundTask import BackgroundTask
Expand Down
Loading