Index: dev/install_python_gtk.ps1 ================================================================== --- dev/install_python_gtk.ps1 +++ dev/install_python_gtk.ps1 @@ -27,157 +27,135 @@ ) #-- paths $UsrFolder = $MyInvocation.MyCommand.Path -replace ("([\\/][^\\/]+){4}$","") $UninstallPath = "$UsrFolder\share\streamtuner2\dev\uninstall.cmd" -$ModifyPath = $MyInvocation.MyCommand.Path -replace (".ps1", ".bat") +$ModifyPath = $MyInvocation.MyCommand.Path -replace ("[.]ps1$", ".bat") $IconPath = "$UsrFolder\share\pixmaps\streamtuner2.ico" #-- system configuration +$ErrorActionPreference = "SilentlyContinue" # ignore all path/registry lookup errors $OutputEncoding = [System.Text.Encoding]::UTF8 $regPathCU = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall" $regPathLM = "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" #64-Bit machine if(!(Test-Path $regPathLM)) { #32-Bit machine $regPathLM = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" $ProgramFiles = "%ProgramFiles%" } $STREAMRIPPER = "$ProgramFiles\Streamripper" -$pythonPathLM = (Get-ItemProperty -path ($regPathLM.substring(0,$regPathLM.indexOf("\Microsoft"))+ "\Python\PythonCore\2.7\InstallPath\")).'(default)' 2> $null -$pythonPathCU = (Get-ItemProperty -path ($regPathCU.substring(0,$regPathCU.indexOf("\Microsoft"))+ "\Python\PythonCore\2.7\InstallPath\")).'(default)' 2> $null #-- what and how to install -# each row is a list of (title,url,cmd,msi args,regkey,optional) +# each row is a list of (title, url, cmd, msi args, regkey, pathcheck, is_optional, prelookup) $tasks = @( @( "Python 2.7.12", # title "https://www.python.org/ftp/python/2.7.12/python-2.7.12.msi", # url "", # custom cmd 'TARGETDIR="{PYTHON}" /qb-!', # msi args "$regPathLM\{9DA28CE5-0AA5-429E-86D8-686ED898C665}", # registry "{PYTHON}\pythonw.exe", # installed check - "" # is optional? + "", # is optional? + '' # check-prerequisite→$_found? ), @( "PyGtk 2.24.2", "http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/pygtk-all-in-one-2.24.2.win32-py2.7.msi", "", 'TARGETDIR="{PYTHON}" ADDLOCAL=ALL REMOVE=PythonExtensionModulePyGtkSourceview2,PythonExtensionModulePyGoocanvas,PythonExtensionModulePyRsvg,DevelopmentTools /qb-!', "$regPathLM\{09F82967-D26B-48AC-830E-33191EC177C8}", "$regPathLM\{09F82967-D26B-48AC-830E-33191EC177C8}", - "" + "", + '' ), @( "Python requests", "requests", # no download url, pip handles this "easy_install", "", "", "{PYTHON}\Lib\site-packages\requests-2.12.1-py2.7.egg", - "" + "", + '' ), @( "LXML 2.3", "https://pypi.python.org/packages/d4/fa/e4e0c7a8fe971b10e275cdc20efd16f553a225e700c400c11da25276e4f4/lxml-2.3-py2.7-win32.egg", "easy_install", "", "", "{PYTHON}\Lib\site-packages\lxml-2.3-py2.7-win32.egg", - "" + "", + '' ), @( "PyQuery 1.2.1", "https://pypi.python.org/packages/62/71/8ac1f5c0251e51714d20e4b102710d5eee1683c916616129552b0a025ba5/pyquery-1.2.17-py2.py3-none-any.whl", "pip", "--disable-pip-version-check", "", "{PYTHON}\Lib\site-packages\pyquery-1.2.17.dist-info", - "" + "", + '' ), @( "PIL 1.1.7", "http://effbot.org/downloads/PIL-1.1.7.win32-py2.7.exe", "", "", "$regPathCU\PIL-py2.7", "{PYTHON}\Lib\site-packages\PIL", - "" + "", + '' ), @( "Streamripper 1.64.6", - "http://downloads.sourceforge.net/project/streamripper/streamripper%20%28current%29/1.64.6/streamripper-windows-installer-1.64.6.exe?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fstreamripper%2Ffiles%2Fstreamripper%2520%2528current%2529%2F1.64.6%2F&ts=1480104543&use_mirror=kent" + "https://netcologne.dl.sourceforge.net/project/streamripper/streamripper%20%28current%29/1.64.6/streamripper-windows-installer-1.64.6.exe", "", "/S /D={STREAMRIPPER}" #NSIS does not use double quotes in /D parm, "$regPathLM\Streamripper", "{STREAMRIPPER}\streamripper.exe", - '($true)' + '($true)', # ← could use '((Ask "Install streamripper too [y/N]") -match N)' instead + '(($_found = (Get-ITPV "Streamripper")) -AND ($script:STREAMRIPPER = $_found))' # look up path in Check-Prerequisites ), @( "Uninstall script", "", - 'Create-Uninstallscript', - "", - "", - "", - "" + 'Create-Uninstallscript' ), @( "Desktop shortcut", "", - 'Make-Shortcut -dir $Home\Desktop -name Streamtuner2.lnk -target $PYTHON\pythonw.exe -arg $UsrFolder\bin\streamtuner2', - "", - "", - "" ,# always overwrite $Home\Desktop\Streamtuner2.lnk - "" + 'Make-Shortcut -dir $Home\Desktop -name Streamtuner2.lnk -target $PYTHON\pythonw.exe -arg $UsrFolder\bin\streamtuner2' ), @( "Startmenu shortcut", "", - 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Streamtuner2.lnk -target $PYTHON\pythonw.exe -arg $UsrFolder\bin\streamtuner2', - "", - "", - "", - "" + 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Streamtuner2.lnk -target $PYTHON\pythonw.exe -arg $UsrFolder\bin\streamtuner2' ), @( "Startmenu help.chm", "", - 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Help.lnk -target $UsrFolder\share\streamtuner2\help\help.chm', - "", - "", - "", - "" + 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Help.lnk -target $UsrFolder\share\streamtuner2\help\help.chm' ), @( "Startmenu uninstall", "", - 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Uninstall.lnk -target $UninstallPath', - "", - "", - "", - "" + 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name Uninstall.lnk -target $UninstallPath' ), @( "Startmenu Internet", "", - 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name "Streamtuner2 on the Web.lnk" -target "$AboutLink"', - "", - "", - "", - "" + 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name "Streamtuner2 on the Web.lnk" -target "$AboutLink"' ), @( "Startmenu Reconfigure", "", - 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name "Reconfigure.lnk" -target $ModifyPath', - "", - "", - "", - "" + 'Make-Shortcut -dir "$StartMenu\Streamtuner2" -name "Reconfigure.lnk" -target $ModifyPath' ), @( - "FINISHED", "", 'Any-Key Green', "", "", "", "" + "FINISHED" ) ) @@ -203,15 +181,16 @@ ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– "@ } function Ask-First { Write-Host "" - if ((Ask "Do you want to install Python 2.7.12 and Gtk dependencies now? [Y/n] ") -notmatch "^[yY]|^$") { - exit; # or $tasks = $tasks[7..($tasks.length-1)] + if ((Ask "Do you want to install Python and Gtk now? [Y/n] ") -notmatch "^[yY]|^$") { + $tasks = $tasks[7..($tasks.length-1)] + return } - $reuseCachedFiles = (Ask "Do you want to reuse any cached setup files? [r]euse/[I]gnore) ") -match "^[Rr]" - $optionalInstall = (Ask "Do you want to check optional components? [y/N] ") -match "^[Yy]" + $reuseCachedFiles = (Ask "Reuse any cached setup files? [r]euse/[I]gnore) ") -match "^[Rr]" + $optionalInstall = (Ask "Install optional components? [y/N] ") -match "^[Yy]" Write-Host "" return $reuseCachedFiles, $optionalInstall } function Console-MaxHeight { @@ -232,13 +211,14 @@ #-- create Desktop/Startmenu shortcuts function Make-Shortcut { [CmdletBinding()] param($dir, $name, $target, $arg=$false) if (!(Test-Path -Path $dir)) { - New-Item -Path $dir -ItemType directory > $null + New-Item -Path $dir -ItemType directory 2> $null } $wsh = New-Object -ComObject WScript.Shell + if (!$wsh) { return } $lnk = $wsh.CreateShortcut("$dir\$name") $lnk.TargetPath = $target if ($arg) { $lnk.Arguments = '"'+$arg+'"' $lnk.IconLocation = "$IconPath" @@ -257,15 +237,11 @@ $UninstallScript = Get-Content -Path $UninstallScriptPath Out-File -FilePath $UninstallScriptPath -Encoding ascii -InputObject "@set installFolder=$installFolder" Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject "@set usrFolder=$usrFolder" Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject "@set Python=$PYTHON" Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject "@set StreamripperFolder=$STREAMRIPPER" - <# - if ($STREAMRIPPER) { - Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject "@set StreamripperFolder=$STREAMRIPPER" - } - #> + Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject "@echo off" for ($i=4; $i -lt $UninstallScript.Length ; $i++) { Out-File -FilePath $UninstallScriptPath -Encoding ascii -Append -InputObject $UninstallScript[$i] } #Out-File -FilePath "$UsrFolder\share\streamtuner2\dev\Y" -Encoding ascii -InputObject "Y" #if (Test-IsElevated) { @@ -313,24 +289,29 @@ Write-Host -b DarkRed -f White "`nThe bin\streamtuner2 start script could not be found.`nThe installation cannot continue.`nDo not change the folder structure of the Streamtuner2 package!`nIf you want to run the install_python_gtk.ps1 script post-install,`nplease use the -UsrFolder parameter.`n" Any-Key Red ; exit } } +#-- shortcut Get-ItemPropertyValue over multiple registry hives +function Get-ITPV($regpath, $value="(default)") { + @('HKLM:\Software\WOW6432Node', 'HKLM:\Software', 'HKCU:\Software') | % { + if (($val = (Get-ItemProperty -path "$_\$regpath" 2>$null).$value) -AND (Test-Path $val)) { return $val } + } +} #-- Check if previous Python 2.7 installation exists function Check-PythonInstall { - if ($pythonPathLM) {$PythonInstalledPath = $PythonPathLM} - else {$PythonInstalledPath = $PythonPathCU} - + $PythonInstalledPath = Get-ITPV('Python\PythonCore\2.7\InstallPath\') + #-- if Python 2.7.12 installed, reuse installation folder if (Get-Item -path "$regPathLM\{9DA28CE5-0AA5-429E-86D8-686ED898C665}" 2> $null ) { - $PYTHON = $pythonInstalledPath.substring(0,$pythonInstalledPath.LastIndexOf('\')) + $PYTHON = $pythonInstalledPath -replace "\\$", "" } #-- older 2.7 version found else { - if (($pythonPathLM) -or ($pythonPathCU)) { + if ($PythonInstalledPath) { Write-Host "" Write-Host -b Red -f White @" Setup has detected an older version of Python 2.7 in $PythonInstalledPath. @@ -351,53 +332,34 @@ #-- check prereqs installation function Check-Prerequisites { [CmdletBinding()] param($result = 1) - Check-Package - ForEach ($task in $tasks) { - $title, $url, $cmd, $args, $regkey, $check, $optional = $task; - if ($optional) { - if ($optionalInstall) { - if ($title -match "Streamripper") { - - $StreamripperPath = (get-itemproperty -path HKCU:\Software\Streamripper).'(default)' 2> $null - if (!(Test-Path -Path ($StreamripperPath + "\streamripper.exe"))) { - write-host " - $title not found" - } - else { - Write-Host " + $title found in $StreamripperPath" - } - } - } - } - - else { - if ($regkey) { - if (!(Test-Path -Path $regkey)) { # avoid runtime error if not existent (not working in PS2) - Write-Host " - $title not found" - $result = 0 - } - else { - #Write-Host (Get-ItemProperty -Path $regkey -Name "DisplayName".DisplayName).DisplayName " found" - if ($title -match "Python 2.7.12") { - Write-Host " + $title found in $PYTHON" - } - else { - Write-Host " + $title found" - } - } - } - elseif ($title -match "requests|PyQuery|LXML") { - if (!(Test-Path -Path ($check -replace "{PYTHON}","$PYTHON"))) { - write-Host " - $title not found" - $result = 0 - } - else { - Write-Host " + $title found" - } - } + ForEach ($task in $tasks) { + $title, $url, $cmd, $args, $regkey, $checkpath, $is_optional, $presearch, $_found = $task; + $checkpath = $checkpath -replace "{PYTHON}","$PYTHON" + if (($is_optional -and !$optionalInstall) -or (!$regkey -and !$checkpath)) { + continue + } + if ($presearch) { # expression for e.g. registry → path lookup + Invoke-Expression $presearch # should set $_found + global $PLACEHOLDER variable + } + elseif ($checkpath) { + if (Test-Path $checkpath) { + $_found = $checkpath + } + } + elseif ($regkey -and (Test-Path $regkey)) { + $_found = $regkey -replace ".+\\", "" + } + if (!$_found) { + Write-Host " - $title not found" + $result = 0; + } + else { + Write-Host -n " + $title found " # and display shortened path: + Write-Host -f DarkGray "($($_found -replace '(? # license: Public Domain # url: http://freshcode.club/projects/streamtuner2 # config: @@ -18,20 +18,23 @@ # pack: *.py, gtk3.xml.gz, bin, channels/__init__.py, bundle/*.py, CREDITS, help/index.page, # streamtuner2.desktop, README, help/streamtuner2.1=/usr/share/man/man1/, # NEWS=/usr/share/doc/streamtuner2/, icon.png=/usr/share/pixmaps/streamtuner2.png # architecture: all # -# Streamtuner2 is a GUI for browsing internet radio directories, music -# collections, and video services - grouped by genres or categories. -# It runs your preferred audio player, and streamripper for recording. -# -# It's an independent rewrite of streamtuner1. Being written in Python, -# can be more easily extended and fixed. The mix of JSON APIs, regex -# or PyQuery extraction makes list generation simpler and more robust. -# -# Primarily radio stations are displayed, some channels however are music -# collections. Commercial and sign-up services are not an objective. +# Streamtuner2 is a GUI for browsing internet radio directories, +# music collections, and video services - grouped by genres or +# categories. It runs your preferred audio player or streamripper +# for recording. +# +# It's an independent rewrite of streamtuner1. Being written in +# Python, can be more easily extended and fixed. The mix of +# JSON APIs, regex or PyQuery extraction simplifies collecting +# station lists. +# +# Primarily radio stations are displayed, some channels however +# are music collections. Commercial and sign-up services are not +# an objective. # standard modules import sys import os