Esempio n. 1
0
    def sync_collection(self, m: Media, dry_run=False):
        if not self.config.plex_to_trakt["collection"]:
            return

        if m.is_collected:
            return

        logger.info(f"To be added to collection: {m}")
        if not dry_run:
            m.add_to_collection()
Esempio n. 2
0
 def addPlexItem(self, trakt_item, plex_item):
     rank = self.trakt_items.get((trakt_item.media_type, trakt_item.trakt))
     if rank is not None:
         self.plex_items.append((rank, plex_item))
         if isinstance(plex_item, Episode):
             logger.info(
                 f"Added to list {self.name}: {plex_item.show()}: {plex_item.seasonEpisode}"
             )
         else:
             logger.info(f"Added to list {self.name}: {plex_item}")
Esempio n. 3
0
def sync(
    sync_option: str,
    library: str,
    show: str,
    movie: str,
    ids: List[str],
    batch_size: int,
    dry_run: bool,
    no_progress_bar: bool,
):
    """
    Perform sync between Plex and Trakt
    """

    logger.info(f"PlexTraktSync [{version()}]")
    ensure_login()

    movies = sync_option in ["all", "movies"]
    shows = sync_option in ["all", "tv", "shows"]

    config = factory.run_config().update(batch_size=batch_size,
                                         dry_run=dry_run,
                                         progressbar=not no_progress_bar)
    wc = factory.walk_config().update(movies=movies, shows=shows)
    w = factory.walker()

    if ids:
        for id in ids:
            wc.add_id(id)
    if library:
        wc.add_library(library)
    if show:
        wc.add_show(show)
    if movie:
        wc.add_movie(movie)

    if not wc.is_valid():
        click.echo(
            "Nothing to sync, this is likely due conflicting options given.")
        return

    try:
        w.print_plan(print=tqdm.write)
    except RuntimeError as e:
        raise ClickException(str(e))

    if dry_run:
        print("Enabled dry-run mode: not making actual changes")

    with measure_time("Completed full sync"):
        try:
            runner = factory.sync()
            runner.sync(walker=w, dry_run=config.dry_run)
        except RuntimeError as e:
            raise ClickException(str(e))
Esempio n. 4
0
    def submit_collection(self):
        if self.queue_size() == 0:
            return

        try:
            result = self.trakt_sync_collection(self.collection)
            result = self.remove_empty_values(result.copy())
            if result:
                logger.info(f"Updated Trakt collection: {result}")
        finally:
            self.collection.clear()
Esempio n. 5
0
 def addList(self, username, listname, trakt_list=None):
     if trakt_list is not None:
         self.lists.append(TraktList.from_trakt_list(listname, trakt_list))
         logger.info("Downloaded List {}".format(listname))
         return
     try:
         self.lists.append(TraktList(username, listname))
         logger.info("Downloaded List {}".format(listname))
     except (NotFoundException, OAuthException):
         logger.warning("Failed to get list {} by user {}".format(
             listname, username))
Esempio n. 6
0
def clear_collections(confirm, dry_run):
    if not confirm and not dry_run:
        click.echo("You need to pass --confirm or --dry-run option to proceed")
        return

    trakt = factory.trakt_api()

    for movie in trakt.movie_collection:
        logger.info(f"Deleting: {movie}")
        if not dry_run:
            trakt.remove_from_library(movie)

    for show in trakt.show_collection:
        logger.info(f"Deleting: {show}")
        if not dry_run:
            trakt.remove_from_library(show)
Esempio n. 7
0
    def sync_watched(self, m: Media, dry_run=False):
        if not self.config.sync_watched_status:
            return

        if m.watched_on_plex is m.watched_on_trakt:
            return

        if m.watched_on_plex:
            if not self.config.plex_to_trakt["watched_status"]:
                return
            logger.info(f"Marking as watched in Trakt: {m}")
            if not dry_run:
                m.mark_watched_trakt()
        elif m.watched_on_trakt:
            if not self.config.trakt_to_plex["watched_status"]:
                return
            logger.info(f"Marking as watched in Plex: {m}")
            if not dry_run:
                m.mark_watched_plex()
Esempio n. 8
0
    def sync_ratings(self, m: Media, dry_run=False):
        if not self.config.sync_ratings:
            return

        if m.plex_rating is m.trakt_rating:
            return

        # Plex rating takes precedence over Trakt rating
        if m.plex_rating is not None:
            if not self.config.plex_to_trakt["ratings"]:
                return
            logger.info(f"Rating {m} with {m.plex_rating} on Trakt")
            if not dry_run:
                m.trakt_rate()
        elif m.trakt_rating is not None:
            if not self.config.trakt_to_plex["ratings"]:
                return
            logger.info(f"Rating {m} with {m.trakt_rating} on Plex")
            if not dry_run:
                m.plex_rate()
Esempio n. 9
0
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