Example #1
0
def append_collection(config_path, config_update=None):
    while True:
        if config_update:
            collection_name = config_update
            selected_collection = plex_tools.get_collection(
                plex, collection_name, True)
        else:
            collection_name = input("Enter collection to add to: ")
            selected_collection = plex_tools.get_collection(
                plex, collection_name)
        try:
            if not isinstance(selected_collection, str):
                print("\"{}\" Selected.".format(selected_collection.title))
                finished = False
                while not finished:
                    try:
                        collection_type = selected_collection.subtype
                        if collection_type == 'movie':
                            method = input(
                                "Add Movie(m), Actor(a), IMDb/TMDb/Trakt List(l), Custom(c)?: "
                            )
                        else:
                            method = input(
                                "Add Show(s), Actor(a), IMDb/TMDb/Trakt List(l), Custom(c)?: "
                            )
                        if method == "m":
                            if not config_update:
                                method = "movie"
                                value = input(
                                    "Enter Movie (Name or Rating Key): ")
                                if value is int:
                                    plex_movie = plex_tools.get_movie(
                                        int(value))
                                    print('+++ Adding %s to collection %s' %
                                          (plex_movie.title,
                                           selected_collection.title))
                                    plex_movie.addCollection(
                                        selected_collection.title)
                                else:
                                    results = plex_tools.get_movie(plex, value)
                                    if len(results) > 1:
                                        while True:
                                            i = 1
                                            for result in results:
                                                print(
                                                    "{POS}) {TITLE} - {RATINGKEY}"
                                                    .format(POS=i,
                                                            TITLE=result.title,
                                                            RATINGKEY=result.
                                                            ratingKey))
                                                i += 1
                                            s = input(
                                                "Select movie (N for None): ")
                                            if int(s):
                                                s = int(s)
                                                if len(results) >= s > 0:
                                                    result = results[s - 1]
                                                    print(
                                                        '+++ Adding %s to collection %s'
                                                        % (result.title,
                                                           selected_collection.
                                                           title))
                                                    result.addCollection(
                                                        selected_collection.
                                                        title)
                                                    break
                                            else:
                                                break
                            else:
                                print(
                                    "Movies in configuration file not yet supported"
                                )

                        elif method == "s":
                            if not config_update:
                                method = "show"
                                value = input(
                                    "Enter Show (Name or Rating Key): ")
                                if value is int:
                                    plex_show = plex_tools.get_show(int(value))
                                    print('+++ Adding %s to collection %s' %
                                          (plex_show.title,
                                           selected_collection.title))
                                    plex_show.addCollection(
                                        selected_collection.title)
                                else:
                                    results = plex_tools.get_show(plex, value)
                                    if len(results) > 1:
                                        while True:
                                            i = 1
                                            for result in results:
                                                print(
                                                    "{POS}) {TITLE} - {RATINGKEY}"
                                                    .format(POS=i,
                                                            TITLE=result.title,
                                                            RATINGKEY=result.
                                                            ratingKey))
                                                i += 1
                                            s = input(
                                                "Select show (N for None): ")
                                            if int(s):
                                                s = int(s)
                                                if len(results) >= s > 0:
                                                    result = results[s - 1]
                                                    print(
                                                        '+++ Adding %s to collection %s'
                                                        % (result.title,
                                                           selected_collection.
                                                           title))
                                                    result.addCollection(
                                                        selected_collection.
                                                        title)
                                                    break
                                            else:
                                                break
                            else:
                                print(
                                    "Shows in configuration file not yet supported"
                                )

                        elif method == "a":
                            method = "actors"
                            value = input("Enter Actor Name: ")
                            a_rkey = plex_tools.get_actor_rkey(plex, value)
                            if config_update:
                                modify_config(config_path, collection_name,
                                              method, value)
                            else:
                                plex_tools.add_to_collection(
                                    config_path, plex, method, a_rkey,
                                    selected_collection.title)

                        elif method == "l":
                            l_type = input(
                                "Enter list type IMDb(i) TMDb(t) Trakt(k): ")
                            if l_type == "i":
                                l_type = "IMDb"
                                method = "imdb-list"
                            elif l_type == "t":
                                l_type = "TMDb"
                                method = "tmdb-list"
                            elif l_type == "k":
                                l_type = "Trakt"
                                method = "trakt-list"
                            else:
                                return
                            url = input(
                                "Enter {} List URL: ".format(l_type)).strip()
                            print("Processing {} List: {}".format(l_type, url))
                            if config_update:
                                modify_config(config_path, collection_name,
                                              method, url)
                            else:
                                missing = plex_tools.add_to_collection(
                                    config_path, plex, method, url,
                                    selected_collection.title)
                                if missing:
                                    if collection_type == 'movie':
                                        print(
                                            "{} missing movies from {} List: {}"
                                            .format(len(missing), l_type, url))
                                        if input(
                                                "Add missing movies to Radarr? (y/n)"
                                        ).upper() == "Y":
                                            add_to_radarr(config_path, missing)
                                    elif collection_type == 'show':
                                        print(
                                            "{} missing shows from {} List: {}"
                                            .format(len(missing_shows), l_type,
                                                    url))
                                    #     if input("Add missing shows to Sonarr? (y/n)").upper() == "Y":
                                    #         add_to_sonarr(missing_shows)
                                print("Bad {} List URL".format(l_type))

                        elif method == "c":
                            print(
                                "Please read the below link to see valid filter types. "
                                "Please note not all have been tested")
                            print(
                                "https://python-plexapi.readthedocs.io/en/latest/modules/video.html?highlight=plexapi.video.Movie#plexapi.video.Movie"
                            )
                            while True:
                                method = input(
                                    "Enter filter method (q to quit): ")
                                if method in "quit":
                                    break
                                m_search = "  " + method + " "
                                if m_search in Movie.__doc__ or hasattr(
                                        Movie, m_search):
                                    if method[-1:] == "s":
                                        method_p = method[:-1]
                                    else:
                                        method_p = method
                                    value = input(
                                        "Enter {}: ".format(method_p))
                                    if config_update:
                                        modify_config(config_path,
                                                      collection_name, method,
                                                      value)
                                    else:
                                        plex_tools.add_to_collection(
                                            config_path, plex, method, value,
                                            selected_collection.title)
                                    break
                                else:
                                    print(
                                        "Filter method did not match an attribute for plexapi.video.Movie"
                                    )
                    except TypeError:
                        print("Bad {} URL".format(l_type))
                    except KeyError as e:
                        print(e)
                    if input("Add more to collection? (y/n): ") == "n":
                        finished = True
                        print("\n")
                break
            else:
                print(selected_collection)
                break
        except AttributeError:
            print("No collection found")
Example #2
0
while not mode == "q":
    try:
        print("Modes: Rescan(r), Actor(a), IMDb/TMDb/Trakt List(l), "
              "Add to Existing Collection(+), Delete(-), "
              "Search(s), Quit(q)\n")
        mode = input("Select Mode: ")

        if mode == "r":
            update_from_config(config_path, plex)

        elif mode == "a":
            actor = input("Enter actor name: ")
            a_rkey = plex_tools.get_actor_rkey(plex, actor)
            if isinstance(a_rkey, int):
                c_name = input("Enter collection name: ")
                plex_tools.add_to_collection(config_path, plex, "actors",
                                             a_rkey, c_name)
            else:
                print("Invalid actor")
            print("\n")

        elif mode == "l":
            l_type = input("Enter list type IMDb(i) TMDb(t) Trakt(k): ")
            method_map = {
                "i": ("IMDb", "imdb-list"),
                "t": ("TMDb", "tmdb-list"),
                "k": ("Trakt", "trakt-list")
            }
            if l_type in ("i", "t", "k"):
                l_type, method = method_map[l_type]
                url = input("Enter {} List URL: ".format(l_type)).strip()
                c_name = input("Enter collection name: ")
Example #3
0
def update_from_config(config_path, plex):
    config = Config(config_path)
    collections = config.collections
    if isinstance(plex.Library, MovieSection):
        libtype = "movie"
    elif isinstance(plex.Library, ShowSection):
        libtype = "show"
    for c in collections:
        print("Updating collection: {}...".format(c))
        methods = [m for m in collections[c] if m not in ("details", "subfilters")]
        subfilters = []
        if "subfilters" in collections[c]:
            for sf in collections[c]["subfilters"]:
                sf_string = sf, collections[c]["subfilters"][sf]
                subfilters.append(sf_string)
        for m in methods:
            if isinstance(collections[c][m], list):
                # Support multiple imdb/tmdb/trakt lists
                values = collections[c][m]
            else:
                values = collections[c][m].split(", ")
            for v in values:
                if m[-1:] == "s":
                    m_print = m[:-1]
                else:
                    m_print = m
                print("Processing {}: {}".format(m_print, v))
                if m == "actors" or m == "actor":
                    v = get_actor_rkey(plex, v)
                try:
                    missing = add_to_collection(config_path, plex, m, v, c, subfilters)
                except UnboundLocalError:  # No sub-filters
                    missing = add_to_collection(config_path, plex, m, v, c)
                except (KeyError, ValueError) as e:
                    print(e)
                    missing = False
                if missing:
                    if libtype == "movie":
                        if "imdb" in m:
                            method_name = "IMDb"
                        elif "trakt" in m:
                            method_name = "Trakt"
                        else:
                            method_name = "TMDb"
                        print("{} missing movies from {} List: {}".format(len(missing), method_name, v))
                        if 'add_movie' in config.radarr:
                            if config.radarr['add_movie'] is True:
                                print("Adding missing movies to Radarr")
                                add_to_radarr(config_path, missing)
                        else:
                            if input("Add missing movies to Radarr? (y/n): ").upper() == "Y":
                                add_to_radarr(config_path, missing)
                    elif libtype == "show":
                        if "trakt" in m:
                            method_name = "Trakt"
                        else:
                            method_name = "TMDb"
                        print("{} missing shows from {} List: {}".format(len(missing), method_name, v))
                        # if not skip_sonarr:
                        #     if input("Add missing shows to Sonarr? (y/n): ").upper() == "Y":
                        #         add_to_radarr(missing_shows)
        # Multiple collections of the same name
        if "details" in collections[c]:
            # # Check if there are multiple collections with the same name
            # movie_collections = plex.MovieLibrary.search(title=c, libtype="collection")
            # show_collections = plex.ShowLibrary.search(title=c, libtype="collection")
            # if len(movie_collections + show_collections) > 1:
            #     print("Multiple collections named {}.\nUpdate of \"details\" is currently unsupported.".format(c))
            #     continue
            plex_collection = get_collection(plex, c)
            if not isinstance(plex_collection, Collections):
                # No collections created with requested criteria
                continue

            rkey = plex_collection.ratingKey

            # Handle collection summary
            summary = None
            if "summary" in collections[c]["details"]:
                summary = collections[c]["details"]["summary"]
            elif "tmdb-summary" in collections[c]["details"]:
                # Seems clunky ...
                try:
                    summary = tmdb_get_summary(config_path, collections[c]["details"]["tmdb-summary"], "overview")
                except AttributeError:
                    summary = tmdb_get_summary(config_path, collections[c]["details"]["tmdb-summary"], "biography")
            if summary:
                # Push summary to Plex
                # Waiting on https://github.com/pkkid/python-plexapi/pull/509
                # See https://github.com/pkkid/python-plexapi/issues/514
                url = plex.url + "/library/sections/" + str(plex.Library.key) + "/all"
                querystring = {"type": "18",
                               "id": str(rkey),
                               "summary.value": summary,
                               "X-Plex-Token": config.plex['token']}
                response = requests.put(url, params=querystring)
                # To do: add logic to report errors
            
            # Handle collection posters
            poster = None
            if "poster" in collections[c]["details"]:
                poster = collections[c]["details"]["poster"]
            elif "tmdb-poster" in collections[c]["details"]:
                # Seems clunky ...
                try:
                    slug = tmdb_get_summary(config_path, collections[c]["details"]["tmdb-poster"], "poster_path")
                except AttributeError:
                    slug = tmdb_get_summary(config_path, collections[c]["details"]["tmdb-poster"], "profile_path")
                
                poster = "https://image.tmdb.org/t/p/original/" + slug
            else:
                # Try to pull image from image_server.
                # To do: this should skip if it's run without the image server
                # To do: this only runs if 'details' key is set - might make sense to run regardless
                # Setup connection to image_server
                config_client = ImageServer(config_path, "client")

                # Url encode collection name
                c_name = urllib.parse.quote(c, safe='')
                
                # Create local url to where image would be if exists
                local_poster_url = "http://" + config_client.host + ":" + str(config_client.port) + "/images/" + c_name
                
                # Test local url
                response = requests.head(local_poster_url)
                if response.status_code < 400:
                    poster = local_poster_url

            if poster:               
                # Push poster to Plex
                # Waiting on https://github.com/pkkid/python-plexapi/pull/509
                # See https://github.com/pkkid/python-plexapi/issues/514
                url = plex.url + "/library/metadata/" + str(rkey) + "/posters"
                querystring = {"url": poster,
                               "X-Plex-Token": config.plex['token']}
                response = requests.post(url, params=querystring)
Example #4
0
def update_from_config(plex, skip_radarr=False):
    config = Config()
    collections = config.collections
    for c in collections:
        print("Updating collection: {}...".format(c))
        methods = [
            m for m in collections[c] if m not in ("details", "subfilters")
        ]
        subfilters = []
        if "subfilters" in collections[c]:
            for sf in collections[c]["subfilters"]:
                sf_string = sf, collections[c]["subfilters"][sf]
                subfilters.append(sf_string)
        for m in methods:
            values = collections[c][m].split(", ")
            for v in values:
                if m[-1:] == "s":
                    m_print = m[:-1]
                else:
                    m_print = m
                print("Processing {}: {}".format(m_print, v))
                if m == "actors" or m == "actor":
                    v = get_actor_rkey(plex, v)
                try:
                    missing = add_to_collection(plex, m, v, c, subfilters)
                except UnboundLocalError:  # No sub-filters
                    missing = add_to_collection(plex, m, v, c)
                except KeyError as e:
                    print(e)
                    missing = False
                if missing:
                    if "imdb" in m:
                        m = "IMDB"
                    else:
                        m = "TMDb"
                    print("{} missing movies from {} List: {}".format(
                        len(missing), m, v))
                    if not skip_radarr:
                        if input("Add missing movies to Radarr? (y/n): "
                                 ).upper() == "Y":
                            add_to_radarr(missing)
        if "details" in collections[c]:
            for dt_m in collections[c]["details"]:
                rkey = get_collection(plex, c).ratingKey
                dt_v = collections[c]["details"][dt_m]
                if "summary" in dt_m:
                    if "tmdb" in dt_m:
                        try:
                            dt_v = tmdb_get_summary(dt_v, "overview")
                        except AttributeError:
                            dt_v = tmdb_get_summary(dt_v, "biography")

                    library_name = plex.library
                    section = plex.Server.library.section(library_name).key
                    url = plex.url + "/library/sections/" + str(
                        section) + "/all"

                    querystring = {
                        "type": "18",
                        "id": str(rkey),
                        "summary.value": dt_v,
                        "X-Plex-Token": config.plex['token']
                    }
                    response = requests.request("PUT", url, params=querystring)
                poster = None
                if "poster" in dt_m:
                    if "tmdb" in dt_m:
                        poster = "https://image.tmdb.org/t/p/original/"
                        poster = poster + tmdb_get_summary(dt_v).poster_path
                    else:
                        poster = dt_v
                if not poster:
                    # try to pull image from image_server. File is Collection name.png
                    # Setup connection to image_server
                    try:
                        host = config.image_server["host"]
                    except AttributeError:
                        host = "127.0.0.1"
                    try:
                        port = config.image_server["port"]
                    except AttributeError:
                        port = "5000"

                    # Replace spaces in collection name with %20
                    c_name = c.replace(" ", "%20")
                    # Create url to where image would be if exists
                    poster = "http://" + host + ":" + str(
                        port) + "/images/" + c_name
                    try:
                        r = requests.request("GET", poster)
                        if not r.status_code == 404:
                            # Create url for request to Plex
                            url = plex.url + "/library/metadata/" + str(
                                rkey) + "/posters"
                            querystring = {
                                "url": poster,
                                "X-Plex-Token": config.plex['token']
                            }
                            response = requests.request("POST",
                                                        url,
                                                        params=querystring)
                    except:
                        False
Example #5
0
def update_from_config(config_path, plex, skip_radarr=False):
    config = Config(config_path)
    collections = config.collections
    if isinstance(plex.Library, MovieSection):
        libtype = "movie"
    elif isinstance(plex.Library, ShowSection):
        libtype = "show"
    for c in collections:
        print("Updating collection: {}...".format(c))
        methods = [
            m for m in collections[c] if m not in ("details", "subfilters")
        ]
        subfilters = []
        if "subfilters" in collections[c]:
            for sf in collections[c]["subfilters"]:
                sf_string = sf, collections[c]["subfilters"][sf]
                subfilters.append(sf_string)
        for m in methods:
            if isinstance(collections[c][m], list):
                # Support multiple imdb/tmdb/trakt lists
                values = collections[c][m]
            else:
                values = collections[c][m].split(", ")
            for v in values:
                if m[-1:] == "s":
                    m_print = m[:-1]
                else:
                    m_print = m
                print("Processing {}: {}".format(m_print, v))
                if m == "actors" or m == "actor":
                    v = get_actor_rkey(plex, v)
                try:
                    missing = add_to_collection(config_path, plex, m, v, c,
                                                subfilters)
                except UnboundLocalError:  # No sub-filters
                    missing = add_to_collection(config_path, plex, m, v, c)
                except (KeyError, ValueError) as e:
                    print(e)
                    missing = False
                if missing:
                    if libtype == "movie":
                        if "imdb" in m:
                            method_name = "IMDb"
                        elif "trakt" in m:
                            method_name = "Trakt"
                        else:
                            method_name = "TMDb"
                        print("{} missing movies from {} List: {}".format(
                            len(missing), method_name, v))
                        if not skip_radarr:
                            if input("Add missing movies to Radarr? (y/n): "
                                     ).upper() == "Y":
                                add_to_radarr(config_path, missing)
                    elif libtype == "show":
                        if "trakt" in m:
                            method_name = "Trakt"
                        else:
                            method_name = "TMDb"
                        print("{} missing shows from {} List: {}".format(
                            len(missing), method_name, v))
                        # if not skip_sonarr:
                        #     if input("Add missing shows to Sonarr? (y/n): ").upper() == "Y":
                        #         add_to_radarr(missing_shows)
        # Multiple collections of the same name
        if "details" in collections[c]:
            # # Check if there are multiple collections with the same name
            # movie_collections = plex.MovieLibrary.search(title=c, libtype="collection")
            # show_collections = plex.ShowLibrary.search(title=c, libtype="collection")
            # if len(movie_collections + show_collections) > 1:
            #     print("Multiple collections named {}.\nUpdate of \"details\" is currently unsupported.".format(c))
            #     continue
            plex_collection = get_collection(plex, c)
            if not isinstance(plex_collection, Collections):
                # No collections created with requested criteria
                continue
            for dt_m in collections[c]["details"]:
                rkey = plex_collection.ratingKey
                # subtype = plex_collection.subtype
                dt_v = collections[c]["details"][dt_m]
                if "summary" in dt_m:
                    if "tmdb" in dt_m:
                        try:
                            dt_v = tmdb_get_summary(config_path, dt_v,
                                                    "overview")
                        except AttributeError:
                            dt_v = tmdb_get_summary(config_path, dt_v,
                                                    "biography")

                    library_name = plex.Library

                    #section = plex.Server.library.section(library_name).key
                    section = library_name.key
                    url = plex.url + "/library/sections/" + str(
                        section) + "/all"

                    querystring = {
                        "type": "18",
                        "id": str(rkey),
                        "summary.value": dt_v,
                        "X-Plex-Token": config.plex['token']
                    }
                    response = requests.request("PUT", url, params=querystring)
                poster = None
                if "poster" in dt_m:
                    if "tmdb" in dt_m:
                        poster = "https://image.tmdb.org/t/p/original/"
                        poster = poster + tmdb_get_summary(dt_v).poster_path
                    else:
                        poster = dt_v
                if not poster:
                    # try to pull image from image_server. File is Collection name.png
                    # Setup connection to image_server
                    try:
                        host = config.image_server["host"]
                    except AttributeError:
                        host = "127.0.0.1"
                    try:
                        port = config.image_server["port"]
                    except AttributeError:
                        port = "5000"

                    # Replace spaces in collection name with %20
                    c_name = c.replace(" ", "%20")
                    # Create url to where image would be if exists
                    poster = "http://" + host + ":" + str(
                        port) + "/images/" + c_name
                    try:
                        r = requests.request("GET", poster)
                        if not r.status_code == 404:
                            # Create url for request to Plex
                            url = plex.url + "/library/metadata/" + str(
                                rkey) + "/posters"
                            querystring = {
                                "url": poster,
                                "X-Plex-Token": config.plex['token']
                            }
                            response = requests.request("POST",
                                                        url,
                                                        params=querystring)
                    except:
                        False