def watch(): server = factory.plex_server() trakt = factory.trakt_api() plex = factory.plex_api() mf = factory.media_factory() config = factory.config() ws = WebSocketListener(server) updater = WatchStateUpdater(plex, trakt, mf, config) ws.on( PlaySessionStateNotification, updater.on_play, state=["playing", "stopped", "paused"], ) ws.on( ActivityNotification, updater.on_activity, type="library.refresh.items", event="ended", progress=100, ) ws.on(TimelineEntry, updater.on_delete, state=9, metadata_state="deleted") ws.on(Error, updater.on_error) print("Listening for events!") ws.listen()
def provider(self): if self.guid_is_imdb_legacy: return "imdb" x = self.guid.split("://")[0] x = x.replace("com.plexapp.agents.", "") x = x.replace("tv.plex.agents.", "") x = x.replace("themoviedb", "tmdb") x = x.replace("thetvdb", "tvdb") if x == "xbmcnfo": CONFIG = factory.config() x = CONFIG["xbmc-providers"][self.media_type] if x == "xbmcnfotv": CONFIG = factory.config() x = CONFIG["xbmc-providers"]["shows"] return x
def info(): """ Print application and environment version info """ print(f"PlexTraktSync Version: {get_version()}") py_version = sys.version.replace("\n", "") print(f"Python Version: {py_version}") print(f"Plex API Version: {PLEX_API_VERSION}") print(f"Trakt API Version: {TRAKT_API_VERSION}") print(f"Cache Dir: {cache_dir}") print(f"Config Dir: {config_dir}") print(f"Log Dir: {log_dir}") config = factory.config() print(f"Plex username: {config['PLEX_USERNAME']}") print(f"Trakt username: {config['TRAKT_USERNAME']}") if has_plex_token(): plex = factory.plex_api() print( f"Plex Server version: {plex.version}, updated at: {plex.updated_at}" ) print( f"Enabled {len(plex.library_sections)} libraries in Plex Server: {plex.library_section_names}" )
def login(): api = factory.trakt_api() trakt_authenticate(api) user = api.me.username CONFIG = factory.config() CONFIG["TRAKT_USERNAME"] = user CONFIG.save() click.echo(TRAKT_LOGIN_SUCCESS)
def cache(sort: str, limit: int, reverse: bool, url: str): config = factory.config() trakt_cache = config["cache"]["path"] session = CachedSession(cache_name=trakt_cache, backend="sqlite") if url: inspect_url(session, url) return click.echo(f"Cache status:\n{session.cache}\n") click.echo("URLs:") sorted = get_sorted_cache(session, sort, reverse) for i, r in limit_iterator(sorted, limit): click.echo(f"- {i + 1:3d}. {r}")
from plexapi.myplex import MyPlexAccount, MyPlexResource, ResourceConnection from plexapi.server import PlexServer from plextraktsync.factory import factory from plextraktsync.style import (comment, disabled, error, highlight, prompt, success, title) PROMPT_PLEX_PASSWORD = prompt("Please enter your Plex password") PROMPT_PLEX_USERNAME = prompt("Please enter your Plex username or e-mail") PROMPT_PLEX_RELOGIN = prompt("You already have Plex Access Token, do you want to log in again?") SUCCESS_MESSAGE = success("Plex Media Server Authentication Token and base URL have been added to .env file") NOTICE_2FA_PASSWORD = comment( "If you have 2 Factor Authentication enabled on Plex " "you can append the code to your password below (eg. passwordCODE)" ) CONFIG = factory.config() from InquirerPy import get_style, inquirer style = get_style({"questionmark": "hidden", "question": "ansiyellow", "pointer": "fg:ansiblack bg:ansiyellow", }) def myplex_login(username, password): while True: username = click.prompt(PROMPT_PLEX_USERNAME, type=str, default=username) click.echo(NOTICE_2FA_PASSWORD) password = click.prompt(PROMPT_PLEX_PASSWORD, type=str, default=password, hide_input=True, show_default=False) try: return MyPlexAccount(username, password) except Unauthorized as e: click.echo(error(f"Log in to Plex failed: {e}, Try again."))
def _get_plex_server(): CONFIG = factory.config() plex_token = CONFIG["PLEX_TOKEN"] plex_baseurl = CONFIG["PLEX_BASEURL"] plex_fallbackurl = CONFIG["PLEX_FALLBACKURL"] if plex_token == "-": plex_token = "" server = None plexapi.X_PLEX_PLATFORM = PLEX_PLATFORM plexapi.BASE_HEADERS["X-Plex-Platform"] = plexapi.X_PLEX_PLATFORM session = factory.session() PlexServer = partial(plexapi.server.PlexServer, session=session) # if connection fails, it will try : # 1. url expected by new ssl certificate # 2. url without ssl # 3. fallback url (localhost) try: server = PlexServer(token=plex_token, baseurl=plex_baseurl) except plexapi.server.requests.exceptions.SSLError as e: m = "Plex connection error: {}, fallback url {} didn't respond either.".format( str(e), plex_fallbackurl) excep_msg = str(e.__context__) if "doesn't match '*." in excep_msg: hash_pos = excep_msg.find("*.") + 2 new_hash = excep_msg[hash_pos:hash_pos + 32] end_pos = plex_baseurl.find(".plex.direct") new_plex_baseurl = (plex_baseurl[:end_pos - 32] + new_hash + plex_baseurl[end_pos:]) try: # 1 server = PlexServer(token=plex_token, baseurl=new_plex_baseurl) # save new url to .env CONFIG["PLEX_TOKEN"] = plex_token CONFIG["PLEX_BASEURL"] = new_plex_baseurl CONFIG["PLEX_FALLBACKURL"] = plex_fallbackurl CONFIG.save() logger.info( "Plex server url changed to {}".format(new_plex_baseurl)) except Exception: pass if server is None and plex_baseurl[:5] == "https": new_plex_baseurl = plex_baseurl.replace("https", "http") try: # 2 server = PlexServer(token=plex_token, baseurl=new_plex_baseurl) logger.warning( "Switched to Plex unsecure connection because of SSLError." ) except Exception: pass except Exception as e: m = "Plex connection error: {}, fallback url {} didn't respond either.".format( str(e), plex_fallbackurl) if server is None: try: # 3 server = PlexServer(token=plex_token, baseurl=plex_fallbackurl) logger.warning("No response from {}, fallback to {}".format( plex_baseurl, plex_fallbackurl)) except Exception: logger.error(m) print(m) exit(1) return server
def library_sections(self) -> Dict[int, PlexLibrarySection]: CONFIG = factory.config() for section in self.plex.library.sections(): if section.title in CONFIG["excluded-libraries"]: continue yield section.key, PlexLibrarySection(section, plex=self)
def has_trakt_token(): if not exists(pytrakt_file): return False CONFIG = factory.config() return CONFIG["TRAKT_USERNAME"] is not None