diff --git a/hosts/nas/modules/filebot-process.nix b/hosts/nas/modules/filebot-process.nix index dd818e9..903a892 100644 --- a/hosts/nas/modules/filebot-process.nix +++ b/hosts/nas/modules/filebot-process.nix @@ -19,6 +19,7 @@ pkgs.writeShellScriptBin "filebot-process" '' OUTPUT_DIR="/var/lib/multimedia" LOG_FILE="/var/lib/pyload/filebot-amc.log" EXCLUDE_LIST="/var/lib/pyload/filebot-exclude-list.txt" + PASSWORD_FILE="/var/lib/pyload/extraction-passwords.txt" # Ensure FileBot data directory exists mkdir -p /var/lib/pyload/.local/share/filebot/data @@ -32,18 +33,114 @@ pkgs.writeShellScriptBin "filebot-process" '' fi echo "===========================================" >> "$LOG_FILE" - echo "$(date): PyLoad package extracted hook triggered" >> "$LOG_FILE" + echo "$(date): PyLoad package hook triggered" >> "$LOG_FILE" echo "Package ID: $PACKAGE_ID" >> "$LOG_FILE" echo "Package Name: $PACKAGE_NAME" >> "$LOG_FILE" echo "Download Directory: $DOWNLOAD_DIR" >> "$LOG_FILE" echo "===========================================" >> "$LOG_FILE" - # Check if download directory exists and has media files + # Check if download directory exists if [ ! -d "$DOWNLOAD_DIR" ]; then echo "$(date): Download directory does not exist: $DOWNLOAD_DIR" >> "$LOG_FILE" exit 0 fi + # --- Archive Extraction --- + + # Try extraction with passwords, then without + try_extract() { + local archive="$1" + local outdir + outdir="$(dirname "$archive")" + + # Try each password from file + if [ -f "$PASSWORD_FILE" ]; then + while IFS= read -r pass || [ -n "$pass" ]; do + [ -z "$pass" ] && continue + case "$archive" in + *.rar) ${pkgs.unrar}/bin/unrar x -p"$pass" -o+ "$archive" "$outdir/" >/dev/null 2>&1 && return 0 ;; + *.7z) ${pkgs.p7zip}/bin/7z x -p"$pass" -aoa -o"$outdir" "$archive" >/dev/null 2>&1 && return 0 ;; + *.zip) ${pkgs.p7zip}/bin/7z x -p"$pass" -aoa -o"$outdir" "$archive" >/dev/null 2>&1 && return 0 ;; + esac + done < "$PASSWORD_FILE" + fi + + # Try without password + case "$archive" in + *.rar) ${pkgs.unrar}/bin/unrar x -o+ "$archive" "$outdir/" >/dev/null 2>&1 && return 0 ;; + *.7z) ${pkgs.p7zip}/bin/7z x -aoa -o"$outdir" "$archive" >/dev/null 2>&1 && return 0 ;; + *.zip) ${pkgs.p7zip}/bin/7z x -aoa -o"$outdir" "$archive" >/dev/null 2>&1 && return 0 ;; + esac + return 1 + } + + # Delete all parts of a split RAR archive + delete_rar_parts() { + local first_part="$1" + local base dir + + dir="$(dirname "$first_part")" + # Extract base name: "foo.part1.rar" -> "foo", "foo.part01.rar" -> "foo" + base="$(basename "$first_part" | ${pkgs.gnused}/bin/sed -E 's/\.part[0-9]+\.rar$//')" + + # Delete all parts matching the pattern + find "$dir" -maxdepth 1 -type f -iname "''${base}.part*.rar" -delete + echo "$(date): Deleted all parts: ''${base}.part*.rar" >> "$LOG_FILE" + } + + # Extract archives in directory + extract_archives() { + local dir="$1" + local extracted=0 + + # 1. Handle split RAR archives (*.part1.rar or *.part01.rar - first part only) + while IFS= read -r -d "" archive; do + echo "$(date): Extracting split RAR: $archive" >> "$LOG_FILE" + if try_extract "$archive"; then + echo "$(date): Extraction successful" >> "$LOG_FILE" + delete_rar_parts "$archive" + extracted=1 + else + echo "$(date): Extraction FAILED: $archive" >> "$LOG_FILE" + fi + done < <(find "$dir" -type f \( -iname "*.part1.rar" -o -iname "*.part01.rar" \) -print0 2>/dev/null) + + # 2. Handle single RAR files (not part of split archive) + while IFS= read -r -d "" archive; do + echo "$(date): Extracting RAR: $archive" >> "$LOG_FILE" + if try_extract "$archive"; then + echo "$(date): Extraction successful, deleting: $archive" >> "$LOG_FILE" + rm -f "$archive" + extracted=1 + else + echo "$(date): Extraction FAILED: $archive" >> "$LOG_FILE" + fi + done < <(find "$dir" -type f -iname "*.rar" ! -iname "*.part*.rar" -print0 2>/dev/null) + + # 3. Handle 7z and zip archives + while IFS= read -r -d "" archive; do + echo "$(date): Extracting: $archive" >> "$LOG_FILE" + if try_extract "$archive"; then + echo "$(date): Extraction successful, deleting: $archive" >> "$LOG_FILE" + rm -f "$archive" + extracted=1 + else + echo "$(date): Extraction FAILED: $archive" >> "$LOG_FILE" + fi + done < <(find "$dir" -type f \( -iname "*.7z" -o -iname "*.zip" \) -print0 2>/dev/null) + + [ "$extracted" -eq 1 ] && return 0 || return 1 + } + + # Run extraction (loop to handle nested archives) + echo "$(date): Starting archive extraction..." >> "$LOG_FILE" + for i in 1 2 3; do + extract_archives "$DOWNLOAD_DIR" || break + done + echo "$(date): Archive extraction complete" >> "$LOG_FILE" + + # --- Media Processing --- + # Check if there are any video/media files to process if ! find "$DOWNLOAD_DIR" -type f \( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.m4v" -o -iname "*.mov" \) -print -quit | grep -q .; then echo "$(date): No media files found in: $DOWNLOAD_DIR" >> "$LOG_FILE" diff --git a/hosts/nas/modules/pyload.nix b/hosts/nas/modules/pyload.nix index 2c06f55..05a8152 100644 --- a/hosts/nas/modules/pyload.nix +++ b/hosts/nas/modules/pyload.nix @@ -22,11 +22,11 @@ in "d /var/lib/multimedia/music 0755 jellyfin jellyfin - -" "d /var/lib/multimedia/audiobooks 0775 jellyfin jellyfin - -" - # PyLoad hook scripts directory + # PyLoad hook scripts directory (package_finished triggers after download completes) "d /var/lib/pyload/config 0755 pyload pyload - -" "d /var/lib/pyload/config/scripts 0755 pyload pyload - -" - "d /var/lib/pyload/config/scripts/package_extracted 0755 pyload pyload - -" - "L+ /var/lib/pyload/config/scripts/package_extracted/filebot-process.sh - - - - ${filebotScript}/bin/filebot-process" + "d /var/lib/pyload/config/scripts/package_finished 0755 pyload pyload - -" + "L+ /var/lib/pyload/config/scripts/package_finished/filebot-process.sh - - - - ${filebotScript}/bin/filebot-process" ]; # FileBot license secret (only if secrets.yaml exists) @@ -37,7 +37,7 @@ in path = "/var/lib/pyload/filebot-license.psm"; }; - # Extraction passwords for pyload (one password per line) + # Extraction passwords for filebot-process script (one password per line) sops.secrets.pyload-extraction-passwords = { mode = "0440"; owner = "pyload"; @@ -78,14 +78,8 @@ in PYLOAD__DOWNLOAD__LIMIT_SPEED = "1"; PYLOAD__DOWNLOAD__MAX_SPEED = "19200"; - # Enable ExtractArchive plugin - PYLOAD__EXTRACTARCHIVE__ENABLED = "1"; - PYLOAD__EXTRACTARCHIVE__DELETE = "1"; - PYLOAD__EXTRACTARCHIVE__DELTOTRASH = "0"; - PYLOAD__EXTRACTARCHIVE__REPAIR = "1"; - PYLOAD__EXTRACTARCHIVE__RECURSIVE = "1"; - PYLOAD__EXTRACTARCHIVE__FULLPATH = "1"; - PYLOAD__EXTRACTARCHIVE__PASSWORDFILE = "/var/lib/pyload/extraction-passwords.txt"; + # Disable ExtractArchive plugin (extraction handled by filebot-process script) + PYLOAD__EXTRACTARCHIVE__ENABLED = "0"; # Enable ExternalScripts plugin for hooks PYLOAD__EXTERNALSCRIPTS__ENABLED = "1";