nix-configs

Personal NixOS and home-manager configuration files
Log | Files | Refs

tank-sort.nix (3439B)


      1 { pkgs, vars, ... }:
      2 
      3 let
      4   media-sort = pkgs.callPackage ../common/media-sort.nix {};
      5 
      6   tank-sort = pkgs.writeShellScriptBin "tank-sort" ''
      7 	set -euo pipefail  # Exit on any error
      8 
      9 	# variables
     10 	export PATH=/run/wrappers/bin:/run/current-system/sw/bin:$PATH
     11 	temp_mount="$(mktemp -d)"
     12 	rclone_remote="seedbox:"
     13 	extensions="mp4,m4v,mkv"
     14 	state_file="$HOME/.cache/tank-sort.cache"
     15 	destination_tvshows="/tank/media/videos/television"
     16 	template_tvshows="{{ .Name }}/{{ .Name }} S{{ printf \"%02d\" .Season }}E{{ printf \"%02d\" .Episode }}{{ if ne .ExtraEpisode -1 }}-{{ printf \"%02d\" .ExtraEpisode }}{{end}}.{{ .Ext }}"
     17 	destination_movies="/tank/media/videos/movies"
     18 	template_movies="{{ .Name }} ({{ .Year }})/{{ .Name }}.{{ .Ext }}"
     19 
     20 	# Cleanup function
     21 	cleanup() {
     22 	  echo "Cleaning up..."
     23 	  if [ -n "''${RCLONE_PID:-}" ]; then
     24 	    kill "$RCLONE_PID" 2>/dev/null || tru
     25 	    wait "$RCLONE_PID" 2>/dev/null || true
     26 	  fi
     27 	  if mountpoint -q "$temp_mount" 2>/dev/null; then
     28 		fusermount -uz "$temp_mount" 2>/dev/null || true
     29 	  fi
     30 	  if [ -d "$temp_mount" ]; then
     31 		rmdir "$temp_mount" 2>/dev/null || true
     32 	  fi
     33 	}
     34 	trap cleanup EXIT
     35 
     36 	# check for changes on remote
     37 	current_hash="$(${pkgs.rclone}/bin/rclone --config /home/${vars.user.username}/.config/rclone/rclone.conf lsjson "$rclone_remote" \
     38 	  --include "*.{''${extensions}}" \
     39 	  | ${pkgs.jq}/bin/jq -S '.[] | {Path, Size, ModTime}' \
     40 	  | sort \
     41 	  | sha256sum | cut -d' ' -f1)"
     42 	if [ -f "$state_file" ]; then
     43 	  previous_hash="$(cat "$state_file")"
     44 	else
     45 	  previous_hash=""
     46 	fi
     47 
     48 	if [ "$current_hash" = "$previous_hash" ]; then
     49 	  echo "No changes detected in remote. Exiting."
     50 	  exit 0
     51 	fi
     52 
     53 	echo "Changes detected. Proceeding..."
     54 
     55 	# mount remote
     56 	echo "Mounting rclone remote..."
     57 	${pkgs.rclone}/bin/rclone mount "$rclone_remote" "$temp_mount" --vfs-cache-mode writes &
     58 	${pkgs.rclone}/bin/rclone mount \
     59 	  "$rclone_remote" \
     60 	  "$temp_mount" \
     61 	  --vfs-cache-mode writes &
     62 	RCLONE_PID=$!
     63 
     64 	# Wait for mount to be ready
     65 	echo "Waiting for mount to be ready..."
     66 	mounted=0
     67 	for i in {1..30}; do
     68 	  if mountpoint -q "$temp_mount"; then
     69 	    mounted=1
     70 	    break
     71 	  fi
     72 	  sleep 1
     73 	done
     74 	if [ "$mounted" -eq 0 ]; then
     75 	  echo "ERROR: rclone mount never became available"
     76 	  exit 1
     77 	fi
     78 
     79 	# sorting process
     80 	echo "Starting media sort..."
     81 	${media-sort}/bin/media-sort \
     82 	  --action copy \
     83 	  --concurrency 1 \
     84 	  --accuracy-threshold 90 \
     85 	  --tv-dir "$destination_tvshows" \
     86 	  --movie-dir "$destination_movies" \
     87 	  --tv-template "$template_tvshows" \
     88 	  --movie-template "$template_movies" \
     89 	  --recursive \
     90 	  --overwrite-if-larger \
     91 	  --extensions "$extensions" \
     92 	  "$temp_mount"
     93 
     94     # update state file
     95     echo "$current_hash" > "$state_file"
     96 
     97 	# git tank logger
     98 	tank-log
     99 
    100 	echo "Media sort completed successfully"
    101   '';
    102 in {
    103   environment.systemPackages = [ tank-sort media-sort ];
    104 
    105   systemd.services.tank-sort = {
    106     description = "Sort media from rclone remote";
    107     serviceConfig = {
    108       Type = "oneshot";
    109       User = vars.user.username;
    110       ExecStart = "${tank-sort}/bin/tank-sort";
    111       Environment = [
    112         "PATH=/run/wrappers/bin:/run/current-system/sw/bin"
    113         "HOME=/home/${vars.user.username}"
    114         ];
    115     };
    116   };
    117 
    118   systemd.timers.tank-sort = {
    119     description = "Run tank-sort every 4 hours";
    120     wantedBy = [ "timers.target" ];
    121     timerConfig = {
    122       OnCalendar = "*-*-* 00/4:00:00";
    123       Persistent = true;
    124     };
    125   };
    126 }