GithubHelp home page GithubHelp logo

rfsbraz / deleterr Goto Github PK

View Code? Open in Web Editor NEW
132.0 5.0 6.0 272 KB

Deleterr is a Python script designed to help you manage available disk space in your Plex media server.

License: MIT License

Python 99.03% Dockerfile 0.63% Makefile 0.33%
overseerr plex plex-media-server plex-server python radarr radarr-api sonarr sonarr-api sonarr3

deleterr's Introduction

Hi there 👋

deleterr's People

Contributors

dependabot[bot] avatar elit3ge avatar fastrack20 avatar rfsbraz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

deleterr's Issues

Library Tag Exclusion not working

I do not believe the tag exclusion is working for libraries, if I understand how it's supposed to work. I set up a tag in both Sonarr and Radarr for "never_expire" and added that to the Deleterr config. However a dry-run showed that it would have deleted several movies and shows that are tagged with this tag.

Add verbose mode - dry run produces no logs

first time user
setup my confutation file
have dry run still enabled
when I run this is all that I get:

2023-09-14 20:03:45 - INFO :: config.py :: deleterr : Running in dry-run mode, no changes will be made.
2023-09-14 20:03:45 - INFO :: deleterr.py :: deleterr : Processing sonarr instance: 'Sonarr'
2023-09-14 20:03:46 - INFO :: deleterr.py :: deleterr : Processing radarr instance: 'Radarr'

I was assuming that media to be deleted would be found in this same log file. Is that accurate?
Thanks

Support for iMDB Lists

It would be great to have support for iMDB lists similar to how Trakt lists work (for exclusions).

Ability to exclude shows that have not ended

This mainly applies to TV Shows, but I imagine there might be a world in anime/movies where the same configuration might be useful.

I want Deleterr to not delete shows that are continuing, only shows that have ended. This is useful if I am waiting around for a new season of a show.

I think Sonarr has information on a show that includes whether it's continuing/ended, so this might be a simple check against Sonarr?

ability to exclude shows that the current season hasnt ended yet and then delete whole season after x days

would like to have the ability to hade deleterr exclude seasons from a tv shows that is currently not finished and only then start counting the "x amount of days until delete".

so as an example, if tv show is currently airing season 5. nothing should get deleted from that season as long as that season is still going on. only after that season is completed (last episode) it should start counting down "x amount of days until delete", and it should calculcate those days from the LAST episode of that season, and when met, delelete that whole season.

Trakt.tv Favorites List not being excluded

Hi there-

I may be configuring this wrong, but I noticed that deleterr is not picking up my Trakt “Favorites” list when I add it to my config like this:

    lists: # Trakt lists to exclude
      [
        "https://trakt.tv/movies/trending",
        "https://trakt.tv/movies/popular",
        "https://trakt.tv/movies/watched/yearly",
        "https://trakt.tv/movies/collected/yearly",
        "https://trakt.tv/users/<username>/favorites"
      ]

When running, in addition to not excluding the movies / shows in the favorites list, I see this error:

deleterr | 2023-08-31 18:29:58 - WARNING :: trakt.py :: deleterr : Traktpy does not support watched shows. Skipping...
deleterr | 2023-08-31 18:29:58 - WARNING :: trakt.py :: deleterr : Traktpy does not support collected shows. Skipping...

More control over how shows are removed

A user is requesting the ability to automatically remove older seasons of a TV show when a new season starts arriving. This would be particularly useful for specific types of content like reality TV shows, sports events, or other seasonal content. Users should be able to specify which collections or shows this rule applies to.

TypeError: unsupported type for timedelta days component: NoneType

I'm getting an error when running deleterr on both the latest and develop tags.

2024-04-02 18:23:51 - INFO :: deleterr.py :: deleterr : Running version 
2024-04-02 18:23:51 - INFO :: deleterr.py :: deleterr : Log level set to INFO
2024-04-02 18:23:51 - INFO :: config.py :: deleterr : Running in dry-run mode, no changes will be made.
2024-04-02 18:23:51 - INFO :: deleterr.py :: deleterr : Processing radarr instance: 'Radarr'
2024-04-02 18:23:51 - INFO :: media_cleaner.py :: deleterr : Processing library 'Movies'
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/app/deleterr.py", line 111, in <module>
    main()
  File "/app/app/deleterr.py", line 107, in main
    Deleterr(config)
  File "/app/app/deleterr.py", line 32, in __init__
    self.process_radarr()
  File "/app/app/deleterr.py", line 42, in process_radarr
    saved_space += self.media_cleaner.process_library_movies(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/media_cleaner.py", line 212, in process_library_movies
    movie_activity = self.get_movie_activity(library, movies_library)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/media_cleaner.py", line 58, in get_movie_activity
    return self.tautulli.get_activity(library, movies_library.key)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/modules/tautulli.py", line 45, in get_activity
    min_date = self._calculate_min_date(library_config)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/modules/tautulli.py", line 65, in _calculate_min_date
    unwatched_threshold_date = datetime.now() - timedelta(
                                                ^^^^^^^^^^
TypeError: unsupported type for timedelta days component: NoneType

Leaving Plex soon notification support

Users want a way to get notified before their media is deleted. The idea is for Deleterr to provide a list that can be consumed by Tautulli's newsletter or email notifications. This way, users can receive an alert telling them which items are slated for deletion in the near future, giving them time to watch it and prevent it.

Add Overseerr support

  • Support excluding requested shows
  • Support including only requested shows
  • Support refreshing the status of deleted shows, to allow them to be requested again

IndexError

Hi
First time user here, hope someone can help. I have been scratching my head with this error. It works fine if I just run it with sonarr. As soon as I enable radarr in the config I get this error. Thanks

2024-05-08 16:39:30 - INFO :: media_cleaner.py :: deleterr : Processing library 'Films'
Traceback (most recent call last):
File "", line 198, in _run_module_as_main
File "", line 88, in _run_code
File "/app/app/deleterr.py", line 111, in
main()
File "/app/app/deleterr.py", line 107, in main
Deleterr(config)
File "/app/app/deleterr.py", line 32, in init
self.process_radarr()
File "/app/app/deleterr.py", line 42, in process_radarr
saved_space += self.media_cleaner.process_library_movies(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/media_cleaner.py", line 212, in process_library_movies
movie_activity = self.get_movie_activity(library, movies_library)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/media_cleaner.py", line 58, in get_movie_activity
return self.tautulli.get_activity(library, movies_library.key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/modules/tautulli.py", line 48, in get_activity
key = self._determine_key(raw_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/modules/tautulli.py", line 98, in _determine_key
if raw_data[0].get("grandparent_rating_key", "")
~~~~~~~~^^^
IndexError: list index out of range

Support for Radarr tags

It would be great if we could add support for Radarr tags that can be used for exclusion items.

TypeError: 'NoneType' object is not iterable since v0.0.13

Hi,

Since version: [v0.0.13], I'm getting

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/app/deleterr.py", line 745, in <module>
    main()
  File "/app/app/deleterr.py", line 741, in main
    Deleterr(config)
  File "/app/app/deleterr.py", line 64, in __init__
    self.process_radarr()
  File "/app/app/deleterr.py", line 212, in process_radarr
    if not library_meets_disk_space_threshold(library, radarr):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/deleterr.py", line 697, in library_meets_disk_space_threshold
    for item in library.get("disk_size_threshold"):
TypeError: 'NoneType' object is not iterable
1

Seems to be related to the new disk_size_threshold function. I have not set this up in the config file.

Any other details needed; let me know.

Delete after played

Discussed in #45

Originally posted by X-static November 20, 2023
Hi, if I wish to delete an episode of a movie a few days after being played, there's no option for that, isn't it?
Will last_watched_threshold: 0 delete anything?

Thank you.

Add support for deleting media X days after being played

Add arm64 image build to registry

If using servarr on a rpi5 it won't be able to run deleterr due to the following:

The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

Can this platform be added to the build process. This is an option on the docker/build-push-action@v5

Archive, instead of delete?

Is there a function to define within the configuration, where you ask Deleterr to archive a show / movie, instead of deleting it?

This would behave the same way as the applications intention, except instead of deleting, it would move the intended file or files to a external hard drive, or a network drive, or some general location where files are to be archived.

Additional features might include zipping or tar’ing the file before officially archiving it.

settings.yaml not found

Current version (not working): 0.0.7
Previous version (working): 0.0.6

Logs:
2023-11-11 06:54:44 - ERROR :: config.py :: deleterr : Configuration file config/settings.yaml not found. Copy the example config and edit it to your needs.
2023-11-11 06:54:44 - INFO :: deleterr.py :: deleterr : Log level set to DEBUG

deleterr.log

Writer/Producer Exclude on Sonarr Library causes crash

Once I add any value to writer, producer for the TV Library I experience a crash.

deleterr | Traceback (most recent call last):
deleterr | File "", line 198, in _run_module_as_main
deleterr | File "", line 88, in _run_code
deleterr | File "/app/app/deleterr.py", line 367, in
deleterr | main()
deleterr | File "/app/app/deleterr.py", line 364, in main
deleterr | Deleterr()
deleterr | File "/app/app/deleterr.py", line 37, in init
deleterr | self.process_sonarr()
deleterr | File "/app/app/deleterr.py", line 95, in process_sonarr
deleterr | for sonarr_show in self.process_library_rules(library, plex_library, all_show_data, show_activity, trakt_items):
deleterr | File "/app/app/deleterr.py", line 249, in process_library_rules
deleterr | if not self.is_movie_actionable(library_config, activity_data, media_data, trakt_movies, plex_media_item, last_watched_threshold, added_at_threshold, apply_last_watch_threshold_to_collections):
deleterr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
deleterr | File "/app/app/deleterr.py", line 305, in is_movie_actionable
deleterr | if producer.lower() in (g.tag.lower() for g in plex_media_item.producers):
deleterr | ^^^^^^^^^^^^^^^^^^^^^^^^^
deleterr | File "/usr/local/lib/python3.11/site-packages/plexapi/base.py", line 516, in getattribute
deleterr | value = super(PlexPartialObject, self).getattribute(attr)
deleterr | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
deleterr | AttributeError: 'Show' object has no attribute 'producers'
deleterr exited with code 0

Plex SSL

Discussed in #68

Originally posted by Lockie85 February 17, 2024
Hey,

My Plex server only allows secure connections (SSL / HTTPS) which looks to be causing issues with connecting deleterr to plex as I'm getting the following error:

2024-02-17 16:48:20 - INFO :: deleterr.py :: deleterr : Running version 
2024-02-17 16:48:20 - INFO :: deleterr.py :: deleterr : Log level set to DEBUG
2024-02-17 16:48:20 - DEBUG :: config.py :: deleterr : Loading configuration from /config/settings.yaml
2024-02-17 16:48:20 - INFO :: config.py :: deleterr : Running in dry-run mode, no changes will be made.
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 467, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 1096, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.12/site-packages/urllib3/connection.py", line 642, in connect
    sock_and_verified = _ssl_wrap_socket_and_match_hostname(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connection.py", line 782, in _ssl_wrap_socket_and_match_hostname
    ssl_sock = ssl_wrap_socket(
               ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/ssl_.py", line 470, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/ssl_.py", line 514, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 1046, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.12/ssl.py", line 1317, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '192.168.5.2'. (_ssl.c:1000)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 790, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 491, in _make_request
    raise new_e
urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '192.168.5.2'. (_ssl.c:1000)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 844, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/retry.py", line 515, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.5.2', port=32400): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '192.168.5.2'. (_ssl.c:1000)")))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/app/deleterr.py", line 703, in <module>
    main()
  File "/app/app/deleterr.py", line 699, in main
    Deleterr(config)
  File "/app/app/deleterr.py", line 36, in __init__
    self.plex = PlexServer(
                ^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/plexapi/server.py", line 116, in __init__
    data = self.query(self.key, timeout=self._timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/plexapi/server.py", line 759, in query
    response = method(url, headers=headers, timeout=timeout, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 517, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.5.2', port=32400): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '192.168.5.2'. (_ssl.c:1000)")))

Any idea on how I can resolve this problem? Many thanks

Support moving shows to an intermediate storage

A user has suggested a new feature where media files are moved to a different storage location after they reach a certain age. The media server re-indexes these files, so they are still accessible. A second time configuration then governs when these files are actually deleted. Additionally, there should be an interface that provides an overview of what media is currently live, in intermediate storage, or recently deleted.

Requirements:

  1. Implement Move Action Type

    • Create a new action type in Deleterr to "move" files to a designated intermediate storage location.
  2. Two-Stage Deletion Process

    • Set up two time-based conditions: one for moving to intermediate storage and one for deletion.
  3. Re-Index Media After Move

    • Ensure the media server can re-index moved media so it remains accessible to users.
  4. Overview Interface

    • Develop an interface that lists media by its current stage: live, intermediate, or recently deleted.
  5. Update User Guide

    • Include instructions for setting up and using the intermediate storage feature.
  6. Optional Turn On/Off Feature

    • Allow users to enable or disable this feature from Deleterr settings.

deprecate interactive mode

Interactive mode adds too much code complexity for little benefit, I don't feel anyone is really using deleterr that way.

ValueError from Tautulli

Hi, i am getting this error when i am start the docker. I am want to use only radarr and my movies library. Tautulli, Plex, Radarr and Trakt is added. And it says at start "Got xxx Movies" from Radarr and Plex.

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/app/deleterr.py", line 676, in <module>
    main()
  File "/app/app/deleterr.py", line 672, in main
    Deleterr(config)
  File "/app/app/deleterr.py", line 56, in __init__
    self.process_radarr()
  File "/app/app/deleterr.py", line 217, in process_radarr
    movie_activity = self.tautulli.get_activity(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/modules/tautulli.py", line 49, in get_activity
    last_activity[metadata["guid"]] = self._prepare_activity_entry(
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/app/modules/tautulli.py", line 99, in _prepare_activity_entry
    "year": int(metadata["year"]),
            ^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: ''

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.