From 2eec46ce03d2c6b5665dc0448f968d8e11e61218 Mon Sep 17 00:00:00 2001 From: Kelly Thomas Reardon Date: Fri, 27 Dec 2024 16:06:18 -0600 Subject: [PATCH 1/2] Refactor qBittorrent script for improved authentication and torrent management --- Invoke-QBTCleanarr.ps1 | 51 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/Invoke-QBTCleanarr.ps1 b/Invoke-QBTCleanarr.ps1 index 13a4925..824f05a 100644 --- a/Invoke-QBTCleanarr.ps1 +++ b/Invoke-QBTCleanarr.ps1 @@ -1,35 +1,45 @@ # Configuration -$qbittorrentUrl = 'http://localhost:8080' # Change if necessary -$username = 'your_username' -$password = 'your_password' -$excludedTrackers = @('tracker1.com', 'tracker2.com') +$qbtHost = 'ktr.h4ck.me' +$qbtPort = '7878' +$qbtUser = 'kelly' +$qbtPassword = 'KjBWnJC;cabA^gFxcN]5' +$excludedTrackers = @( + 'digitalcore.club', + 'please.passthepopcorn.me:2710', + 'please.passthepopcorn.me' +) # 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 { param ( - [System.Net.WebClient]$session, + [Microsoft.PowerShell.Commands.WebRequestSession]$session, [string]$hash ) - $session.UploadString("$qbittorrentUrl/api/v2/torrents/delete", "hashes=$hash") + # $session.UploadString("$qbittorrentUrl/api/v2/torrents/delete", "hashes=$hash") } # Main script @@ -37,15 +47,20 @@ $session = Get-QBittorrentSession $torrents = Get-Torrents -session $session foreach ($torrent in $torrents) { - if ($torrent.state -eq 'completed') { + if ($torrent.state -eq 'uploading' -or $torrent.state -like "*UP") { # Check if any of the excluded trackers are in the torrent's tracker list - $trackers = $torrent.trackers | ForEach-Object { $_.url } + if ($torrent.tracker -match "https?://([^/]+)") { + $trackers = $matches[1] + } else { + $trackers = @() + } if (-not ($trackers | Where-Object { $excludedTrackers -contains $_ })) { # Delete the torrent - Delete-Torrent -session $session -hash $torrent.hash + Write-Host "Would delete: $($torrent.name)" + # Delete-Torrent -session $session -hash $torrent.hash } } } # Logout (optional, but good practice) -$session.UploadString("$qbittorrentUrl/api/v2/auth/logout", "") +# $session.UploadString("$qbittorrentUrl/api/v2/auth/logout", "") From a6b5717707137566ee53584dce351b4ab962d4dc Mon Sep 17 00:00:00 2001 From: Kelly Thomas Reardon Date: Fri, 27 Dec 2024 22:18:08 -0600 Subject: [PATCH 2/2] Add Docker support and environment variable configuration for qBittorrent script --- Dockerfile | 10 ++++++ Invoke-QBTCleanarr.ps1 | 80 +++++++++++++++++++++++++++--------------- docker-compose.yaml | 13 +++++++ 3 files changed, 74 insertions(+), 29 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yaml 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 824f05a..b3559c2 100644 --- a/Invoke-QBTCleanarr.ps1 +++ b/Invoke-QBTCleanarr.ps1 @@ -1,13 +1,10 @@ # Configuration -$qbtHost = 'ktr.h4ck.me' -$qbtPort = '7878' -$qbtUser = 'kelly' -$qbtPassword = 'KjBWnJC;cabA^gFxcN]5' -$excludedTrackers = @( - 'digitalcore.club', - 'please.passthepopcorn.me:2710', - 'please.passthepopcorn.me' -) +[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 { @@ -34,33 +31,58 @@ function Get-Torrents { } # Function to delete a torrent -function Delete-Torrent { +function Remove-Torrent { param ( [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 '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 ($notificationWebhookURL) + { + $headers = @{ + "Content-Type"="application/json" } - if (-not ($trackers | Where-Object { $excludedTrackers -contains $_ })) { - # Delete the torrent - Write-Host "Would delete: $($torrent.name)" - # Delete-Torrent -session $session -hash $torrent.hash + $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