Merge pull request #11 from Iristyle/sickbeard

Sickbeard
This commit is contained in:
Ethan J. Brown
2012-10-22 12:25:49 -07:00
8 changed files with 214 additions and 51 deletions

View File

@@ -58,6 +58,7 @@ Note that if this is a first time install it will be necessary to configure SABn
Fix UI refresh issue when using Safari on iOS6 (Safari bug)</releaseNotes>
</metadata>
<files>
<file src="..\core\WaitForSuccess.ps1" target="tools" />
<file src="tools\**" target="tools" />
</files>
</package>

View File

@@ -87,7 +87,7 @@ try
if (!$upgrade)
{
#launch local default browser to configure
[Diagnostics.Process]::Start('http://localhost:8080')
[Diagnostics.Process]::Start('http://localhost:8080') | Out-Null
}
}
else

View File

@@ -0,0 +1,124 @@
$package = 'Sickbeard'
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 SickBeard Windows Firewall config'
netsh advfirewall firewall delete rule name="SickBeard"
# check registry for path to sickbeard
$servicePath = 'HKLM:\SYSTEM\CurrentControlSet\Services\SickBeard\Parameters'
$installDir = Get-ItemProperty $servicePath -ErrorAction SilentlyContinue |
Select -ExpandProperty AppParameters
if ($installDir)
{
$sickBeardDir = Split-Path $installDir
$sitePackages = Split-Path $sickBeardDir
Write-Host "Found SickBeard service configuration directory of $sickBeardDir"
}
# 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 SickBeard or Python!'
}
else
{
$pythonRoot = Split-Path $localPython
$sitePackages = (Join-Path (Join-Path $pythonRoot 'Lib') 'site-packages')
$sickBeardDir = Join-Path $sitePackages 'Sick-Beard'
Write-Host "SickBeard service configuration not found - assuming $sickBeardDir"
}
}
# delete the service and reg keys
if (Get-Service SickBeard -ErrorAction SilentlyContinue)
{
Write-Host 'Deleting SickBeard service'
Stop-Service SickBeard
sc.exe delete SickBeard
}
# we found Sickbeard on disk, so delete all the files
if (Test-Path $sickBeardDir)
{
Write-Host "Removing all files in $sickBeardDir"
Remove-Item $sickBeardDir -Recurse -Force -ErrorAction SilentlyContinue
if (Test-Path $sickBeardDir)
{
Write-Warning "$sickBeardDir must be deleted manually"
}
}
# Read SABNzbd+ config file to delete SickBeard 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 SickBeard files
if ($scriptsDir -and ($scriptsDir -ne "`"`"") -and (Test-Path $scriptsDir))
{
Write-Host "Found SABnzbd+ script_dir $scriptsDir"
$sickbeardScripts = 'autoProcessTV.cfg', 'autoProcessTV.cfg.sample',
'autoProcessTV.py', 'hellaToSickBeard.py', 'sabToSickBeard.py'
Write-Host "Removing SickBeard scripts $sickbeardScripts"
Get-ChildItem -Path $scriptsDir -Include $sickbeardScripts -Recurse |
Remove-Item -Force
}
$tv = $sabconfig.categories.tv
if ($tv -and ($tv.script -eq 'sabToSickBeard.py'))
{
Write-Host 'Removed sabToSickBeard.py script from tv category inside SABnzbd+'
$tv.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
}

View File

@@ -3,13 +3,13 @@
<metadata>
<id>SickBeard.Source</id>
<title>Sick Beard Usenet PVR</title>
<version>10.00.1600.22-Alpha</version>
<version>2012.10.22</version>
<authors>midgetspy</authors>
<owners>Ethan Brown</owners>
<summary>The ultimate PVR application that searches for and manages your TV shows.</summary>
<description>Sick Beard is a PVR for newsgroup users (with limited torrent support). It watches for new episodes of your favorite shows and when they are posted it downloads them, sorts and renames them, and optionally generates metadata for them. It currently supports NZBs.org, NZBMatrix, NZBs'R'Us, Newzbin, Womble's Index, NZB.su, TVTorrents and EZRSS and retrieves show information from theTVDB.com and TVRage.com.
This package
This package performs a number of normally quite painful / tedious tasks
- Installs SABnzbd+ (compiled version)
- Installs Python
- Installs Cheetah with Windows optimizations
@@ -38,6 +38,9 @@
</dependencies>
</metadata>
<files>
<file src="..\core\Out-IniFile.ps1" target="tools" />
<file src="..\core\Get-IniContent.ps1" target="tools" />
<file src="..\core\WaitForSuccess.ps1" target="tools" />
<file src="tools\**" target="tools" />
</files>
</package>

View File

@@ -8,9 +8,9 @@ try {
[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')
. (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
@@ -20,21 +20,9 @@ try {
Select -ExpandProperty Definition
}
function WaitService([string]$name, [int]$seconds)
{
Write-Host "Waiting up to $($seconds)s for $name to start..."
$result = 0..($seconds * 2) |
% {
$service = Get-Service $name -ErrorAction SilentlyContinue
if ($service -and ($service.Status -eq 'Running'))
{ return $true }
elseif ($service)
{ Start-Sleep -Milliseconds 500 }
return $false
} |
Select -Last 1
return $result
$sickBeardRunning = {
$service = Get-Service 'SickBeard' -ErrorAction SilentlyContinue
return ($service -and ($service.Status -eq 'Running'))
}
# Use PYTHONHOME if it exists, or fallback to 'Where' to search PATH
@@ -51,6 +39,17 @@ try {
$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))
{
@@ -62,14 +61,20 @@ try {
Push-Location $sitePackages
$git = Which git
$sickBeardPath = (Join-Path $sitePackages 'Sick-Beard')
$sickBeardEmpty = $true
if (Test-Path $sickBeardPath)
{
$files = Get-ChildItem $sickBeardPath -Recurse -ErrorAction SilentlyContinue
$sickBeardEmpty = ($files.Count -eq 0)
}
if (!$sickBeardEmpty)
{
Write-ChocolateySuccess 'SickBeard already installed!'
return
}
else
{
Write-ChocolateySuccess 'Cloning SickBeard source from GitHub'
Write-Host 'Cloning SickBeard source from GitHub'
&git clone https://github.com/midgetspy/Sick-Beard
}
@@ -79,7 +84,7 @@ try {
if (Test-Path $sabIniPath)
{
Write-Host "Reading SABnzbd+ config file at $sabIniPath"
$sabConfig = Get-IniContent $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 `
@@ -88,12 +93,12 @@ try {
$scriptDir = (Join-Path $sabDataPath 'scripts')
Write-Host "Configured SABnzbd+ script_dir to $scriptDir"
$sabConfig.misc.script_dir = $scriptDir
$sabConfig | Out-IniFile -FilePath $sabIniPath -Force
$sabConfig | Out-IniFile -FilePath $sabIniPath -Force -Encoding UTF8
}
if (!(Test-Path $sabConfig.misc.script_dir))
{
[Void]New-Item -Path $sabConfig.misc.script_dir -Type Directory
New-Item -Path $sabConfig.misc.script_dir -Type Directory | Out-Null
}
# copy and configure autoprocessing scripts in SABNzbd+ scripts directory
@@ -123,7 +128,7 @@ try {
}
Write-Host 'Configured tv category in SABnzbd+'
$sabConfig | Out-IniFile -FilePath $sabIniPath -Force
$sabConfig | Out-IniFile -FilePath $sabIniPath -Force -Encoding UTF8
}
# regardless of sabnzbd+ install status, .PY should be executable
@@ -147,7 +152,7 @@ try {
Write-Host "Found resource kit - registering SickBeard as a service"
Push-Location $resourceKit
$srvAny = Join-Path $resourceKit 'srvany.exe'
.\instsrv SickBeard $srvany
.\instsrv SickBeard $srvany | Out-Null
# Set-Service cmdlet doesn't have depend OR delayed start :(
Write-Host "Configuring service delayed auto with Tcpip dependency"
@@ -171,12 +176,34 @@ try {
Start-Service SickBeard
# config files are created on first start-up
if (WaitService 'SickBeard', 20)
{
$configPath = (Join-Path $sickBeardPath 'config.ini')
$sickBeardConfig = Get-IniContent $configPath
$configPath = (Join-Path $sickBeardPath 'config.ini')
Write-Host "Configuring Windows Firewall for the SickBeard port"
# to start hacking config.ini the service needs to be up, config.ini needs
# to exist, and SickBeard must respond to requests (config.ini is complete)
$waitOnConfig = {
if (!(&$sickBeardRunning)) { return $false }
if (!(Test-Path $configPath)) { return $false }
# fails with a 200 (unknown API key) so we know it's accepting requests!
$pingUrl = 'http://localhost:8081/api/?cmd=sb.ping'
try
{
(New-Object Net.WebClient).DownloadString($pingUrl)
return $true
}
catch {}
return $false
}
if (WaitForSuccess $waitOnConfig 20 'SickBeard to start and create config')
{
Write-Host 'SickBeard started and configuration files created'
$sickBeardConfig = Get-IniContent -Path $configPath
$sickBeardApiKey = $sickBeardConfig.General.api_key
Write-Host 'Configuring Windows Firewall for the SickBeard port'
# configure windows firewall
netsh advfirewall firewall delete rule name="SickBeard"
# program="$pythonW"
@@ -191,7 +218,9 @@ try {
$sickBeardConfig.General.move_associated_files = 1
$sickBeardConfig.General.api_key = [Guid]::NewGuid().ToString('n')
$sickBeardConfig.General.metadata_xbmc = '1|1|1|1|1|1'
$sickBeardConfig.General.naming_pattern = '%SN - %Sx%0E - %EN'
$sickBeardConfig.General.keep_processed_dir = 0
$sickBeardConfig.General.naming_pattern = 'Season %S\%SN - %Sx%0E - %EN'
#range like x03-05
$sickBeardConfig.General.naming_multi_ep = 8
@@ -210,30 +239,33 @@ try {
$sickBeardConfig.SABnzbd.sab_category = 'tv'
$sickBeardConfig.SABnzbd.sab_host = "http://localhost:$($sabConfig.misc.port)/"
$sickBeardConfig | Out-IniFile -File $configPath -Force -Encoding ASCII
$sickBeardConfig |
Out-IniFile -File $configPath -Force -Encoding UTF8 |
Out-Null
Stop-Service SickBeard
Start-Service SickBeard
Restart-Service SickBeard
}
$autoConfig = Join-Path $sabConfig.misc.script_dir 'autoProcessTV.cfg'
if (!(Test-Path $autoConfig))
{
$processConfig = @{
'SickBeard' = @{
host = $sickBeardConfig.General.web_host;
port = $sickBeardConfig.General.web_port;
username = $sickBeardConfig.General.web_username;
password = $sickBeardConfig.General.web_password;
web_root = $sickBeardConfig.General.web_root;
ssl = 0;
}
}
$processConfig | Out-IniFile -FilePath $autoConfig
# order shouldn't matter, but don't trust Python ;0
$sbAuto = New-Object Collections.Specialized.OrderedDictionary
$sbAuto.host = $sickBeardConfig.General.web_host -replace '0\.0\.0\.0',
'localhost';
$sbAuto.port = $sickBeardConfig.General.web_port;
$sbAuto.username = $sickBeardConfig.General.web_username;
$sbAuto.password = $sickBeardConfig.General.web_password;
$sbAuto.web_root = $sickBeardConfig.General.web_root;
$sbAuto.ssl = 0;
@{ 'SickBeard' = $sbAuto } |
Out-IniFile -FilePath $autoConfig -Encoding ASCII -Force
Write-Host @"
SickBeard SABNzbd+ post-processing scripts configured
If SickBeard is reconfigured with a username or password or another
host then those same changes must be made to $sickBeardConfig
host then those same changes must be made to $configPath
"@
}
@@ -243,12 +275,15 @@ SickBeard SABNzbd+ post-processing scripts configured
(New-Object Net.WebClient).DownloadString($url)
#wait up to 5 seconds for service to fire up
if (WaitService 'SickBeard' 5)
if (WaitForSuccess $sickBeardRunning 5 'SickBeard to start')
{
#launch local default browser for additional config
[Diagnostics.Process]::Start("http://localhost:$($sickBeardConfig.General.web_port)")
$configUrl = "http://localhost:$($sickBeardConfig.General.web_port)"
[Diagnostics.Process]::Start($configUrl) | Out-Null
}
Write-Host "For use in other apps, SickBeard API key: $sickBeardApiKey"
Pop-Location
}

View File

@@ -128,7 +128,7 @@ function Out-IniFile
Write-Verbose "[INFO]: Out-IniFile writing file [$FilePath]"
if ((New-Object IO.FileInfo($FilePath)).Extension -ne '.ini')
{
Write-Warning 'Out-IniFile [$FilePath] does not end in .ini extension'
Write-Warning "Out-IniFile [$FilePath] does not end in .ini extension"
}
if ((Test-Path $FilePath) -and (!$Force))
@@ -178,4 +178,4 @@ function Out-IniFile
Write-Verbose "[SUCCESS]: Out-IniFile wrote file [$outFile]"
if ($PassThru) { return $outFile }
}
}
}

View File

@@ -12,7 +12,7 @@ function WaitForSuccess([ScriptBlock] $script, [int]$seconds = 10,
$skip = $true
return $true
}
elseif ($service)
else
{
Start-Sleep -Milliseconds 500
}