Schaka / janitorr

Cleans your Radarr, Sonarr, Jellyseerr and Jellyfin before you run out of space
GNU General Public License v3.0
313 stars 7 forks source link

`leaving-soon` directories getting wiped #42

Closed qkevinto closed 4 months ago

qkevinto commented 4 months ago

It appears as though I'm experiencing an issue similar to that mentioned in #36, although I am on latest/v1.4.0 and it would appear that the issue should've been fixed based on updates in said issue but perhaps my issue is something else, a user/configuration error or a misunderstanding of how janitorr functions.

The logs seem to indicate that symlinks were created but after janitorr runs all that remains is an empty leaving-soon directory.

My configuration and logs are as follows:

docker-compose.yaml: I have tried explicitly using the v1.4.0 tag as well to ensure it is actually pulling latest

version: '3'

services:
  janitorr:
    container_name: janitorr
    image: ghcr.io/schaka/janitorr:latest
    volumes:
      - /root/config:/config
      - /mnt/data:/mnt/data

application.yaml:

logging:
  level:
    com.github.schaka: TRACE

server:
  port: 8978

# File system access (same mapping as Sonarr, Radarr and Jellyfin) is required to delete TV shows by season and create "Leaving Soon" collections in Jellyfin
# Currently, Jellyfin does not support an easy way to add only a few seasons or movies to a collection, we need access to temporary symlinks
# Additionally, checks to prevent deletion on currently still seeding media currently require file system access as well
file-system:
  access: true 
  validate-seeding: true # validates seeding by checking if the original file exists and skips deletion - turning this off will send a delete to the *arrs even if a torrent may still be active
  leaving-soon-dir: "/mnt/data/media/leaving-soon" # A directory this container can write to and Jellyfin can find under the same path - this will contain new folders with symlinks to files for Jellyfin's "Leaving Soon" collections
  from-scratch: false # Clean up entire "Leaving Soon" directory and rebuild from scratch - this can help with clearing orphaned data - turning this off can save resources (less writes to drive)
  free-space-check-dir: "/mnt/data" # This is the default directory Janitorr uses to check how much space is left on your drives. By default, it checks the entire root - you may point it at a specific folder

application:
  dry-run: true 
  whole-tv-show: false # activating this will treat as a whole show as recently download/watched from a single episode, rather than that episode's season - shows will be deleted as a whole
  whole-show-seeding-check: false # Turning this off, disables the seeding check entirely if whole-tv-show is enabled. Activating this check will keep a whole TV show if any season is still seeding (requires file access).
  leaving-soon: 14d # 14 days before a movie is deleted, it gets added to a "Leaving Soon" type collection (i.e. movies that are 76 to 89 days old)
  exclusion-tag: "janitorr_keep" # Set this tag to your movies or TV shows in the *arrs to exclude media from being cleaned up

  media-deletion:
    enabled: true
    movie-expiration:
      # Percentage of free disk space to expiration time - if the highest given number is not reached, nothing will be deleted
      # If filesystem access is not given, disk percentage can't be determined. As a result, Janitorr will always choose the largest expiration time.
      25: 14d # 2 weeks
      50: 30d # 1 month      
      100: 90d # 3 months
    season-expiration:
      25: 14d # 2 weeks
      50: 30d # 1 month
      100: 90d # 3 months

  tag-based-deletion:
    enabled: true
    minimum-free-disk-percent: 100
    schedules:
      - tag: 5 - demo
        expiration: 30d
      - tag: 10 - demo
        expiration: 7d
clients:
  sonarr:
    enabled: true
    url: "http://192.168.1.205:8989"
    api-key: "xxxxxxxxxxxxx"
    delete-empty-shows: true # If a show that was "touched" by Janitorr contains no files and has no monitored seasons at all, it will get deleted as part of orphan cleanup
  radarr:
    enabled: true
    url: "http://192.168.1.117:7878"
    api-key: "xxxxxxxxxxxxx"

  ## You can only choose one out of Jellyfin or Emby.
  ## User login is only needed if deletion is enabled.
  jellyfin:
    enabled: true
    url: "http://192.168.1.185:8096"
    api-key: "xxxxxxxxxxxxx"
    username: janitorr
    password: "xxxxxxxxxxxxx"
    delete: true # Jellyfin setup is required for JellyStat. However, if you don't want Janitorr to send delete requests to the Jellyfin API, disable it here

  ## You can only choose one out of Jellyfin or Emby. Emby support is secondary.
  ## User login is only needed if deletion is enabled.
  emby:
    enabled: false
    url: "http://localhost:8096"
    api-key: "4da8d93992804489ba2d1f0e31b8316c"
    username: Janitorr
    password: janitorr
    delete: true # Emby setup is required for JellyStat. However, if you don't want Janitorr to send delete requests to the Emby API, disable it here
  jellyseerr:
    enabled: true
    url: "http://192.168.1.162:5055"
    api-key: "xxxxxxxxxxxxx"
    match-server: false # Enable if you have several Radarr/Sonarr instances set up in Jellyseerr. Janitorr will match them by the host+port supplied in their respective config settings.
  jellystat:
    enabled: true
    whole-tv-show: false # Enabling this will make Jellystat consider TV shows as a whole if any episode of any season has been watched
    url: "http://192.168.1.20:3000"
    api-key: "xxxxxxxxxxxxx"

logs: I've truncated some similar events just to keep things shorter

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.4)

2024-06-03T15:11:26.264Z  INFO 1 --- [           main] c.g.s.janitorr.JanitorrApplicationKt     : Starting JanitorrApplicationKt using Java 21.0.3 with PID 1 (/app/classes started by root in /)
2024-06-03T15:11:26.267Z DEBUG 1 --- [           main] c.g.s.janitorr.JanitorrApplicationKt     : Running with Spring Boot v3.2.4, Spring v6.1.5
2024-06-03T15:11:26.272Z  INFO 1 --- [           main] c.g.s.janitorr.JanitorrApplicationKt     : No active profile set, falling back to 1 default profile: "default"
2024-06-03T15:11:28.151Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8978 (http)
2024-06-03T15:11:28.163Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-06-03T15:11:28.163Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.19]
2024-06-03T15:11:28.214Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-06-03T15:11:28.216Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1814 ms
2024-06-03T15:11:29.426Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8978 (http) with context path ''
2024-06-03T15:11:29.443Z  INFO 1 --- [           main] c.g.s.janitorr.JanitorrApplicationKt     : Started JanitorrApplicationKt in 3.766 seconds (process running for 4.145)
2024-06-03T15:11:30.444Z DEBUG 1 --- [   scheduling-1] c.g.s.j.jellystat.JellystatRestService   : Updating history - user some-user watched some-other-episode at 2024-05-30T15:12:16.847Z
...
2024-06-03T15:11:30.580Z TRACE 1 --- [   scheduling-1] c.g.s.j.mediaserver.MediaServerService   : Season folder - Source: /mnt/data/media/tv/some-show/Season 03, Target: /mnt/data/media/leaving-soon/tv/some-show/Season 03
2024-06-03T15:11:30.584Z TRACE 1 --- [   scheduling-1] c.g.s.j.mediaserver.MediaServerService   : Creating season folder /mnt/data/media/leaving-soon/tv/some-show/Season 03
2024-06-03T15:11:30.597Z DEBUG 1 --- [   scheduling-1] c.g.s.j.mediaserver.MediaServerService   : Creating episode link from /mnt/data/media/tv/some-show/Season 03/some-show - S03E06 - some-episode.mkv to /mnt/data/media/leaving-soon/tv/some-show/Season 03/some-show - S03E06 - some-episode.mkv
...
2024-06-03T15:11:30.625Z  INFO 1 --- [   scheduling-1] c.g.s.j.s.sonarr.SonarrRestService       : Dry run - not deleting any TV shows without files or monitoring
2024-06-03T15:11:30.911Z DEBUG 1 --- [   scheduling-1] c.g.s.j.jellystat.JellystatRestService   : Updating history - user some-user watched some-movie at 2024-06-01T13:32:23.574Z
2024-06-03T15:11:30.937Z TRACE 1 --- [   scheduling-1] c.g.s.j.mediaserver.MediaServerService   : Movie folder - PathStructure(sourceFolder=/mnt/data/media/movies/some-movie, sourceFile=/mnt/data/media/movies/some-movie/some-movie.mkv, targetFolder=/mnt/data/media/leaving-soon/movies/some-movie, targetFile=/mnt/data/media/leaving-soon/movies/some-movie/some-movie.mkv)
2024-06-03T15:11:30.944Z DEBUG 1 --- [   scheduling-1] c.g.s.j.mediaserver.MediaServerService   : Creating movie link from /mnt/data/media/movies/some-movie/some-movie.mkv to /mnt/data/media/leaving-soon/movies/some-movie/some-movie.mkv
...
2024-06-03T15:11:31.026Z DEBUG 1 --- [   scheduling-1] c.g.s.j.cleanup.TagBasedCleanupSchedule  : Deleting TV shows and movies with tag: TagDeleteSchedule(tag=5 - demo, expiration=PT720H)
2024-06-03T15:11:31.553Z  INFO 1 --- [   scheduling-1] c.g.s.j.s.sonarr.SonarrRestService       : Dry run - not deleting any TV shows without files or monitoring
2024-06-03T15:11:31.767Z DEBUG 1 --- [   scheduling-1] c.g.s.j.cleanup.TagBasedCleanupSchedule  : Deleting TV shows and movies with tag: TagDeleteSchedule(tag=10 - demo, expiration=PT168H)
2024-06-03T15:11:31.812Z  INFO 1 --- [   scheduling-1] c.g.s.j.s.sonarr.SonarrRestService        : Dry run - not deleting any TV shows without files or monitoring

Thank you for the help!

Schaka commented 4 months ago

I think it's the tag based deletion. If you turn that off entirely, does it work correctly? I think I need to consider a way to let both jobs know about the other so they don't empty the directories if they don't find any deleteables themselves.

Either that or they need to run on different sub-folders.

qkevinto commented 4 months ago

That was it! Disabling tag-based-deletion, restarted the container and now the movies and tv directories are present with all the relevant symlinks. Thank you for that!

Schaka commented 4 months ago

Fixed in v1.4.1 You can use both cleanups again after updating.