- additional blocking of sending client logs and events
- fixed incorrect exp processing behavior
- minor change

Co-Authored-By: jetfir3 <95306468+jetfir3@users.noreply.github.com>
This commit is contained in:
amd64fox
2023-10-28 19:32:46 +03:00
parent 77ceb30760
commit e454aa86da
2 changed files with 174 additions and 102 deletions

View File

@@ -239,6 +239,15 @@
"to": "" "to": ""
} }
}, },
"Dsa3": {
"name": "enableDSASetting",
"description": "Enable DSA (Digital Service Act) features for desktop and web",
"native_description": "Enable DSA (Digital Service Act) features for desktop and web",
"version": {
"fr": "1.2.20",
"to": ""
}
},
"NewAdsNpv": { "NewAdsNpv": {
"name": "enableNewAdsNpv", "name": "enableNewAdsNpv",
"description": "Enable showing new ads NPV", "description": "Enable showing new ads NPV",
@@ -275,15 +284,6 @@
"to": "" "to": ""
} }
}, },
"DSASetting": {
"name": "enableDSASetting",
"description": "Enable DSA (Digital Service Act) features for desktop and web",
"native_description": "Enable DSA (Digital Service Act) features for desktop and web",
"version": {
"fr": "1.2.20",
"to": ""
}
},
"NewAdsNpvNewVideoTakeoverSlot": { "NewAdsNpvNewVideoTakeoverSlot": {
"name": "enableNewAdsNpvNewVideoTakeoverSlot", "name": "enableNewAdsNpvNewVideoTakeoverSlot",
"description": "Enable new modal slot to position redesigned new ads NPV VideoTakeover above all areas except RightSidebar and NPB", "description": "Enable new modal slot to position redesigned new ads NPV VideoTakeover above all areas except RightSidebar and NPB",
@@ -301,8 +301,16 @@
"fr": "1.2.22", "fr": "1.2.22",
"to": "" "to": ""
} }
},
"GabitoAdEvent": {
"name": "enableGabitoAdEvent",
"description": "Use Gabito AdEvent instead of Gabo AdEvent",
"native_description": "Use Gabito AdEvent instead of Gabo AdEvent",
"version": {
"fr": "1.1.93",
"to": ""
}
} }
}, },
"EnableExp": { "EnableExp": {
"EnhanceLikedSongs": { "EnhanceLikedSongs": {
@@ -589,7 +597,7 @@
"description": "Enable Smart Shuffle in playlists", "description": "Enable Smart Shuffle in playlists",
"native_description": "Enable Smart Shuffle", "native_description": "Enable Smart Shuffle",
"version": { "version": {
"fr": "1.2.15", "fr": "1.2.22",
"to": "" "to": ""
} }
}, },
@@ -747,23 +755,34 @@
} }
} }
}, },
"block_update": { "binary": {
"version": { "block_update": {
"fr": "1.1.58", "version": {
"to": "" "fr": "1.1.58",
"to": ""
},
"add": "(?<=desktop-update\/.)7(\/update)",
"match": "(?<=desktop-update\/.)2(\/update)",
"replace": "7/update"
}, },
"add": "(?<=desktop-update\/.)7(\/update)", "podcast_ad_block": {
"match": "(?<=desktop-update\/.)2(\/update)", "version": {
"replace": "7/update" "fr": "1.1.68",
}, "to": ""
"podcast_ad_block": { },
"version": { "add": "slott(?=.{3,8}override_url)",
"fr": "1.1.68", "match": "slots(?=.{3,8}override_url)",
"to": "" "replace": "slott"
}, },
"add": "slott(?=.{3,8}override_url)", "block_gabo": {
"match": "slots(?=.{3,8}override_url)", "version": {
"replace": "slott" "fr": "1.1.68",
"to": ""
},
"add": "dodo(?=.receiver-service)",
"match": "gabo(?=.receiver-service)",
"replace": "dodo"
}
}, },
"podcastsoff": { "podcastsoff": {
"version": { "version": {
@@ -1079,8 +1098,14 @@
"fr": "1.1.70", "fr": "1.1.70",
"to": "" "to": ""
}, },
"match": "(?:prototype\\.)?bindClient(?:=function)?\\(\\w+\\)\\{", "match": [
"replace": "${0}return;" "(?:prototype\\.)?bindClient(?:=function)?\\(\\w+\\)\\{",
"@\\w+\/gabo[^\"]+"
],
"replace": [
"${0}return;",
""
]
}, },
"removertl-cssmin": { "removertl-cssmin": {
"version": { "version": {
@@ -1228,7 +1253,7 @@
}, },
"match": "(this\\._product_state(?:|_service)=(.))", "match": "(this\\._product_state(?:|_service)=(.))",
"replace": "$1,$2.putOverridesValues({0})", "replace": "$1,$2.putOverridesValues({0})",
"add": "ads:'0',catalogue:'premium',product:'premium',type:'premium',name:'Spotify'", "add": "ads:'0',catalogue:'premium',product:'premium',type:'premium',name:'Spotify','unrestricted':'1'",
"add2": "'storage-size-config':'{0},90,500,3'" "add2": "'storage-size-config':'{0},90,500,3'"
}, },
"podcast_page_banner": { "podcast_page_banner": {
@@ -1247,6 +1272,22 @@
"match": "(isPremium:).(.{20,40}?isHptoHidden:).", "match": "(isPremium:).(.{20,40}?isHptoHidden:).",
"replace": "$1true$2true" "replace": "$1true$2true"
}, },
"sentry": {
"version": {
"fr": "1.1.70",
"to": ""
},
"match": "https[0-9a-zA-Z/:@\\d\\.]{0,55}sentry\\.io\/\\d+",
"replace": ""
},
"disablelog": {
"version": {
"fr": "1.1.70",
"to": ""
},
"match": "sp://logging/v3/\\w+",
"replace": ""
},
"hidemerchsidebar": { "hidemerchsidebar": {
"version": { "version": {
"fr": "1.2.0", "fr": "1.2.0",
@@ -1263,14 +1304,6 @@
"match": "(\\[(.)\\.go\\.en,)(.+?\\])", "match": "(\\[(.)\\.go\\.en,)(.+?\\])",
"replace": "$1$2.go.ru]" "replace": "$1$2.go.ru]"
}, },
"disablelog": {
"version": {
"fr": "1.1.70",
"to": ""
},
"match": "sp://logging/v3/\\w+",
"replace": ""
},
"goofyhistory": { "goofyhistory": {
"version": { "version": {
"fr": "1.1.90", "fr": "1.1.90",

167
run.ps1
View File

@@ -28,10 +28,12 @@ param
[switch]$confirm_uninstall_ms_spoti, [switch]$confirm_uninstall_ms_spoti,
[Parameter(HelpMessage = 'Overwrite outdated or unsupported version of Spotify with the recommended version.')] [Parameter(HelpMessage = 'Overwrite outdated or unsupported version of Spotify with the recommended version.')]
[Alias('sp-over')]
[switch]$confirm_spoti_recomended_over, [switch]$confirm_spoti_recomended_over,
[Parameter(HelpMessage = 'Uninstall outdated or unsupported version of Spotify and install the recommended version.')] [Parameter(HelpMessage = 'Uninstall outdated or unsupported version of Spotify and install the recommended version.')]
[switch]$confirm_spoti_recomended_unistall, [Alias('sp-uninstall')]
[switch]$confirm_spoti_recomended_uninstall,
[Parameter(HelpMessage = 'Installation without ad blocking for premium accounts.')] [Parameter(HelpMessage = 'Installation without ad blocking for premium accounts.')]
[switch]$premium, [switch]$premium,
@@ -602,10 +604,10 @@ if ($spotifyInstalled) {
# Old version Spotify # Old version Spotify
if ($oldversion) { if ($oldversion) {
if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_unistall) { if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_uninstall) {
Write-Host ($lang).OldV`n Write-Host ($lang).OldV`n
} }
if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_unistall)) { if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_uninstall)) {
do { do {
Write-Host (($lang).OldV2 -f $offline, $online) Write-Host (($lang).OldV2 -f $offline, $online)
$ch = Read-Host -Prompt ($lang).OldV3 $ch = Read-Host -Prompt ($lang).OldV3
@@ -616,14 +618,14 @@ if ($spotifyInstalled) {
} }
while ($ch -notmatch '^y$|^n$') while ($ch -notmatch '^y$|^n$')
} }
if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_unistall) { if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_uninstall) {
$ch = 'y' $ch = 'y'
Write-Host ($lang).AutoUpd`n Write-Host ($lang).AutoUpd`n
} }
if ($ch -eq 'y') { if ($ch -eq 'y') {
$upgrade_client = $true $upgrade_client = $true
if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_unistall)) { if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_uninstall)) {
do { do {
$ch = Read-Host -Prompt (($lang).DelOrOver -f $offline) $ch = Read-Host -Prompt (($lang).DelOrOver -f $offline)
Write-Host Write-Host
@@ -633,7 +635,7 @@ if ($spotifyInstalled) {
} }
while ($ch -notmatch '^y$|^n$') while ($ch -notmatch '^y$|^n$')
} }
if ($confirm_spoti_recomended_unistall) { $ch = 'y' } if ($confirm_spoti_recomended_uninstall) { $ch = 'y' }
if ($confirm_spoti_recomended_over) { $ch = 'n' } if ($confirm_spoti_recomended_over) { $ch = 'n' }
if ($ch -eq 'y') { if ($ch -eq 'y') {
Write-Host ($lang).DelOld`n Write-Host ($lang).DelOld`n
@@ -684,10 +686,10 @@ if ($spotifyInstalled) {
Write-Host "error description: "$Error[0] Write-Host "error description: "$Error[0]
} }
if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_unistall) { if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_uninstall) {
Write-Host ($lang).NewV`n Write-Host ($lang).NewV`n
} }
if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_unistall)) { if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_uninstall)) {
do { do {
Write-Host (($lang).NewV2 -f $offline, $online) Write-Host (($lang).NewV2 -f $offline, $online)
$ch = Read-Host -Prompt (($lang).NewV3 -f $offline) $ch = Read-Host -Prompt (($lang).NewV3 -f $offline)
@@ -698,10 +700,10 @@ if ($spotifyInstalled) {
} }
while ($ch -notmatch '^y$|^n$') while ($ch -notmatch '^y$|^n$')
} }
if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_unistall) { $ch = 'n' } if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_uninstall) { $ch = 'n' }
if ($ch -eq 'y') { $upgrade_client = $false } if ($ch -eq 'y') { $upgrade_client = $false }
if ($ch -eq 'n') { if ($ch -eq 'n') {
if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_unistall)) { if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_uninstall)) {
do { do {
$ch = Read-Host -Prompt (($lang).Recom -f $online) $ch = Read-Host -Prompt (($lang).Recom -f $online)
Write-Host Write-Host
@@ -711,14 +713,14 @@ if ($spotifyInstalled) {
} }
while ($ch -notmatch '^y$|^n$') while ($ch -notmatch '^y$|^n$')
} }
if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_unistall) { if ($confirm_spoti_recomended_over -or $confirm_spoti_recomended_uninstall) {
$ch = 'y' $ch = 'y'
Write-Host ($lang).AutoUpd`n Write-Host ($lang).AutoUpd`n
} }
if ($ch -eq 'y') { if ($ch -eq 'y') {
$upgrade_client = $true $upgrade_client = $true
$downgrading = $true $downgrading = $true
if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_unistall)) { if (!($confirm_spoti_recomended_over) -and !($confirm_spoti_recomended_uninstall)) {
do { do {
$ch = Read-Host -Prompt (($lang).DelOrOver -f $offline) $ch = Read-Host -Prompt (($lang).DelOrOver -f $offline)
Write-Host Write-Host
@@ -728,7 +730,7 @@ if ($spotifyInstalled) {
} }
while ($ch -notmatch '^y$|^n$') while ($ch -notmatch '^y$|^n$')
} }
if ($confirm_spoti_recomended_unistall) { $ch = 'y' } if ($confirm_spoti_recomended_uninstall) { $ch = 'y' }
if ($confirm_spoti_recomended_over) { $ch = 'n' } if ($confirm_spoti_recomended_over) { $ch = 'n' }
if ($ch -eq 'y') { if ($ch -eq 'y') {
Write-Host ($lang).DelNew`n Write-Host ($lang).DelNew`n
@@ -890,6 +892,43 @@ if ($retries -eq 3) {
} }
function Helper($paramname) { function Helper($paramname) {
function Remove-Json {
param (
[Parameter(Mandatory = $true)]
[Alias("j")]
[PSObject]$Json,
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Alias("p")]
[string[]]$Properties
)
foreach ($Property in $Properties) {
$Json.psobject.properties.Remove($Property)
}
}
function Move-Json {
param (
[Parameter(Mandatory = $true)]
[Alias("t")]
[PSObject]$to,
[Parameter(Mandatory = $true)]
[Alias("n")]
[string[]]$name,
[Parameter(Mandatory = $true)]
[Alias("f")]
[PSObject]$from
)
foreach ($propertyName in $name) {
$from | Add-Member -MemberType NoteProperty -Name $propertyName -Value $to.$propertyName
Remove-Json -j $to -p $propertyName
}
}
switch ( $paramname ) { switch ( $paramname ) {
"HtmlLicMin" { "HtmlLicMin" {
# licenses.html minification # licenses.html minification
@@ -1009,42 +1048,47 @@ function Helper($paramname) {
"ForcedExp" { "ForcedExp" {
# Forced disable some exp (xpui.js) # Forced disable some exp (xpui.js)
$offline_patch = $offline -replace '(\d+\.\d+\.\d+)(.\d+)', '$1' $offline_patch = $offline -replace '(\d+\.\d+\.\d+)(.\d+)', '$1'
$remEnable = $webjson.others.EnableExp.psobject.properties $Enable = $webjson.others.EnableExp
$remCustom = $webjson.others.CustomExp.psobject.properties $Disable = $webjson.others.DisableExp
$Custom = $webjson.others.CustomExp
if ($enhance_like_off) { $remEnable.remove('EnhanceLikedSongs') } if ($enhance_like_off) { Remove-Json -j $Enable -p'EnhanceLikedSongs' }
if ($enhance_playlist_off) { $remEnable.remove('EnhancePlaylist') } if ($enhance_playlist_off) { Remove-Json -j $Enable -p 'EnhancePlaylist' }
if ($EnhanceSongs) { if ($EnhanceSongs) {
$smartShuffle = $webjson.others.EnableExp.SmartShuffle Move-Json -n 'SmartShuffle' -t $Enable -f $Disable
$webjson.others.DisableExp | Add-Member -MemberType NoteProperty -Name "SmartShuffle" -Value $smartShuffle }
else {
if ([version]$offline -ge [version]'1.2.22.980') {
Move-Json -n "EnhanceLikedSongs", "EnhancePlaylist"-t $Enable -f $Disable
}
} }
$remEnable.remove('QueueOnRightPanel') Remove-Json -j $Enable -p "EncoreCards", "QueueOnRightPanel"
$remEnable.remove('EncoreCards')
if (!($funnyprogressBar)) { $remEnable.remove('HeBringsNpb') } if (!($funnyprogressBar)) { Remove-Json -j $Enable -p "HeBringsNpb" }
# Old theme # Old theme
if (!($new_theme) -and [version]$offline -le [version]"1.2.13.661") { if (!($new_theme) -and [version]$offline -le [version]"1.2.13.661") {
$LeftSidebar = $webjson.others.EnableExp.LeftSidebar
$RightSidebar = $webjson.others.EnableExp.RightSidebar
$webjson.others.DisableExp | Add-Member -MemberType NoteProperty -Name "LeftSidebar" -Value $LeftSidebar
$webjson.others.DisableExp | Add-Member -MemberType NoteProperty -Name "RightSidebar" -Value $RightSidebar
$remCustom.remove('NavAlt'), $remCustom.remove('NavAlt2'), $remEnable.remove('RightSidebarLyrics'), $remEnable.remove('RightSidebarCredits'), Move-Json -n 'RightSidebar', 'LeftSidebar' -t $Enable -f $Disable
$remEnable.remove('RightSidebar'), $remEnable.remove('LeftSidebar'), $remEnable.remove('RightSidebarColors');
Remove-Json -j $Custom -p "NavAlt", 'NavAlt2'
Remove-Json -j $Enable -p 'RightSidebarLyrics', 'RightSidebarCredits', 'RightSidebar', 'LeftSidebar', 'RightSidebarColors'
} }
# New theme # New theme
else { else {
if ($rightsidebar_off) { if ($rightsidebar_off) {
$RightSidebar = $webjson.others.EnableExp.RightSidebar Move-Json -n 'RightSidebar' -t $Enable -from $Disable
$webjson.others.DisableExp | Add-Member -MemberType NoteProperty -Name "RightSidebar" -Value $RightSidebar
} }
else { else {
if (!($rightsidebarcolor)) { $remEnable.remove('RightSidebarColors') } if (!($rightsidebarcolor)) { Remove-Json -j $Enable -p 'RightSidebarColors' }
if ($old_lyrics) { $remEnable.remove('RightSidebarLyrics') } if ($old_lyrics) { Remove-Json -j $Enable -p 'RightSidebarLyrics' }
} }
} }
if (!$premium) { $remEnable.remove('RemoteDownloads') } if (!$premium) { Remove-Json -j $Enable -p 'RemoteDownloads' }
# Disable unimportant exp # Disable unimportant exp
if ($exp_spotify) { if ($exp_spotify) {
@@ -1068,7 +1112,7 @@ function Helper($paramname) {
} }
$Exp = ($webjson.others.EnableExp, $webjson.others.DisableExp, $webjson.others.CustomExp) $Exp = ($Enable, $Disable, $Custom)
foreach ($item in $Exp) { foreach ($item in $Exp) {
$itemProperties = $item | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $itemProperties = $item | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
@@ -1084,19 +1128,19 @@ function Helper($paramname) {
} }
} }
$enableExp = $webjson.others.EnableExp $Enable = $webjson.others.EnableExp
$disableExp = $webjson.others.DisableExp $Disable = $webjson.others.DisableExp
$CustomExp = $webjson.others.CustomExp $Custom = $webjson.others.CustomExp
$enableNames = foreach ($item in $enableExp.PSObject.Properties.Name) { $enableNames = foreach ($item in $Enable.PSObject.Properties.Name) {
$webjson.others.EnableExp.$item.name $webjson.others.EnableExp.$item.name
} }
$disableNames = foreach ($item in $disableExp.PSObject.Properties.Name) { $disableNames = foreach ($item in $Disable.PSObject.Properties.Name) {
$webjson.others.DisableExp.$item.name $webjson.others.DisableExp.$item.name
} }
$customNames = foreach ($item in $CustomExp.PSObject.Properties.Name) { $customNames = foreach ($item in $Custom.PSObject.Properties.Name) {
$custname = $webjson.others.CustomExp.$item.name $custname = $webjson.others.CustomExp.$item.name
$custvalue = $webjson.others.CustomExp.$item.value $custvalue = $webjson.others.CustomExp.$item.value
@@ -1149,19 +1193,16 @@ function Helper($paramname) {
$contents = $webjsonru.psobject.properties.name $contents = $webjsonru.psobject.properties.name
$json = $webjsonru $json = $webjsonru
} }
"PodcastAd" { "Binary" {
# Aodcast ad block
$name = "patches.json.others." $binary = $webjson.others.binary
if ($block_update) { Remove-Json -j $binary -p 'BlockUpdate' }
$name = "patches.json.others.binary."
$n = "Spotify.exe" $n = "Spotify.exe"
$contents = "podcast_ad_block" $contents = $webjson.others.binary.psobject.properties.name
$json = $webjson.others $json = $webjson.others.binary
}
"BlockUpdate" {
# Block Spotify client updates
$name = "patches.json.others."
$n = "Spotify.exe"
$contents = "block_update"
$json = $webjson.others
} }
"Collaborators" { "Collaborators" {
# Hide Collaborators icon # Hide Collaborators icon
@@ -1172,14 +1213,14 @@ function Helper($paramname) {
} }
"VariousofXpui-js" { "VariousofXpui-js" {
$rem = $webjson.VariousJs.psobject.properties $VarJs = $webjson.VariousJs
if ($urlform_goofy -and $idbox_goofy) { if ($urlform_goofy -and $idbox_goofy) {
$webjson.VariousJs.goofyhistory.replace = "`$1 const urlForm=" + '"' + $urlform_goofy + '"' + ";const idBox=" + '"' + $idbox_goofy + '"' + $webjson.VariousJs.goofyhistory.replace $webjson.VariousJs.goofyhistory.replace = "`$1 const urlForm=" + '"' + $urlform_goofy + '"' + ";const idBox=" + '"' + $idbox_goofy + '"' + $webjson.VariousJs.goofyhistory.replace
} }
else { $rem.remove('goofyhistory') } else { Remove-Json -j $VarJs -p "goofyhistory" }
if (!($ru)) { $rem.remove('offrujs') } if (!($ru)) { Remove-Json -j $VarJs -p "offrujs" }
if (!($premium) -or ($cache_limit)) { if (!($premium) -or ($cache_limit)) {
if (!($premium)) { if (!($premium)) {
@@ -1199,7 +1240,7 @@ function Helper($paramname) {
$repl = $webjson.VariousJs.product_state.replace $repl = $webjson.VariousJs.product_state.replace
$webjson.VariousJs.product_state.replace = $repl -f "{pairs:{$adds}}" $webjson.VariousJs.product_state.replace = $repl -f "{pairs:{$adds}}"
} }
else { $rem.remove('product_state') } else { Remove-Json -j $VarJs -p 'product_state' }
$name = "patches.json.VariousJs." $name = "patches.json.VariousJs."
$n = "xpui.js" $n = "xpui.js"
@@ -1550,10 +1591,11 @@ If (!(Test-Path $start_menu)) {
$ANSI = [Text.Encoding]::GetEncoding(1251) $ANSI = [Text.Encoding]::GetEncoding(1251)
$old = [IO.File]::ReadAllText($spotifyExecutable, $ANSI) $old = [IO.File]::ReadAllText($spotifyExecutable, $ANSI)
$rexex1 = $old -notmatch $webjson.others.block_update.add $rexex1 = $old -notmatch $webjson.others.binary.block_update.add
$rexex2 = $old -notmatch $webjson.others.podcast_ad_block.add $rexex2 = $old -notmatch $webjson.others.binary.podcast_ad_block.add
$rexex3 = $old -notmatch $webjson.others.binary.block_gabo.add
if ($rexex1 -and $rexex2 ) { if ($rexex1 -and $rexex2 -and $rexex3) {
if (Test-Path -LiteralPath $exe_bak) { if (Test-Path -LiteralPath $exe_bak) {
Remove-Item $exe_bak -Recurse -Force Remove-Item $exe_bak -Recurse -Force
@@ -1562,11 +1604,8 @@ if ($rexex1 -and $rexex2 ) {
copy-Item $spotifyExecutable $exe_bak copy-Item $spotifyExecutable $exe_bak
} }
# Podcast ad block # Binary patch
extract -counts 'exe' -helper 'PodcastAd' extract -counts 'exe' -helper 'Binary'
# Block updates
if ($block_update) { extract -counts 'exe' -helper 'BlockUpdate' }
# Start Spotify # Start Spotify
if ($start_spoti) { Start-Process -WorkingDirectory $spotifyDirectory -FilePath $spotifyExecutable } if ($start_spoti) { Start-Process -WorkingDirectory $spotifyDirectory -FilePath $spotifyExecutable }