diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c64784b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM mcr.microsoft.com/powershell + +ENV SCHEDULE=60 + +VOLUME /tmp + +WORKDIR /data +ADD ["Invoke-QBTCleanarr.ps1", "/data/"] + +ENTRYPOINT ["pwsh", "-Command", "/data/Invoke-QBTCleanarr.ps1"] \ No newline at end of file diff --git a/Invoke-QBTCleanarr.ps1 b/Invoke-QBTCleanarr.ps1 index 13a4925..b3559c2 100644 --- a/Invoke-QBTCleanarr.ps1 +++ b/Invoke-QBTCleanarr.ps1 @@ -1,51 +1,88 @@ # Configuration -$qbittorrentUrl = 'http://localhost:8080' # Change if necessary -$username = 'your_username' -$password = 'your_password' -$excludedTrackers = @('tracker1.com', 'tracker2.com') +[int] $schedule = $ENV:SCHEDULE +[string] $qbtHost = $ENV:QBTHOST +[string] $qbtPort = $ENV:QBTPORT +[string] $qbtUser = $ENV:QBTUSER +[string] $qbtPassword = $ENV:QBTPASSWORD +[string] $notificationWebhookURL = $ENV:NOTIFICATIONWEBHOOKURL # Function to authenticate and get a session function Get-QBittorrentSession { - $session = New-Object System.Net.WebClient - $session.Headers.Add("Content-Type", "application/x-www-form-urlencoded") + $qbtHeaders = @{ + Referer = "https://$($qbtHost):$($qbtPort)" + } + $qbtBody = @{ + username = $qbtUser + password = $qbtPassword + } + $qbtSession = [Microsoft.PowerShell.Commands.WebRequestSession]::new() + $qbtResponse = Invoke-WebRequest -Uri "https://$($qbtHost):$($qbtPort)/api/v2/auth/login" -WebSession $qbtSession -Method POST -Headers $qbtHeaders -Body $qbtBody - # Authenticate - $session.UploadString("$qbittorrentUrl/api/v2/auth/login", "username=$username&password=$password") - return $session + return $qbtSession } # Function to get all torrents function Get-Torrents { param ( - [System.Net.WebClient]$session + [Microsoft.PowerShell.Commands.WebRequestSession]$session ) - $response = $session.DownloadString("$qbittorrentUrl/api/v2/torrents/info") - return $response | ConvertFrom-Json + $qbtResponse = Invoke-WebRequest -Uri "https://$($qbtHost):$($qbtPort)/api/v2/torrents/info" -WebSession $session -Method GET + return $qbtResponse.Content | ConvertFrom-Json } # Function to delete a torrent -function Delete-Torrent { +function Remove-Torrent { param ( - [System.Net.WebClient]$session, + [Microsoft.PowerShell.Commands.WebRequestSession]$session, [string]$hash ) - $session.UploadString("$qbittorrentUrl/api/v2/torrents/delete", "hashes=$hash") -} + $qbtHeaders = @{ + Referer = "https://$($qbtHost):$($qbtPort)" + } + $qbtBody = @{ + hashes = $hash + deleteFiles = 'true' + } + $qbtResponse = Invoke-WebRequest -Uri "https://$($qbtHost):$($qbtPort)/api/v2/torrents/delete" -WebSession $session -Method POST -Headers $qbtHeaders -Body $qbtBody -# Main script -$session = Get-QBittorrentSession -$torrents = Get-Torrents -session $session - -foreach ($torrent in $torrents) { - if ($torrent.state -eq 'completed') { - # Check if any of the excluded trackers are in the torrent's tracker list - $trackers = $torrent.trackers | ForEach-Object { $_.url } - if (-not ($trackers | Where-Object { $excludedTrackers -contains $_ })) { - # Delete the torrent - Delete-Torrent -session $session -hash $torrent.hash + if ($notificationWebhookURL) + { + $headers = @{ + "Content-Type"="application/json" } + $body = @{ + content="Removed torrent with hash $hash" + } + $json = $body | ConvertTo-Json + Invoke-WebRequest -URI $notificationWebhookURL -Method post -Body $json -Headers $headers } } -# Logout (optional, but good practice) -$session.UploadString("$qbittorrentUrl/api/v2/auth/logout", "") +while ($true) +{ + # Main script + $session = Get-QBittorrentSession + $torrents = Get-Torrents -session $session + + foreach ($torrent in $torrents) { + if ($torrent.state -eq 'uploading' -or $torrent.state -like "*UP") { + # Check if any of the excluded trackers are in the torrent's tracker list + if ($torrent.tracker -match "https?://([^/]+)") { + $trackers = $matches[1] + } else { + $trackers = @() + } + if (-not ($trackers | Where-Object { $excludedTrackers -contains $_ })) { + # Delete the torrent + Write-Host "Would delete: $($torrent.name)" + Remove-Torrent -session $session -hash $torrent.hash + } + } + } + + # Logout (optional, but good practice) + # $session.UploadString("$qbittorrentUrl/api/v2/auth/logout", "") + + Write-Host "Sleeping for $schedule minutes..." + Start-Sleep ($schedule * 60) +} diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..dcb8262 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,13 @@ +# SAMPLE DOCKER COMPOSE +services: + qbt-cleanarr: + container_name: qbt-cleanarr + image: docker.io/blinkfink182/qbt-cleanarr + environment: + - SCHEDULE=15 # OPTIONAL: time in minutes to wait between check, 60 is default + # BELOW ARE ALL REQUIRED + - QBTHOST=host.docker.internal # qbittorrent host + - QBTPORT=8787 # qbittorrent port + - QBTUSER=admin # qbittorrent webUI username + - QBTPASSWORD=adminpass # qbittorrent webUI password + - NOTIFICATIONWEBHOOKURL=https://discord.com/api/webhooks/ # discord notification wehook URL \ No newline at end of file