How empty the entryfield "Edition" containing more that one edition after searching/filtering?

I want to delete the editions from my library. So I did enter as an example “a” in the filter field.

The result is this:

Now I select all three movies and hit “Edit”. This is the result:

image

How can I delete the editions of these three movies at once? Usually removing more than one entry in an entryfield works (for example image tags). For editions that does not seem to work.

Is it really required to enter all editions individually and manually to remove them completely? Or is there a Web-URL to do so?

Thanks in advance.

Found a way.

Please close thread.

Care to share the way for anyone who may need to do this in future?

I wrote a Python script to do so. I can’t share the complete script because it’s part of a big Python library that does various things with Plex. All is done with the Web-URLs.

My files are usually renamed like:

Movie (yyyy) {imdb-12345678} {edition-editionname} - part1.mkv

With this script I rename them to the following and patch the edition as empty and unlocked. Notice the different brace styles:

Movie (yyyy) {imdb-12345678} [edition-editionname] - part1.mkv

Just the relevant part. Use at your own risk:

    library_key = findLibrary("movie", args.library)
    if library_key:

        if args.ratingkey:
            data = getUrl(f"/library/sections/{library_key}/all?id={args.ratingkey}")
        elif args.edition:
            data = getUrl(f"/library/sections/{library_key}/all?editionTitle={args.edition}")
        elif args.file:
            data = getUrl(f"/library/sections/{library_key}/all?file={args.file}")
        elif args.recentlyadded:
            data = getUrl(f"/library/sections/{library_key}/recentlyAdded")
        elif args.title:
            data = getUrl(f"/library/sections/{library_key}/all?title={args.title}")
        elif args.year:
            data = getUrl(f"/library/sections/{library_key}/all?year={args.year}")
        else:
            data = getUrl(f"/library/sections/{library_key}/all")
    
        if data:
            media_container = ET.ElementTree(ET.fromstring(data.text))

            for video in media_container.findall("Video"):
                movies += 1

                video_editiontitle = video.get("editionTitle")
                if video_editiontitle:
                   
                    video_key = video.get("key")

                    data = getUrl(f"{video_key}")
                    if data:

                        media_container2 = ET.ElementTree(ET.fromstring(data.text))

                        for video2 in media_container2.findall("Video"):

                            video2_editiontitle_locked = None
                            for video2_field in video2.findall("Field"):
                                video2_field_locked = video2_field.get("locked")
                                video2_field_name = video2_field.get("name")
                                
                                if video2_field_name == FIELDNAMES["Edition"]:
                                    if video2_field_locked == "1":
                                        video2_editiontitle_locked = True
                                        break

                            video2_ratingkey = video2.get("ratingKey")
                            video2_title = video2.get("title")
                            video2_year = video2.get("year")

                            video2_media = video2.find("Media")

                            found = None
                                
                            for video2_media_part in video2_media.findall("Part"):
                                video2_media_part_file = video2_media_part.get("file")
                                
                                file_path, file_filename, file_extension = split_filename(video2_media_part_file)
                                path_old = os.path.basename(os.path.normpath(file_path))
                            
                                imdbid = ""
                                tmdbid = ""
                                tvdbid = ""
                                for guid in video2.findall("Guid"):
                                    guid_id = guid.get("id")
                                    if "imdb://" in guid_id:
                                        imdbid = " {imdb-" + guid_id.replace("imdb://", "") + "}"
                                        if imdbid in video2_media_part_file:
                                            break
                                    elif "tmdb://" in guid_id:
                                        tmdbid = " {tmdb-" + guid_id.replace("tmdb://", "") + "}"
                                        if tmdbid in video2_media_part_file:
                                            break
                                    elif "tvdb://" in guid_id:
                                        tvdbid = " {tvdb-" + guid_id.replace("tvdb://", "") + "}"
                                        if tvdbid in video2_media_part_file:
                                            break
                                    
                                id = ""
                                if imdbid:
                                    id = imdbid
                                elif tmdbid:
                                    id = tmdbid
                                elif tvdbid:
                                    id = tvdbid

                                edition = ""
                                if video_editiontitle:
                                    edition = " [edition-" + video_editiontitle + "]"

                                if not edition and "[edition-" in file_filename:
                                    match_edition_unofficial = pattern_edition_unofficial.match(file_filename)
                                    if match_edition_unofficial:
                                        edition = " [edition-" + match_edition_unofficial[2] + "]"

                                part = ""
                                if " - part" in file_filename:
                                    match_part = pattern_part.match(file_filename)
                                    if match_part:
                                        part = " - part" + match_part[1]

                                year = ""
                                if video2_year:
                                    year = f" ({video2_year})"
                                
                                title_new = processUmlauts(video2_title)
                            
                                movies_verarbeitet += 1

                                filename_new = f"{title_new}{year}{id}{edition}{part}.{file_extension}"

                                if os.path.isfile(video2_media_part_file) and file_filename + "." + file_extension != filename_new:
                                    if not args.dryrun:
                                        os.rename(video2_media_part_file, f"{file_path}/{filename_new}")
                                        
                                found = True

                                if video2_editiontitle_locked:
                                    params = {
                                        "id": video2_ratingkey,
                                        "includeExternalMedia": 1,
                                        "type": SECTIONTYPES["movie"],
                                        FIELDNAMES["Edition"]+".locked": 0,
                                        }

                                    if not args.dryrun:
                                        data = requests.put(f"{plex_url}/library/sections/{library_key}/all", params=params, headers=plex_headers)

                                params = {
                                    "id": video2_ratingkey,
                                    "includeExternalMedia": 1,
                                    "type": SECTIONTYPES["movie"],
                                    FIELDNAMES["Edition"]+".value": "",
                                    }
                                    
                                if not args.dryrun:
                                    data = requests.put(f"{plex_url}/library/sections/{library_key}/all", params=params, headers=plex_headers)

Some additional stuff:

FIELDNAMES = {
#
    "Edition":              "editionTitle",
#
}

SECTIONTYPES = {
#
   "movie":         1,
#
}

pattern_edition = re.compile("^(.*)\{edition-(.*)\}(.*)")
pattern_edition_unofficial = re.compile("^(.*)\[edition-(.*)\](.*)")
pattern_part = re.compile(".* part([0-9]*).*")


def split_foldername(folder):
    foldername = ""
    path = ""

    index_path = folder.rfind("/")
    if index_path:
        foldername = folder[index_path + 1:]
        path = folder[:index_path]

    return path, foldername


def split_filename(file):
    extension = ""
    filename = ""
    path = ""

    path, filename = split_foldername(file)
    if filename:
        index_extension = filename.rfind(".")
        if index_extension:
            extension = filename[index_extension + 1:]
            filename = filename[:index_extension]

    return path, filename, extension


def getUrl(url, use_headers = True):
    if use_headers:
        return requests.get(f"{plex_url}{url}", headers=plex_headers)
    else:
        return requests.get(f"{plex_url}{url}")


plex_url = "http://***.***.***.***:32400"
plex_username = "***@***.***"
plex_password = "********"

plex_client_name = "A"
plex_client_version = "1"
plex_client_id = hashlib.sha512("{} {}".format(plex_client_name, plex_client_version).encode()).hexdigest()
plex_base64string = base64.b64encode("{}:{}".format(plex_username, plex_password).encode())

plex_headers = {
    "Authorization": "Basic {}".format(plex_base64string.decode("ascii")),
    "X-Plex-Client-Identifier": plex_client_id,
    "X-Plex-Product": plex_client_name,
    "X-Plex-Version": plex_client_version,
    }


def processUmlauts(text):
    text = text.replace("ä", "ae")
    text = text.replace("ö", "oe")
    text = text.replace("ü", "ue")
    text = text.replace("Ä", "Ae")
    text = text.replace("Ö", "Oe")
    text = text.replace("Ü", "Ue")
    text = text.replace("ß", "ss")

    text = text.replace("&", " Und ")
    text = text.replace("+", " Plus ")
    text = text.replace("$", "s")
    text = text.replace(":", " ")
    text = text.replace("-", " ")
    text = text.replace("_", " ")
    text = text.replace("²", " 2")
    text = text.replace("³", " 3")
    text = text.replace("½", " 1 2")
    text = text.replace("/", " ")
    
    text = unidecode(text)
    
    text = re.sub("[^a-zA-Z0-9 ]+", "", text)

    text = re.sub("\s+", " ", text)

    text = text.title()

    return text.strip()


def findLibrary(library_type, library_name):
    data = getUrl("/library/sections")
    if data:
        media_container = ET.ElementTree(ET.fromstring(data.text))
        for directory in media_container.findall("Directory"):
            directory_key = directory.get("key")
            directory_title = directory.get("title")
            directory_type = directory.get("type")

            if directory_type == library_type and directory_title == library_name:    
                return directory_key
            
    return None

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.