param ( [Parameter(Mandatory=$true)] [string]$outputFilePath, [string]$rentryUrl = "https://rentry.org/ponyxl_loras_n_stuff" ) function Get-RemoteFileSize { param ( [string]$url ) try { $ProgressPreference = 'SilentlyContinue' $response = Invoke-WebRequest -Uri $url -Method Head $ProgressPreference = 'Continue' $fileSize = [int]$response.Headers['Content-Length'] return $fileSize; } catch { Write-Error "Failed to retrieve file size. $_" } } function Create-Entry { param ( [string]$name, [string]$url, [int]$size, [string] $comment, [int]$status ) return [pscustomobject]@{Name=$name;Url=$url;Size=$size;Status=$status;Comment=$comment;Selected=0} } Clear-Host #The path to the history file $historyFile = Join-Path $outputFilePath "_history.txt" # Initialize an empty dictionary for tracking the history $historyDict = @{} if (Test-Path $historyFile -PathType Leaf) { # Read the file line by line and populate the dictionary Get-Content -Path $historyFile | ForEach-Object { # Split the line into key and value based on whitespace $lineParts = $_ -split '\s+' # Ensure there are at least two parts on the line if ($lineParts.Length -ge 2) { $key = $lineParts[0] #$index = $_.IndexOf($lineParts[1]) #$comment = $_.Substring($index + $lineParts[1].Length).Trim() #$value = @($lineParts[1], $comment) # Add an entry to the dictionary $historyDict[$key] = $lineParts[1] } } } Write-Host "Getting details about the Loras" # Define a regular expression pattern to match URLs within HTML elements ending with "safetensors" $downloadLinkPattern = ']*href=["'']?(https?://(?:www\.)?[^\s]+safetensors\b[^"''\s>]*)[^>]*>([^<]*)([^<]*)' # Download the content of the rentry.org page $pageContent = Invoke-RestMethod -Uri $rentryUrl # Find all matches using the regular expression pattern $matches = $pageContent | Select-String -Pattern $downloadLinkPattern -AllMatches | ForEach-Object { $_.Matches } # Initialize an empty list for tracking the available loras, each entry is a tuple with name, url, file size, integer indicating status (0 is new, 1 is updated), and integer indicating if user wants to download $availableLoras = @() # Process each match and extract download link, the first string inside element, and the HTML content after foreach ($match in $matches) { $url = $match.Groups[1].Value $htmlAfterA = $match.Groups[3].Value # Trim the string and split it into two variables $trimmedString = $htmlAfterA.Trim() $firstWord = $trimmedString.Split(' ', 2)[0] $remainingText = $trimmedString.Split(' ', 2)[1] $outputFileWithPath = Join-Path "$outputFilePath" "ponyxl_$firstWord.safetensors" $comment = if($remainingText -ne $null) { $remainingText.Trim() } else { "" } if($historyDict[$firstWord] -eq $null -or -Not (Test-Path $outputFileWithPath -PathType Leaf)) { $fileSize = Get-RemoteFileSize -url $url #We don't have the lora yet, add it to the list of options $availableLoras += Create-Entry -name $firstWord -url $url -size $fileSize -comment $comment -status 0 } elseif(-Not ($historyDict[$firstWord] -eq $url)) { #The Lora was updated $fileSize = Get-RemoteFileSize -url $url $availableLoras += Create-Entry -name $firstWord -url $url -size $fileSize -comment $comment -status 1 } } if($availableLoras.Count -eq 0) { Write-Host "There are no available updates based on your history file." Exit } Do { Clear-Host Write-Host "Below are the available LoRAs, asterisk indicates a LoRA is queued." $index = 1 foreach ($availableLora in $availableLoras) { $name = $availableLora.Name $queued = if ($availableLora.Selected -eq 1) { "(*)" } else { "" } $size = $availableLora.Size / 1048576 $status = if ($availableLora.Status -eq 0) { "New" } else { "Updated" } $size = $size.ToString("F2") Write-Host "[$index]) $queued $name - $status ($size MB)" $index++; } Write-Host "Enter a number to toggle queued status, a to queue all, or c to continue to download the queued LoRAs." $input = Read-Host "Command" if($input -eq "a") { foreach ($availableLora in $availableLoras) { $availableLora.Selected = 1 } } elseif($input -ne "c") { $parsedInt = -1 $success = [int]::TryParse($input, [ref]$parsedInt) if($success) { $availableLoras[$parsedInt - 1].Selected = ($availableLoras[$parsedInt - 1].Selected + 1) % 2 } } } while($input -ne "c") if (-not (Test-Path $outputFilePath -PathType Container)) { # If the folder doesn't exist, create it New-Item -Path $outputFilePath -ItemType Directory } #Download the selected LoRAs $downloadedLoras = 0 foreach ($availableLora in $availableLoras) { if($availableLora.Selected -eq 1) { try { $name = $availableLora.Name $url = $availableLora.Url.Trim() $comment = $availableLora.Comment $outputFileWithPath = Join-Path $outputFilePath "ponyxl_$name.safetensors" #if the file already exists, rename the old one before downloading the new one if (Test-Path $outputFileWithPath) { $counter = 1 $newName = "ponyxl_$($name)_old_$counter.safetensors" $newPath = Join-Path $outputFilePath $newName while (Test-Path $newPath) { $newName = "ponyxl_$($name)_old_$counter.safetensors" $newPath = Join-Path $outputFilePath $newName $counter++ } Rename-Item -LiteralPath $outputFileWithPath -NewName $newName Write-Host "Renamed old $name LoRA to: $newName" } Write-Host "Downloading lora $name with url $url" Invoke-WebRequest $url -OutFile $outputFileWithPath ++$downloadedLoras $historyDict[$name] = $url if ($comment -ne $null -and $comment -ne "") { $commentFileWithPath = Join-Path "$outputFilePath" "ponyxl_$name.txt" # Clear the existing content of the output text file if (Test-Path $commentFileWithPath -PathType Leaf) { Clear-Content -Path $commentFileWithPath # Write the new string to the text file Add-Content -Path $commentFileWithPath -Value $comment } } } catch { Write-Host "Error downloading lora $name, skipping, error was $_" } } } if (Test-Path $historyFile -PathType Leaf) { # Clear the existing content of the history file Clear-Content -Path $historyFile } #Write the new history foreach ($entry in $historyDict.GetEnumerator()) { $entryString = "{0} {1}" -f $entry.Key, $entry.Value Add-Content -Path $historyFile -Value $entryString } Write-Host "Downloaded $downloadedLoras LoRAs." Write-Host "Wrote the most recent urls for each model to _history.txt."