From 44f5b0d162975ea9af8d49cee242afed64154800 Mon Sep 17 00:00:00 2001 From: Iristyle Date: Sun, 4 Nov 2012 12:29:07 -0500 Subject: [PATCH] CouchPotato Installs CouchPotato from source - Registers as Windows Service - Configures SABNzbd+ - Configures alternative post-processing script --- CouchPotato/CouchPotato-logo.png | Bin 0 -> 5838 bytes CouchPotato/CouchPotato.nuspec | 45 +++ CouchPotato/tools/chocolateyInstall.ps1 | 347 ++++++++++++++++++++++ CouchPotato/tools/chocolateyUninstall.ps1 | 134 +++++++++ 4 files changed, 526 insertions(+) create mode 100644 CouchPotato/CouchPotato-logo.png create mode 100644 CouchPotato/CouchPotato.nuspec create mode 100644 CouchPotato/tools/chocolateyInstall.ps1 create mode 100644 CouchPotato/tools/chocolateyUninstall.ps1 diff --git a/CouchPotato/CouchPotato-logo.png b/CouchPotato/CouchPotato-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e6d9f313dc65d7b736c6c4e1cc39461fe984f1 GIT binary patch literal 5838 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 Y0ErLWlyz8-y#N3J07*qoM6N<$fk literal 0 HcmV?d00001 diff --git a/CouchPotato/CouchPotato.nuspec b/CouchPotato/CouchPotato.nuspec new file mode 100644 index 0000000..e85fbe5 --- /dev/null +++ b/CouchPotato/CouchPotato.nuspec @@ -0,0 +1,45 @@ + + + + CouchPotato + CouchPotato automatic NZB downloader + 2012.11.04 + RuudBurger + Ethan Brown + CouchPotato (CP) is an automatic NZB and torrent downloader. You can keep a "movies I want"-list and it will search for NZBs/torrents of these movies every X hours. Once a movie is found, it will send it to SABnzbd or download the torrent to a specified directory. + CouchPotato is an automatic NZB and torrent downloader. +You can keep a "want to watch"-list and it will search for NZBs/torrents of these items every X hours. Once a correct release is found, matching the correct quality, it will send it to SABnzbd or download the .nzb or .torrent to a specified directory. + + This package performs a number of normally quite painful / tedious tasks + - Installs SABnzbd+ (compiled version) + - Installs Python + - Installs PyWin32 + - Git clones the CouchPotato source to site-packages + - Configures Git within CouchPotato to auto-update + - Configures for XBMC metadata + - Configures XMBC notifications - to port 9090 as SABnzbd+ uses 8080 + - Configures CouchPotato to send NZBs to SABnzbd+ using API key + - Configures CouchPotato to run as a Windows service + - Configured alternate sabToCouchPotato.py SABnzbd+ post-processing scripts + + https://couchpota.to/ + CouchPotato Python Usenet NZB torrent + https://github.com/RuudBurger/CouchPotatoServer/blob/master/license.txt + false + https://github.com/Iristyle/ChocolateyPackages/raw/master/CouchPotato/CouchPotato-logo.png + + + + + + + + + + + + + + + + diff --git a/CouchPotato/tools/chocolateyInstall.ps1 b/CouchPotato/tools/chocolateyInstall.ps1 new file mode 100644 index 0000000..e794cb9 --- /dev/null +++ b/CouchPotato/tools/chocolateyInstall.ps1 @@ -0,0 +1,347 @@ +$package = 'CouchPotato' + +try { + + function Get-CurrentDirectory + { + $thisName = $MyInvocation.MyCommand.Name + [IO.Path]::GetDirectoryName((Get-Content function:$thisName).File) + } + + . (Join-Path (Get-CurrentDirectory) 'Get-IniContent.ps1') + . (Join-Path (Get-CurrentDirectory) 'Out-IniFile.ps1') + . (Join-Path (Get-CurrentDirectory) 'WaitForSuccess.ps1') + + #simulate the unix command for finding things in path + #http://stackoverflow.com/questions/63805/equivalent-of-nix-which-command-in-powershell + function Which([string]$cmd) + { + Get-Command -ErrorAction "SilentlyContinue" $cmd | + Select -ExpandProperty Definition + } + + $couchPotatoRunning = { + $service = Get-Service 'CouchPotato' -ErrorAction SilentlyContinue + return ($service -and ($service.Status -eq 'Running')) + } + $couchPotatoServing = { + $pingUrl = 'http://localhost:5050/docs/' + try + { + (New-Object Net.WebClient).DownloadString($pingUrl) + return $true + } + catch {} + + return $false + } + + # Use PYTHONHOME if it exists, or fallback to 'Where' to search PATH + if ($Env:PYTHONHOME) { $localPython = Join-Path $Env:PYTHONHOME 'python.exe' } + + if (!$Env:PYTHONHOME -or !(Test-Path $localPython)) + { $localPython = Which python.exe } + + if (!(Test-Path $localPython)) + { + Write-ChocolateyFailure 'CouchPotato requires a Python runtime to install' + return + } + + $pythonRoot = Split-Path $localPython + + # as we're running a service as SYSTEM, Machine needs python in PATH + # TODO: Bug in Install-ChocolateyPath won't add to MACHINE if already in USER + $setMachinePathScript = @" + `$vars = [Environment]::GetEnvironmentVariable('PATH', 'Machine') -split ';'; + if (!(`$vars -contains '$pythonRoot')) { `$vars += '$pythonRoot' }; + [Environment]::SetEnvironmentVariable('PATH', (`$vars -join ';'), 'Machine'); + [Environment]::SetEnvironmentVariable('PYTHONHOME', '$pythonRoot', 'Machine'); +"@ + + Start-ChocolateyProcessAsAdmin $setMachinePathScript + + $sitePackages = (Join-Path (Join-Path $pythonRoot 'Lib') 'site-packages') + if (!(Test-Path $sitePackages)) + { + Write-ChocolateyFailure 'Could not find Python site-packages directory' + return + } + + # grab the latest sources if not present + Push-Location $sitePackages + $git = Which git + $couchPotatoPath = (Join-Path $sitePackages 'CouchPotatoServer') + $couchPotatoEmpty = $true + if (Test-Path $couchPotatoPath) + { + $files = Get-ChildItem $couchPotatoPath -Recurse -ErrorAction SilentlyContinue + $couchPotatoEmpty = ($files.Count -eq 0) + } + if (!$couchPotatoEmpty) + { + Write-ChocolateySuccess 'CouchPotato already installed!' + return + } + else + { + Write-Host 'Cloning CouchPotato source from GitHub' + &git clone https://github.com/RuudBurger/CouchPotatoServer.git + } + + # Read SABNzbd+ config file to find scripts directory + $sabDataPath = Join-Path $Env:LOCALAPPDATA 'sabnzbd' + $sabIniPath = Join-Path $sabDataPath 'sabnzbd.ini' + if (Test-Path $sabIniPath) + { + Write-Host "Reading SABnzbd+ config file at $sabIniPath" + $sabConfig = Get-IniContent -Path $sabIniPath + + # 3 options - missing script_dir, script_dir set to "", or configured script_dir + if (!$sabConfig.misc.script_dir -or ` + ($sabConfig.misc.script_dir -eq "`"`"")) + { + $scriptDir = (Join-Path $sabDataPath 'scripts') + Write-Host "Configured SABnzbd+ script_dir to $scriptDir" + $sabConfig.misc.script_dir = $scriptDir + $sabConfig | Out-IniFile -FilePath $sabIniPath -Force -Encoding UTF8 + } + + if (!(Test-Path $sabConfig.misc.script_dir)) + { + New-Item -Path $sabConfig.misc.script_dir -Type Directory | Out-Null + } + + # To use alternate CouchPotato script, requires modified SickBeard bits + # copy and configure autoprocessing scripts in SABNzbd+ scripts directory + Write-Host "Copying CouchPotato post-processing scripts to SABnzbd+" + Get-ChildItem (Get-CurrentDirectory) -Filter '*.py' | + # overwrite SickBeard scripts if they exist + Copy-Item -Destination $sabConfig.misc.script_dir -Force + + if (!$sabconfig.categories.movies) + { + Write-Host "Configuring movies category inside SABnzbd+" + $movies = New-Object Collections.Specialized.OrderedDictionary + $movies.priority = 0; + $movies.pp = 3; # Download + Unpack +Repair +Delete + $movies.name = 'movies'; + $movies.script = 'sabToCouchPotato.py'; + $movies.newzbin = ''; + $movies.dir = 'movies'; + $sabconfig.categories.movies = $movies + } + + if (([string]::IsNullOrEmpty($sabconfig.categories.movies.script)) -or ` + ($sabconfig.categories.movies.script -ieq 'None') -or + ($sabconfig.categories.movies.script -ieq "`"`"")) + { + $sabconfig.categories.movies.script = 'sabToCouchPotato.py' + } + + # allows failed post processing of empty files (out of retention, etc) + $sabConfig.misc.empty_postproc = 1 + + Write-Host 'Configured movies category in SABnzbd+' + $sabConfig | Out-IniFile -FilePath $sabIniPath -Force -Encoding UTF8 + } + + # regardless of sabnzbd+ install status, .PY should be executable + if (($ENV:PATHEXT -split ';') -inotcontains '.PY') + { + Write-Host 'Adding .PY to PATHEXT' + $ENV:PATHEXT += ';.PY' + [Environment]::SetEnvironmentVariable('PATHEXT', $ENV:PATHEXT, 'Machine') + } + + # find resource kit tools and configure CouchPotato as a service + # http://htpcbuild.com/htpc-software/sickbeard/sickbeard-service/ + # http://stackoverflow.com/questions/32404/can-i-run-a-python-script-as-a-service-in-windows-how + $resourceKit = ${Env:ProgramFiles(x86)}, $Env:ProgramFiles | + % { Join-Path (Join-Path $_ 'Windows Resource Kits') 'Tools' } | + ? { Test-Path $_ } | + Select -First 1 + + if ($resourceKit) + { + Write-Host "Found resource kit - registering CouchPotato as a service" + Push-Location $resourceKit + $srvAny = Join-Path $resourceKit 'srvany.exe' + .\instsrv CouchPotato $srvany | Out-Null + + # Set-Service cmdlet doesn't have depend OR delayed start :( + Write-Host "Configuring service delayed auto with Tcpip dependency" + sc.exe config CouchPotato depend= Tcpip + sc.exe config CouchPotato start= delayed-auto + Pop-Location + + New-Item HKLM:\SYSTEM\CurrentControlSet\Services -Name CouchPotato ` + -ErrorAction SilentlyContinue | Out-Null + New-Item HKLM:\SYSTEM\CurrentControlSet\Services\CouchPotato ` + -Name Parameters -ErrorAction SilentlyContinue | Out-Null + $couchPotatoParams = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\CouchPotato\Parameters + New-ItemProperty -Path $couchPotatoParams.PSPath -PropertyType String ` + -Name 'AppDirectory' -Value $pythonRoot -Force | Out-Null + $pythonW = (Join-Path $pythonRoot 'pythonw.exe') + New-ItemProperty -Path $couchPotatoParams.PSPath -PropertyType String ` + -Name 'Application' -Value $pythonW -Force | Out-Null + $startCouchPotato = (Join-Path $couchPotatoPath 'CouchPotato.py') + New-ItemProperty -Path $couchPotatoParams.PSPath -PropertyType String ` + -Name 'AppParameters' -Value $startCouchPotato -Force | Out-Null + + Start-Service CouchPotato + + $sysProfile = Join-Path 'config' 'systemprofile' + $roamingData = Join-Path $sysProfile 'AppData\Roaming' + + # config files are created on first start-up + $configPath = (Join-Path ([Environment]::GetFolderPath('System')) $roamingData), + # must handle SYSWOW64 on x64 (works inside both 32-bit and 64-bit host procs) + (Join-Path ([Environment]::GetFolderPath('SystemX86')) $roamingData) | + Select -Unique | + ? { Test-Path $_ } | + % { Join-Path $_ 'CouchPotato\settings.conf' } | + Select -First 1 + Write-Host "Expecting configuration file at $configPath" + + # to start hacking settings.conf the service needs to be up, settings.conf needs + # to exist, and CouchPotato must respond to requests (settings.conf is complete) + $waitOnConfig = { + if (!(&$couchPotatoRunning)) { return $false } + if (!(Test-Path $configPath)) { return $false } + return &$couchPotatoServing + } + + if (WaitForSuccess $waitOnConfig 20 'CouchPotato to start and create config') + { + Write-Host 'CouchPotato started and configuration files created' + # an alternative to modifying conf directly is to use the API + # /api/KEY/settings + $couchPotatoConfig = Get-IniContent -Path $configPath + $couchPotatoApiKey = $couchPotatoConfig.core.api_key + + Write-Host 'Configuring Windows Firewall for the CouchPotato port' + # configure windows firewall + netsh advfirewall firewall delete rule name="CouchPotato" + # program="$pythonW" + $port = $couchPotatoConfig.core.port + netsh advfirewall firewall add rule name="CouchPotato" dir=in protocol=tcp localport=$port action=allow + + $couchPotatoConfig.core.launch_browser = 'False' + + # make sure autoupdate is turned on with a correct path to Git + $couchPotatoConfig.updater.notification = 'True' + $couchPotatoConfig.updater.enabled = 'True' + $couchPotatoConfig.updater.git_command = "`"$($git -replace '\\', '\\')`"" + $couchPotatoConfig.updater.automatic = 'True' + + $movieDownloads = Join-Path (Join-Path $sabDataPath 'Downloads') ` + $sabConfig.categories.movies.dir + + $couchPotatoConfig.manage.cleanup = 'True' + # TODO: once we can sniff out the XBMC directory, we can auto-config this + # $couchPotatoConfig.manage.enabled = 'False' + # $couchPotatoConfig.manage.library = '' + + # Write-Host "Using SABNzbd+ movies download directory, but the to must be configured" + $couchPotatoConfig.renamer.from = "`"$($movieDownloads -replace '\\', '\\')`"" + $couchPotatoConfig.renamer.enabled = 'True' + $couchPotatoConfig.renamer.cleanup = 'True' + $couchPotatoConfig.renamer.folder_name = ' []' + $couchPotatoConfig.renamer.move_leftover = 1 + # because we're using alternate post-processing script, don't auto-run this + # on a schedule + $couchPotatoConfig.renamer.run_every = 0 + + # configure for XBMC with default user / pass of xbmc / xbmc + $couchPotatoConfig.xbmc.enabled = 1 + $couchPotatoConfig.xbmc.meta_enabled = 'True' + $couchPotatoConfig.xbmc.meta_thumbnail = 'True' + $couchPotatoConfig.xbmc.meta_fanart = 'True' + $couchPotatoConfig.xbmc.meta_nfo = 'True' + $couchPotatoConfig.xbmc.host = 'localhost:9090' + $couchPotatoConfig.xbmc.username = 'xbmc' + $couchPotatoConfig.xbmc.password = 'xbmc' + + # configure CouchPotato to use SABNzbd + $couchPotatoConfig.sabnzbd.enabled = 1 + $couchPotatoConfig.sabnzbd.api_key = $sabConfig.misc.api_key + $couchPotatoConfig.sabnzbd.category = 'movies' + $couchPotatoConfig.sabnzbd.host = "localhost:$($sabConfig.misc.port)" + + $couchPotatoConfig | + Out-IniFile -File $configPath -Force -Encoding ASCII | + Out-Null + + $restartUrl = "http://localhost:$port/api/$couchPotatoApiKey/app.restart/" + try + { + Write-Host "Restarting CouchPotato using API to accept config" + (New-Object Net.WebClient).DownloadString($restartUrl) + } + catch + { + Write-Host "Error using API - restarting service manually" + Restart-Service CouchPotato + } + } + + # Using alternative CouchPotato renamer script like SickBeard + # https://couchpota.to/forum/showthread.php?tid=343 + # files at http://www.freefilehosting.net/autoprocessmediabuilds-win + # The main benefits to this script are: + # 1 less CPU usage (due to SABnzbd polling an regular disk scanning etc) + # 2 less hard disk scanning + # 3 ability to get hard disk to spin down when not downloading + # 4 the renamer is fired (on demand) + # 5 if you are using SABnzbd renaming this script will add to the manage list without using the renamer. + + $autoConfig = Join-Path $sabConfig.misc.script_dir 'autoProcessMovie.cfg' + if (!(Test-Path $autoConfig)) + { + # order shouldn't matter, but don't trust Python ;0 + $sbAuto = New-Object Collections.Specialized.OrderedDictionary + $sbAuto.host = $couchPotatoConfig.core.host -replace '0\.0\.0\.0', + 'localhost'; + $sbAuto.port = $couchPotatoConfig.core.port; + $sbAuto.username = $couchPotatoConfig.core.username; + $sbAuto.password = $couchPotatoConfig.core.password; + $sbAuto.ssl = 0; + $sbAuto.web_root = $couchPotatoConfig.core.url_base; + $sbAuto.apikey = $couchPotatoConfig.core.api_key + $sbAuto.delay = 60 # must be minimum of 60 seconds + $sbAuto.method = 'renamer' #or 'manage' + + @{ 'CouchPotato' = $sbAuto } | + Out-IniFile -FilePath $autoConfig -Encoding ASCII -Force + + Write-Host @" +CouchPotato SABNzbd+ post-processing scripts configured + If CouchPotato is reconfigured with a username or password or another + host or different API key then those same changes must be made to $configPath +"@ + } + + $url = ("http://localhost:$($sabConfig.misc.port)/api?mode=restart" + + "&apikey=$($sabConfig.misc.api_key)") + Write-Host "Restarting SABnzbd+ to accept configuration changes at $url" + (New-Object Net.WebClient).DownloadString($url) + + #wait up to 5 seconds for service to fire up + if (WaitForSuccess $couchPotatoServing 5 'CouchPotato to start') + { + #launch local default browser for additional config + $configUrl = "http://localhost:$($couchPotatoConfig.core.port)" + [Diagnostics.Process]::Start($configUrl) | Out-Null + } + + Write-Host "For use in other apps, CouchPotato API key: $couchPotatoApiKey" + + Pop-Location + } + + Write-ChocolateySuccess $package +} catch { + Write-ChocolateyFailure $package "$($_.Exception.Message)" + throw +} diff --git a/CouchPotato/tools/chocolateyUninstall.ps1 b/CouchPotato/tools/chocolateyUninstall.ps1 new file mode 100644 index 0000000..d03c273 --- /dev/null +++ b/CouchPotato/tools/chocolateyUninstall.ps1 @@ -0,0 +1,134 @@ +$package = 'CouchPotato' + +try +{ + function Get-CurrentDirectory + { + $thisName = $MyInvocation.MyCommand.Name + [IO.Path]::GetDirectoryName((Get-Content function:$thisName).File) + } + + # load INI parser + . (Join-Path (Get-CurrentDirectory) 'Get-IniContent.ps1') + . (Join-Path (Get-CurrentDirectory) 'Out-IniFile.ps1') + + #simulate the unix command for finding things in path + #http://stackoverflow.com/questions/63805/equivalent-of-nix-which-command-in-powershell + function Which([string]$cmd) + { + Get-Command -ErrorAction "SilentlyContinue" $cmd | + Select -ExpandProperty Definition + } + + Write-Host 'Deleting CouchPotato Windows Firewall config' + netsh advfirewall firewall delete rule name="CouchPotato" + + # check registry for path to CouchPotato + $servicePath = 'HKLM:\SYSTEM\CurrentControlSet\Services\CouchPotato\Parameters' + $installDir = Get-ItemProperty $servicePath -ErrorAction SilentlyContinue | + Select -ExpandProperty AppParameters + + if ($installDir) + { + $couchPotatoDir = Split-Path $installDir + $sitePackages = Split-Path $couchPotatoDir + Write-Host "Found CouchPotato service configuration directory of $couchPotatoDir" + } + # not found - do some guesswork + else + { + # Use PYTHONHOME if it exists, or fallback to 'Where' to search PATH + if ($Env:PYTHONHOME) { $localPython = Join-Path $Env:PYTHONHOME 'python.exe' } + + if (!$Env:PYTHONHOME -or !(Test-Path $localPython)) + { $localPython = Which python.exe } + + if (!(Test-Path $localPython)) + { + Write-Warning 'Could not find CouchPotato or Python!' + } + else + { + $pythonRoot = Split-Path $localPython + $sitePackages = (Join-Path (Join-Path $pythonRoot 'Lib') 'site-packages') + $couchPotatoDir = Join-Path $sitePackages 'CouchPotatoServer' + Write-Host "CouchPotato service configuration not found - assuming $couchPotatoDir" + } + } + + # delete the service and reg keys + if (Get-Service CouchPotato -ErrorAction SilentlyContinue) + { + Write-Host 'Deleting CouchPotato service' + Stop-Service CouchPotato + sc.exe delete CouchPotato + } + + # we found CouchPotato on disk, so delete all the files + if (Test-Path $couchPotatoDir) + { + Write-Host "Removing all files in $couchPotatoDir" + Remove-Item $couchPotatoDir -Recurse -Force -ErrorAction SilentlyContinue + if (Test-Path $couchPotatoDir) + { + Write-Warning "$couchPotatoDir must be deleted manually" + } + } + + $sysProfile = Join-Path 'config' 'systemprofile' + $couchPotatoData = Join-Path (Join-Path 'AppData' 'Roaming') 'CouchPotato' + $couchPotatoData = Join-Path $sysProfile $couchPotatoData + + # config files are created on first start-up + $configPath = (Join-Path ([Environment]::GetFolderPath('System')) $couchPotatoData), + # must handle SYSWOW64 on x64 (works inside both 32-bit and 64-bit host procs) + (Join-Path ([Environment]::GetFolderPath('SystemX86')) $couchPotatoData) | + Select -Unique | + % { + if (Test-Path $_) + { + Write-Warning "$_ data directory must be deleted manually" + } + } + + # Read SABNzbd+ config file to delete CouchPotato scripts if configured + $sabDataPath = Join-Path $Env:LOCALAPPDATA 'sabnzbd' + $sabIniPath = Join-Path $sabDataPath 'sabnzbd.ini' + if (Test-Path $sabIniPath) + { + Write-Host "Reading SABnzbd+ config file at $sabIniPath" + $sabConfig = Get-IniContent $sabIniPath + + $scriptsDir = $sabConfig.misc.script_dir + # found a legit scripts dir, so delete CouchPotato files + if ($scriptsDir -and ($scriptsDir -ne "`"`"") -and (Test-Path $scriptsDir)) + { + Write-Warning "SABnzbd+ post-processing scripts at $scriptsDir must be deleted manually" + } + + $movies = $sabconfig.categories.movies + if ($movies -and ($movies.script -eq 'sabToCouchPotato.py')) + { + Write-Host 'Removed sabToCouchPotato.py script from movies category inside SABnzbd+' + $movies.script = 'None' + $sabConfig | Out-IniFile -FilePath $sabIniPath -Force -Encoding UTF8 + } + + Write-Host 'Restarting SABnzbd+ to accept configuration changes' + $url = ("http://localhost:$($sabConfig.misc.port)/api?mode=restart" + + "&apikey=$($sabConfig.misc.api_key)") + try + { + (New-Object Net.WebClient).DownloadString($url) + } + catch + { + Write-Host "SABNzbd+ not responding to restart request" + } + } + + Write-ChocolateySuccess $package +} catch { + Write-ChocolateyFailure $package "$($_.Exception.Message)" + throw +}