In an old post I teach how to create your own Netflix with Docker Compose. The problem is that over time you can download several movies with really low rating, or from a genre you are not a fan.

I have created a small Jupyter Notebook to help me with my spring-cleaning (in this case winter). Feel free to modify it to your case.

from plexapi.myplex import MyPlexAccount

account = MyPlexAccount('USERNAME', 'PASSWORD')
plex = account.resource('PLEX SERVER NAME').connect()

movies_to_delete = list()
movies_to_refresh = list()
movies = plex.library.section('Films')
liked_genres = {'Comedy', 'Horror', 'Sci-Fi', 'Mystery', 'Adventure', 'Action', 'Fantasy', 'Thriller',
               'Science Fiction', 'Action/Adventure', 'Crime', 'Western', 'Animation'}
for movie in movies.search(unwatched=True): 
    genres = set()
    for genre in movie.genres:
        genres.add(genre.tag)
    if len(genres & liked_genres) == 0:
        print("Movie {} not with liked genres: {}".format(movie.title, genres))
        movies_to_delete.append(movie)
movies = plex.library.section('Films')
for video in movies.search(unwatched=True):
    title = video.title
    rating = video.rating
    audience = video.audienceRating
    if rating is not None and rating < 4.0 and audience is None:
        print("title = {title}, rating = {rating}, audience = {audience}".
              format(title = title, rating = rating, audience = audience))
        movies_to_delete.append(video)
        continue
    if rating is not None and rating < 5.0 and \
       audience is not None and audience < 5.0:
        print("title = {title}, rating = {rating}, audience = {audience}".
              format(title = title, rating = rating, audience = audience))
        movies_to_delete.append(video)
        continue
    if rating is not None and audience is not None and \
       (rating + audience)/2 < 5.0:
        print("title = {title}, rating = {rating}, audience = {audience}".
              format(title = title, rating = rating, audience = audience))
        movies_to_delete.append(video)
        continue
    if audience is not None and audience < 4.0:
        print("title = {title}, rating = {rating}, audience = {audience}".
              format(title = title, rating = rating, audience = audience))
        movies_to_delete.append(video)
        continue
    if audience is None or rating is None:
        movies_to_refresh.append(video)
movies = plex.library.section('Films')
for movie in movies.search(unwatched=True):
    movie.reload()
    for media in movie.media:
        for part in media.parts:
            languages = list()
            for audioStream in part.audioStreams():
                language = audioStream.language
                if language is not None:
                    languages.append(language)
            if len(languages) > 0 and 'English' not in languages:
                print("The movie {} is not in English ({})".format(movie.title, languages))
                movies_to_delete.append(movie)
                    
# for movie in movies_to_delete:
#     print("Deleting {}".format(movie.title))
#     movie.delete()

# for movie in movies_to_refresh:
#     print("Refresing metadata of movie for next run: {}".format(movie.title))
#     video.refresh()

For safety I have commented the lines that delete or trigger a refresh in Plex, so you can copy/paste and try it without risk

Happy cleaning