2024-05-20 19:08:58 +00:00
|
|
|
# Set the console color to Matrix theme and clear the console
|
|
|
|
$host.UI.RawUI.BackgroundColor = "Black"
|
|
|
|
$host.UI.RawUI.ForegroundColor = "Green"
|
|
|
|
Clear-Host
|
|
|
|
|
|
|
|
# Set the log file path and initialize variables
|
|
|
|
$LogFilePath = Join-Path $env:TEMP "script_log.txt"
|
|
|
|
$ProjectDir = "G:\Downloads\GitHub\freqtrade"
|
|
|
|
$RequirementFiles = @("requirements.txt", "requirements-dev.txt", "requirements-hyperopt.txt", "requirements-freqai.txt", "requirements-plot.txt")
|
|
|
|
$VenvName = ".venv"
|
|
|
|
|
|
|
|
function Write-Log {
|
|
|
|
param (
|
|
|
|
[string]$Message,
|
|
|
|
[string]$Level = 'INFO'
|
|
|
|
)
|
2024-05-21 20:32:03 +00:00
|
|
|
|
2024-05-20 19:08:58 +00:00
|
|
|
switch ($Level) {
|
|
|
|
'INFO' { Write-Host $Message -ForegroundColor Green }
|
|
|
|
'WARNING' { Write-Host $Message -ForegroundColor Yellow }
|
|
|
|
'ERROR' { Write-Host $Message -ForegroundColor Red }
|
|
|
|
'PROMPT' { Write-Host $Message -ForegroundColor Cyan }
|
|
|
|
}
|
|
|
|
"${Level}: $Message" | Out-File $LogFilePath -Append
|
|
|
|
}
|
|
|
|
|
|
|
|
function Get-UserSelection {
|
|
|
|
param (
|
|
|
|
[string]$prompt,
|
|
|
|
[string[]]$options,
|
|
|
|
[string]$defaultChoice = 'A'
|
|
|
|
)
|
|
|
|
|
|
|
|
Write-Log "$prompt`n" -Level 'PROMPT'
|
|
|
|
for ($i = 0; $i -lt $options.Length; $i++) {
|
|
|
|
Write-Log "$([char](65 + $i)). $($options[$i])" -Level 'PROMPT'
|
|
|
|
}
|
|
|
|
|
|
|
|
Write-Log "`nSelect one or more options by typing the corresponding letters, separated by commas." -Level 'PROMPT'
|
|
|
|
$inputPath = Read-Host
|
|
|
|
if ([string]::IsNullOrEmpty($inputPath)) {
|
|
|
|
$inputPath = $defaultChoice
|
|
|
|
}
|
|
|
|
|
|
|
|
# Ensure $inputPath is treated as a string and split it by commas
|
|
|
|
$inputPath = [string]$inputPath
|
|
|
|
$selections = $inputPath.Split(',') | ForEach-Object {
|
|
|
|
$_.Trim().ToUpper()
|
|
|
|
}
|
|
|
|
|
2024-05-21 20:32:03 +00:00
|
|
|
# Convert each selection from letter to index and validate
|
|
|
|
$indices = @()
|
|
|
|
foreach ($selection in $selections) {
|
|
|
|
if ($selection -match '^[A-Z]$') {
|
|
|
|
$index = [int][char]$selection - [int][char]'A'
|
|
|
|
if ($index -ge 0 -and $index -lt $options.Length) {
|
|
|
|
$indices += $index
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Log "Invalid input: $selection. Please enter letters within the valid range of options." -Level 'ERROR'
|
|
|
|
}
|
2024-05-20 19:08:58 +00:00
|
|
|
}
|
|
|
|
else {
|
2024-05-21 20:32:03 +00:00
|
|
|
Write-Log "Invalid input: $selection. Please enter letters between A and Z." -Level 'ERROR'
|
2024-05-20 19:08:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $indices
|
|
|
|
}
|
|
|
|
|
|
|
|
function Exit-Script {
|
|
|
|
param (
|
|
|
|
[int]$exitCode,
|
2024-05-21 20:32:03 +00:00
|
|
|
[bool]$isSubShell = $true,
|
|
|
|
[bool]$waitForKeypress = $true
|
2024-05-20 19:08:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if ($OldVirtualPath) {
|
|
|
|
$env:PATH = $OldVirtualPath
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($exitCode -ne 0 -and $isSubShell) {
|
|
|
|
Write-Log "Script failed. Would you like to open the log file? (Y/N)" -Level 'PROMPT'
|
|
|
|
$openLog = Read-Host
|
|
|
|
if ($openLog -eq 'Y' -or $openLog -eq 'y') {
|
|
|
|
Start-Process notepad.exe -ArgumentList $LogFilePath
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-21 20:32:03 +00:00
|
|
|
if ($waitForKeypress) {
|
|
|
|
Write-Log "Press any key to exit..."
|
|
|
|
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
|
|
|
|
}
|
|
|
|
|
|
|
|
return $exitCode
|
2024-05-20 19:08:58 +00:00
|
|
|
}
|
|
|
|
|
2024-05-21 20:32:03 +00:00
|
|
|
# Function to handle installation
|
|
|
|
function Install {
|
2024-05-20 19:08:58 +00:00
|
|
|
param ([string]$InputPath)
|
2024-05-21 20:32:03 +00:00
|
|
|
|
2024-05-20 19:08:58 +00:00
|
|
|
if (-not $InputPath) {
|
2024-05-21 20:32:03 +00:00
|
|
|
Write-Log "No input provided for installation." -Level 'ERROR'
|
2024-05-20 19:08:58 +00:00
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
2024-05-21 20:32:03 +00:00
|
|
|
|
2024-05-20 19:08:58 +00:00
|
|
|
Write-Log "Installing $InputPath..."
|
|
|
|
$installCmd = if (Test-Path $InputPath) { $VenvPip + @('install', '-r', $InputPath) } else { $VenvPip + @('install', $InputPath) }
|
|
|
|
$output = & $installCmd[0] $installCmd[1..$installCmd.Length] 2>&1
|
|
|
|
$output | Out-File $LogFilePath -Append
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
2024-05-21 20:32:03 +00:00
|
|
|
Write-Log "Conflict detected. Exiting now..." -Level 'ERROR'
|
2024-05-20 19:08:58 +00:00
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Function to get the installed Python version tag for wheel compatibility
|
|
|
|
function Get-PythonVersionTag {
|
|
|
|
$pythonVersion = & python -c "import sys; print(f'cp{sys.version_info.major}{sys.version_info.minor}')"
|
|
|
|
$architecture = & python -c "import platform; print('win_amd64' if platform.machine().endswith('64') else 'win32')"
|
|
|
|
return "$pythonVersion-$architecture"
|
|
|
|
}
|
|
|
|
|
2024-05-21 20:32:03 +00:00
|
|
|
# Exit in test environment
|
|
|
|
if ($MyInvocation.InvocationName -ne $MyInvocation.MyCommand.Name) {
|
|
|
|
exit
|
|
|
|
}
|
|
|
|
|
2024-05-20 19:08:58 +00:00
|
|
|
# Check for admin privileges and elevate if necessary
|
|
|
|
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
|
|
Write-Log "Requesting administrative privileges..." -Level 'ERROR'
|
|
|
|
Start-Process PowerShell -ArgumentList "-File `"$PSCommandPath`"" -Verb RunAs
|
|
|
|
Exit-Script -exitCode 1 -isSubShell $false
|
|
|
|
}
|
|
|
|
|
|
|
|
# Log file setup
|
|
|
|
"Admin rights confirmed" | Out-File $LogFilePath -Append
|
|
|
|
"Starting the script operations..." | Out-File $LogFilePath -Append
|
|
|
|
|
|
|
|
# Navigate to the project directory
|
|
|
|
Set-Location -Path $ProjectDir
|
|
|
|
"Current directory: $(Get-Location)" | Out-File $LogFilePath -Append
|
|
|
|
|
|
|
|
# Define the path to the Python executable in the virtual environment
|
|
|
|
$VenvPython = Join-Path $ProjectDir "$VenvName\Scripts\python.exe"
|
|
|
|
|
|
|
|
# Check if the virtual environment exists, if not, create it
|
|
|
|
if (-Not (Test-Path $VenvPython)) {
|
|
|
|
Write-Log "Virtual environment not found. Creating virtual environment..." -IsError $false
|
|
|
|
python -m venv "$VenvName"
|
|
|
|
if (-Not (Test-Path $VenvPython)) {
|
|
|
|
Write-Log "Failed to create virtual environment." -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
Write-Log "Virtual environment created successfully." -IsError $false
|
|
|
|
}
|
|
|
|
|
|
|
|
# Define the pip command using the Python executable
|
|
|
|
$VenvPip = @($VenvPython, '-m', 'pip')
|
|
|
|
|
|
|
|
# Activate the virtual environment
|
|
|
|
$OldVirtualPath = $env:PATH
|
|
|
|
$env:PATH = "$ProjectDir\$VenvName\Scripts;$env:PATH"
|
|
|
|
|
|
|
|
# Ensure setuptools is installed using the virtual environment's pip
|
|
|
|
Write-Log "Ensuring setuptools is installed..."
|
|
|
|
& $VenvPip[0] $VenvPip[1..$VenvPip.Length] 'install', '-v', 'setuptools' | Out-File $LogFilePath -Append 2>&1
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
Write-Log "Failed to install setuptools." -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Pull latest updates
|
|
|
|
Write-Log "Pulling latest updates..."
|
|
|
|
& git pull | Out-File $LogFilePath -Append 2>&1
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
Write-Log "Failed to pull updates from Git." -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Install TA-Lib using the virtual environment's pip
|
|
|
|
Write-Log "Installing TA-Lib using virtual environment's pip..."
|
|
|
|
& $VenvPip[0] $VenvPip[1..$VenvPip.Length] 'install', '--find-links=build_helpers\', '--prefer-binary', 'TA-Lib' | Out-File $LogFilePath -Append 2>&1
|
|
|
|
|
|
|
|
# Present options for requirement files
|
|
|
|
$selectedIndices = Get-UserSelection -prompt "Select which requirement files to install:" -options $RequirementFiles -defaultChoice 'A'
|
|
|
|
|
|
|
|
# Install selected requirement files
|
|
|
|
foreach ($index in $selectedIndices) {
|
|
|
|
if ($index -lt 0 -or $index -ge $RequirementFiles.Length) {
|
|
|
|
Write-Log "Invalid selection index: $index" -Level 'ERROR'
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
$filePath = Join-Path $ProjectDir $RequirementFiles[$index]
|
|
|
|
if (Test-Path $filePath) {
|
2024-05-21 20:32:03 +00:00
|
|
|
Install $filePath
|
2024-05-20 19:08:58 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Log "Requirement file not found: $filePath" -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Install freqtrade from setup using the virtual environment's Python
|
|
|
|
Write-Log "Installing freqtrade from setup..."
|
|
|
|
$setupInstallCommand = "$VenvPython -m pip install -e ."
|
|
|
|
Invoke-Expression $setupInstallCommand | Out-File $LogFilePath -Append 2>&1
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
Write-Log "Failed to install freqtrade." -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Ask if the user wants to install the UI
|
|
|
|
$uiOptions = @("Yes", "No")
|
|
|
|
$installUI = Get-UserSelection -prompt "Do you want to install the freqtrade UI?" -options $uiOptions -defaultChoice 'B'
|
|
|
|
|
|
|
|
if ($uiOptions[$installUI] -eq "Yes") {
|
|
|
|
# Install freqtrade UI using the virtual environment's install-ui command
|
|
|
|
Write-Log "Installing freqtrade UI..."
|
|
|
|
& $VenvPython 'freqtrade', 'install-ui' | Out-File $LogFilePath -Append 2>&1
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
Write-Log "Failed to install freqtrade UI." -Level 'ERROR'
|
|
|
|
Exit-Script -exitCode 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Write-Log "Update complete!"
|
|
|
|
Exit-Script -exitCode 0
|