Skip to content

Commit

Permalink
Merge pull request #1378 from glensc/move-class
Browse files Browse the repository at this point in the history
  • Loading branch information
glensc authored Jan 18, 2023
2 parents 58172ef + 7118353 commit 0256a85
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 163 deletions.
5 changes: 3 additions & 2 deletions plextraktsync/commands/watch.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import annotations

from plextraktsync.events import (ActivityNotification, Error,
PlaySessionStateNotification, TimelineEntry)
from plextraktsync.factory import factory
from plextraktsync.watch.events import (ActivityNotification, Error,
PlaySessionStateNotification,
TimelineEntry)


def watch(server: str):
Expand Down
2 changes: 1 addition & 1 deletion plextraktsync/config/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def http_cache(self):

@property
def sync(self):
from plextraktsync.sync import SyncConfig
from plextraktsync.config.SyncConfig import SyncConfig

return SyncConfig(self)

Expand Down
87 changes: 87 additions & 0 deletions plextraktsync/config/SyncConfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from plextraktsync.decorators.cached_property import cached_property

if TYPE_CHECKING:
from plextraktsync.config.Config import Config


class SyncConfig:
def __init__(self, config: Config):
self.config = dict(config["sync"])

def __getitem__(self, key):
return self.config[key]

def __contains__(self, key):
return key in self.config

def get(self, section, key):
return self[key] if key in self else self[section][key]

@cached_property
def trakt_to_plex(self):
return {
"watched_status": self.get("trakt_to_plex", "watched_status"),
"ratings": self.get("trakt_to_plex", "ratings"),
"liked_lists": self.get("trakt_to_plex", "liked_lists"),
"watchlist": self.get("trakt_to_plex", "watchlist"),
"watchlist_as_playlist": self.get("trakt_to_plex", "watchlist_as_playlist"),
}

@cached_property
def plex_to_trakt(self):
return {
"watched_status": self.get("plex_to_trakt", "watched_status"),
"ratings": self.get("plex_to_trakt", "ratings"),
"collection": self.get("plex_to_trakt", "collection"),
"watchlist": self.get("plex_to_trakt", "watchlist"),
}

@cached_property
def sync_ratings(self):
return self.trakt_to_plex["ratings"] or self.plex_to_trakt["ratings"]

@cached_property
def sync_watchlists(self):
return self.trakt_to_plex["watchlist"] or self.plex_to_trakt["watchlist"]

@cached_property
def clear_collected(self):
return self.plex_to_trakt["collection"] and self["plex_to_trakt"]["clear_collected"]

@cached_property
def sync_watched_status(self):
return self.trakt_to_plex["watched_status"] or self.plex_to_trakt["watched_status"]

@cached_property
def update_plex_wl(self):
return self.trakt_to_plex["watchlist"] and not self.trakt_to_plex["watchlist_as_playlist"]

@cached_property
def update_plex_wl_as_pl(self):
return self.trakt_to_plex["watchlist"] and self.trakt_to_plex["watchlist_as_playlist"]

@cached_property
def update_trakt_wl(self):
return self.plex_to_trakt["watchlist"]

@cached_property
def sync_wl(self):
return self.update_plex_wl or self.update_trakt_wl

@cached_property
def sync_liked_lists(self):
return self.trakt_to_plex["liked_lists"]

@cached_property
def need_library_walk(self):
return any([
self.update_plex_wl_as_pl,
self.sync_watched_status,
self.sync_ratings,
self.plex_to_trakt["collection"],
self.sync_liked_lists,
])
2 changes: 1 addition & 1 deletion plextraktsync/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def enable_self_update(self):

@cached_property
def web_socket_listener(self):
from plextraktsync.listener import WebSocketListener
from plextraktsync.watch.WebSocketListener import WebSocketListener

return WebSocketListener(plex=self.plex_server)

Expand Down
81 changes: 0 additions & 81 deletions plextraktsync/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,87 +18,6 @@
from plextraktsync.walker import Walker


class SyncConfig:
def __init__(self, config: Config):
self.config = dict(config["sync"])

def __getitem__(self, key):
return self.config[key]

def __contains__(self, key):
return key in self.config

def get(self, section, key):
return self[key] if key in self else self[section][key]

@cached_property
def trakt_to_plex(self):
return {
"watched_status": self.get("trakt_to_plex", "watched_status"),
"ratings": self.get("trakt_to_plex", "ratings"),
"liked_lists": self.get("trakt_to_plex", "liked_lists"),
"watchlist": self.get("trakt_to_plex", "watchlist"),
"watchlist_as_playlist": self.get("trakt_to_plex", "watchlist_as_playlist"),
}

@cached_property
def plex_to_trakt(self):
return {
"watched_status": self.get("plex_to_trakt", "watched_status"),
"ratings": self.get("plex_to_trakt", "ratings"),
"collection": self.get("plex_to_trakt", "collection"),
"watchlist": self.get("plex_to_trakt", "watchlist"),
}

@cached_property
def sync_ratings(self):
return self.trakt_to_plex["ratings"] or self.plex_to_trakt["ratings"]

@cached_property
def sync_watchlists(self):
return self.trakt_to_plex["watchlist"] or self.plex_to_trakt["watchlist"]

@cached_property
def clear_collected(self):
return self.plex_to_trakt["collection"] and self["plex_to_trakt"]["clear_collected"]

@cached_property
def sync_watched_status(self):
return (
self.trakt_to_plex["watched_status"] or self.plex_to_trakt["watched_status"]
)

@cached_property
def update_plex_wl(self):
return self.trakt_to_plex["watchlist"] and not self.trakt_to_plex["watchlist_as_playlist"]

@cached_property
def update_plex_wl_as_pl(self):
return self.trakt_to_plex["watchlist"] and self.trakt_to_plex["watchlist_as_playlist"]

@cached_property
def update_trakt_wl(self):
return self.plex_to_trakt["watchlist"]

@cached_property
def sync_wl(self):
return self.update_plex_wl or self.update_trakt_wl

@cached_property
def sync_liked_lists(self):
return self.trakt_to_plex["liked_lists"]

@cached_property
def need_library_walk(self):
return any([
self.update_plex_wl_as_pl,
self.sync_watched_status,
self.sync_ratings,
self.plex_to_trakt["collection"],
self.sync_liked_lists,
])


class Sync:
def __init__(self, config: Config, plex: PlexApi, trakt: TraktApi):
self.config = config.sync
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from time import sleep

from plexapi.server import PlexServer

from plextraktsync.events import Error, EventFactory
from plextraktsync.factory import logging
from plextraktsync.watch.EventFactory import EventFactory
from plextraktsync.watch.events import Error


class EventDispatcher:
Expand Down Expand Up @@ -67,30 +64,3 @@ def match_event(self, listener, event):
return False

return True


class WebSocketListener:
def __init__(self, plex: PlexServer, poll_interval=5, restart_interval=15):
self.plex = plex
self.poll_interval = poll_interval
self.restart_interval = restart_interval
self.dispatcher = EventDispatcher()
self.logger = logging.getLogger("PlexTraktSync.WebSocketListener")

def on(self, event_type, listener, **kwargs):
self.dispatcher.on(event_type, listener, **kwargs)

def listen(self):
self.logger.info("Listening for events!")
while True:
notifier = self.plex.startAlertListener(
callback=self.dispatcher.event_handler
)
while notifier.is_alive():
sleep(self.poll_interval)

self.dispatcher.event_handler(Error(msg="Server closed connection"))
self.logger.error(
f"Listener finished. Restarting in {self.restart_interval} seconds"
)
sleep(self.restart_interval)
39 changes: 39 additions & 0 deletions plextraktsync/watch/EventFactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import importlib


class EventFactory:
EVENTS = {
"account": "AccountUpdateNotification",
"activity": "ActivityNotification",
"backgroundProcessingQueue": "BackgroundProcessingQueueEventNotification",
"playing": "PlaySessionStateNotification",
"preference": "Setting",
"progress": "ProgressNotification",
"reachability": "ReachabilityNotification",
"status": "StatusNotification",
"timeline": "TimelineEntry",
"transcodeSession.end": "TranscodeSession",
"transcodeSession.start": "TranscodeSession",
"transcodeSession.update": "TranscodeSession",
}

def __init__(self):
self.module = importlib.import_module(self.__module__)

def get_events(self, message):
if message["size"] != 1:
raise ValueError(f"Unexpected size: {message}")

message_type = message["type"]
if message_type not in self.EVENTS:
return
class_name = self.EVENTS[message_type]
if class_name not in message:
return
for data in message[class_name]:
event = self.create(class_name, **data)
yield event

def create(self, name, **kwargs):
cls = getattr(self.module, name)
return cls(**kwargs)
5 changes: 3 additions & 2 deletions plextraktsync/watch/WatchStateUpdater.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from typing import TYPE_CHECKING

from plextraktsync.decorators.cached_property import cached_property
from plextraktsync.events import (ActivityNotification, Error,
PlaySessionStateNotification, TimelineEntry)
from plextraktsync.factory import logging
from plextraktsync.watch.events import (ActivityNotification, Error,
PlaySessionStateNotification,
TimelineEntry)

if TYPE_CHECKING:
from plextraktsync.config.Config import Config
Expand Down
38 changes: 38 additions & 0 deletions plextraktsync/watch/WebSocketListener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from __future__ import annotations

from time import sleep
from typing import TYPE_CHECKING

from plextraktsync.factory import logging
from plextraktsync.watch.EventDispatcher import EventDispatcher
from plextraktsync.watch.events import Error

if TYPE_CHECKING:
from plexapi.server import PlexServer


class WebSocketListener:
def __init__(self, plex: PlexServer, poll_interval=5, restart_interval=15):
self.plex = plex
self.poll_interval = poll_interval
self.restart_interval = restart_interval
self.dispatcher = EventDispatcher()
self.logger = logging.getLogger("PlexTraktSync.WebSocketListener")

def on(self, event_type, listener, **kwargs):
self.dispatcher.on(event_type, listener, **kwargs)

def listen(self):
self.logger.info("Listening for events!")
while True:
notifier = self.plex.startAlertListener(
callback=self.dispatcher.event_handler
)
while notifier.is_alive():
sleep(self.poll_interval)

self.dispatcher.event_handler(Error(msg="Server closed connection"))
self.logger.error(
f"Listener finished. Restarting in {self.restart_interval} seconds"
)
sleep(self.restart_interval)
41 changes: 0 additions & 41 deletions plextraktsync/events.py → plextraktsync/watch/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import importlib


class Event(dict):
def __str__(self):
return f"{self.__class__}:{str(self.copy())}"
Expand Down Expand Up @@ -92,41 +89,3 @@ def title(self):

class TranscodeSession(Event):
pass


class EventFactory:
EVENTS = {
"account": "AccountUpdateNotification",
"activity": "ActivityNotification",
"backgroundProcessingQueue": "BackgroundProcessingQueueEventNotification",
"playing": "PlaySessionStateNotification",
"preference": "Setting",
"progress": "ProgressNotification",
"reachability": "ReachabilityNotification",
"status": "StatusNotification",
"timeline": "TimelineEntry",
"transcodeSession.end": "TranscodeSession",
"transcodeSession.start": "TranscodeSession",
"transcodeSession.update": "TranscodeSession",
}

def __init__(self):
self.module = importlib.import_module(self.__module__)

def get_events(self, message):
if message["size"] != 1:
raise ValueError(f"Unexpected size: {message}")

message_type = message["type"]
if message_type not in self.EVENTS:
return
class_name = self.EVENTS[message_type]
if class_name not in message:
return
for data in message[class_name]:
event = self.create(class_name, **data)
yield event

def create(self, name, **kwargs):
cls = getattr(self.module, name)
return cls(**kwargs)
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3 -m pytest
from os.path import join

from plextraktsync.config import Config
from plextraktsync.config.Config import Config
from plextraktsync.factory import factory


Expand Down
Loading

0 comments on commit 0256a85

Please sign in to comment.