fix: pyload and filebot

This commit is contained in:
2025-11-26 21:08:58 +01:00
parent 38bead3dc8
commit 3e2f46377e

View File

@@ -3,24 +3,59 @@ let
cids = import ./staticids.nix; cids = import ./staticids.nix;
networkPrefix = config.networkPrefix; networkPrefix = config.networkPrefix;
# FileBot post-processing script # FileBot post-processing script for PyLoad hooks
filebotScript = pkgs.writeShellScript "filebot-process.sh" '' filebotScript = pkgs.writeShellScript "filebot-process.sh" ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# FileBot AMC script for automated media organization # FileBot AMC script for automated media organization
# Arguments: $1 = download directory (passed by pyload) # Called by PyLoad's package_extracted hook with parameters:
# $1 = package_id
# $2 = package_name
# $3 = download_folder (actual path to extracted files)
# $4 = password (optional)
PACKAGE_ID="''${1:-}"
PACKAGE_NAME="''${2:-unknown}"
DOWNLOAD_DIR="''${3:-/downloads}"
PASSWORD="''${4:-}"
DOWNLOAD_DIR="''${1:-/downloads}"
OUTPUT_DIR="/multimedia" OUTPUT_DIR="/multimedia"
LOG_FILE="/var/lib/filebot/amc.log" LOG_FILE="/var/lib/pyload/filebot-amc.log"
EXCLUDE_LIST="/var/lib/filebot/amc-exclude-list.txt" EXCLUDE_LIST="/var/lib/pyload/filebot-exclude-list.txt"
# Ensure log directory exists # Ensure FileBot data directory exists
mkdir -p /var/lib/pyload/.local/share/filebot/data
mkdir -p "$(dirname "$LOG_FILE")" mkdir -p "$(dirname "$LOG_FILE")"
touch "$EXCLUDE_LIST" touch "$EXCLUDE_LIST"
echo "$(date): Starting FileBot processing for: $DOWNLOAD_DIR" >> "$LOG_FILE" # Install FileBot license if not already installed
if [ ! -f /var/lib/pyload/.local/share/filebot/data/.license ]; then
echo "$(date): Installing FileBot license..." >> "$LOG_FILE"
${pkgs.filebot}/bin/filebot --license /var/lib/pyload/filebot-license.psm || true
fi
echo "===========================================" >> "$LOG_FILE"
echo "$(date): PyLoad package extracted 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
if [ ! -d "$DOWNLOAD_DIR" ]; then
echo "$(date): Download directory does not exist: $DOWNLOAD_DIR" >> "$LOG_FILE"
exit 0
fi
# 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"
echo "$(date): Skipping FileBot processing" >> "$LOG_FILE"
exit 0
fi
echo "$(date): Starting FileBot processing" >> "$LOG_FILE"
# Run FileBot AMC script # Run FileBot AMC script
${pkgs.filebot}/bin/filebot \ ${pkgs.filebot}/bin/filebot \
@@ -37,12 +72,16 @@ let
ut_dir="$DOWNLOAD_DIR" \ ut_dir="$DOWNLOAD_DIR" \
ut_kind=multi \ ut_kind=multi \
clean=y \ clean=y \
skipExtract=y skipExtract=y || {
echo "$(date): FileBot processing failed with exit code $?" >> "$LOG_FILE"
exit 0 # Don't fail the hook even if FileBot fails
}
# Clean up empty directories # Clean up empty directories
find "$DOWNLOAD_DIR" -type d -empty -delete 2>/dev/null || true find "$DOWNLOAD_DIR" -type d -empty -delete 2>/dev/null || true
echo "$(date): FileBot processing completed" >> "$LOG_FILE" echo "$(date): FileBot processing completed successfully" >> "$LOG_FILE"
exit 0
''; '';
pyloadUser = { pyloadUser = {
@@ -51,6 +90,7 @@ let
group = "pyload"; group = "pyload";
home = "/var/lib/pyload"; home = "/var/lib/pyload";
createHome = true; createHome = true;
extraGroups = [ "jellyfin" ]; # Access to multimedia directories
}; };
pyloadGroup = { pyloadGroup = {
gid = cids.gids.pyload; gid = cids.gids.pyload;
@@ -67,26 +107,12 @@ let
jellyfinGroup = { jellyfinGroup = {
gid = cids.gids.jellyfin; gid = cids.gids.jellyfin;
}; };
filebotUser = {
isSystemUser = true;
uid = cids.uids.filebot;
group = "filebot";
home = "/var/lib/filebot";
createHome = true;
extraGroups = [ "pyload" "jellyfin" ]; # Access to both download and media directories
};
filebotGroup = {
gid = cids.gids.filebot;
};
in in
{ {
users.users.pyload = pyloadUser; users.users.pyload = pyloadUser;
users.groups.pyload = pyloadGroup; users.groups.pyload = pyloadGroup;
users.users.jellyfin = jellyfinUser; users.users.jellyfin = jellyfinUser;
users.groups.jellyfin = jellyfinGroup; users.groups.jellyfin = jellyfinGroup;
users.users.filebot = filebotUser;
users.groups.filebot = filebotGroup;
# Create the directory structure on the host # Create the directory structure on the host
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
@@ -96,14 +122,19 @@ in
"d /var/lib/multimedia/tv-shows 0775 jellyfin jellyfin - -" "d /var/lib/multimedia/tv-shows 0775 jellyfin jellyfin - -"
"d /var/lib/multimedia/music 0755 jellyfin jellyfin - -" "d /var/lib/multimedia/music 0755 jellyfin jellyfin - -"
"d /var/lib/jellyfin 0755 jellyfin jellyfin - -" "d /var/lib/jellyfin 0755 jellyfin jellyfin - -"
"d /var/lib/filebot 0755 filebot filebot - -"
# PyLoad hook scripts directory
"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}"
]; ];
# FileBot license secret # FileBot license secret
sops.secrets.filebot-license = { sops.secrets.filebot-license = {
mode = "0440"; mode = "0440";
owner = config.users.users.root.name; owner = "pyload";
group = config.users.groups.root.name; group = "pyload";
}; };
containers.pyload = { containers.pyload = {
@@ -155,11 +186,7 @@ in
hostPath = "/var/lib/multimedia"; hostPath = "/var/lib/multimedia";
isReadOnly = false; isReadOnly = false;
}; };
"/var/lib/filebot" = { "/var/lib/pyload/filebot-license.psm" = {
hostPath = "/var/lib/filebot";
isReadOnly = false;
};
"/var/lib/filebot/license.psm" = {
hostPath = config.sops.secrets.filebot-license.path; hostPath = config.sops.secrets.filebot-license.path;
isReadOnly = true; isReadOnly = true;
}; };
@@ -247,6 +274,10 @@ in
# Disable SSL certificate verification # Disable SSL certificate verification
PYLOAD__GENERAL__SSL_VERIFY = "0"; PYLOAD__GENERAL__SSL_VERIFY = "0";
# Download speed limiting (150 Mbit/s = 19200 KiB/s)
PYLOAD__DOWNLOAD__LIMIT_SPEED = "1";
PYLOAD__DOWNLOAD__MAX_SPEED = "19200";
# Enable ExtractArchive plugin # Enable ExtractArchive plugin
PYLOAD__EXTRACTARCHIVE__ENABLED = "1"; PYLOAD__EXTRACTARCHIVE__ENABLED = "1";
PYLOAD__EXTRACTARCHIVE__DELETE = "1"; PYLOAD__EXTRACTARCHIVE__DELETE = "1";
@@ -254,6 +285,10 @@ in
PYLOAD__EXTRACTARCHIVE__REPAIR = "1"; PYLOAD__EXTRACTARCHIVE__REPAIR = "1";
PYLOAD__EXTRACTARCHIVE__RECURSIVE = "1"; PYLOAD__EXTRACTARCHIVE__RECURSIVE = "1";
PYLOAD__EXTRACTARCHIVE__FULLPATH = "1"; PYLOAD__EXTRACTARCHIVE__FULLPATH = "1";
# Enable ExternalScripts plugin for hooks
PYLOAD__EXTERNALSCRIPTS__ENABLED = "1";
PYLOAD__EXTERNALSCRIPTS__UNLOCK = "1"; # Run hooks asynchronously
}; };
# Bind-mount DNS configuration files into the chroot # Bind-mount DNS configuration files into the chroot
@@ -265,27 +300,8 @@ in
"/etc/ssl" "/etc/ssl"
"/etc/static/ssl" "/etc/static/ssl"
]; ];
}; # Bind mount multimedia directory as writable for FileBot hook scripts
}; BindPaths = [ "/multimedia" ];
# FileBot processing service
systemd.services.filebot-process = {
description = "FileBot media file processing";
serviceConfig = {
Type = "oneshot";
User = "filebot";
Group = "filebot";
ExecStart = "${filebotScript}";
};
};
# Watch for completed downloads and trigger FileBot
systemd.paths.filebot-watch = {
description = "Watch for completed downloads";
wantedBy = [ "multi-user.target" ];
pathConfig = {
PathModified = "/downloads";
Unit = "filebot-process.service";
}; };
}; };
@@ -297,8 +313,6 @@ in
users.groups.pyload = pyloadGroup; users.groups.pyload = pyloadGroup;
users.users.jellyfin = jellyfinUser; users.users.jellyfin = jellyfinUser;
users.groups.jellyfin = jellyfinGroup; users.groups.jellyfin = jellyfinGroup;
users.users.filebot = filebotUser;
users.groups.filebot = filebotGroup;
system.stateVersion = "24.05"; system.stateVersion = "24.05";
}; };