Add parallel companion processing dashboard
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name ChatGPT to Suno Prompt Copier
|
// @name ChatGPT to Suno Prompt Copier
|
||||||
// @namespace local.suno-helper
|
// @namespace local.suno-helper
|
||||||
// @version 0.8.6
|
// @version 0.8.7
|
||||||
// @description Copy structured ChatGPT song prompt versions into Suno fields.
|
// @description Copy structured ChatGPT song prompt versions into Suno fields.
|
||||||
// @author local
|
// @author local
|
||||||
// @match https://chatgpt.com/*
|
// @match https://chatgpt.com/*
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const SCRIPT_VERSION = "0.8.6";
|
const SCRIPT_VERSION = "0.8.7";
|
||||||
const STORAGE_KEY = "chatgptSunoPromptSlots";
|
const STORAGE_KEY = "chatgptSunoPromptSlots";
|
||||||
const SLOT_COUNT = 2;
|
const SLOT_COUNT = 2;
|
||||||
const isChatGPT = location.hostname.includes("chatgpt.com") || location.hostname.includes("chat.openai.com");
|
const isChatGPT = location.hostname.includes("chatgpt.com") || location.hostname.includes("chat.openai.com");
|
||||||
@@ -1417,7 +1417,11 @@
|
|||||||
}
|
}
|
||||||
await new Promise((resolve) => setTimeout(resolve, 400));
|
await new Promise((resolve) => setTimeout(resolve, 400));
|
||||||
}
|
}
|
||||||
setStatus(statusTarget, `${format.toUpperCase()} 일괄 업로드 완료: ${uploaded}곡 성공, ${failed}곡 실패. 로컬에서 메타데이터 후처리 중.`);
|
let healthText = "";
|
||||||
|
try {
|
||||||
|
healthText = ` / ${formatCompanionStatus(await readCompanionHealth())}`;
|
||||||
|
} catch {}
|
||||||
|
setStatus(statusTarget, `${format.toUpperCase()} 일괄 업로드 완료: ${uploaded}곡 성공, ${failed}곡 실패. 로컬에서 메타데이터 후처리 중${healthText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function trackOptionLabel(track, index) {
|
function trackOptionLabel(track, index) {
|
||||||
@@ -1438,7 +1442,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data = tryParseJson(text) || {};
|
const data = tryParseJson(text) || {};
|
||||||
setStatus(statusTarget, `연결 OK: ${data.outputRoot || "outputRoot 확인됨"}`);
|
setStatus(statusTarget, `연결 OK: ${formatCompanionStatus(data)}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setStatus(statusTarget, `연결 실패: companion을 켜고 새로고침해줘. ${error.message || error}`);
|
setStatus(statusTarget, `연결 실패: companion을 켜고 새로고침해줘. ${error.message || error}`);
|
||||||
}
|
}
|
||||||
@@ -1456,6 +1460,20 @@
|
|||||||
return tryParseJson(text) || {};
|
return tryParseJson(text) || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatCompanionStatus(data) {
|
||||||
|
if (!data || typeof data !== "object") return "상태 정보 없음";
|
||||||
|
const active = Number(data.activeCount || 0);
|
||||||
|
const queued = Number(data.queued || 0);
|
||||||
|
const done = Number(data.done ?? ((data.completed || 0) + (data.failed || 0)));
|
||||||
|
const total = Number(data.total || 0);
|
||||||
|
const failed = Number(data.failed || 0);
|
||||||
|
const percent = Number.isFinite(Number(data.percent)) ? Number(data.percent) : (total ? Math.round((done / total) * 1000) / 10 : 100);
|
||||||
|
const workerText = data.maxWorkers ? `${active}/${data.maxWorkers}` : `${active}`;
|
||||||
|
const title = data.active || "";
|
||||||
|
const titleText = title ? ` / 처리중: ${title}` : "";
|
||||||
|
return `작업 ${done}/${total} (${percent}%), 실행 ${workerText}, 대기 ${queued}, 실패 ${failed}${titleText}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function bootSuno() {
|
async function bootSuno() {
|
||||||
const body = createPanel("Suno Prompt Paste");
|
const body = createPanel("Suno Prompt Paste");
|
||||||
const slots = await readSlots();
|
const slots = await readSlots();
|
||||||
@@ -1573,7 +1591,7 @@
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const data = await uploadTrackToCompanion(track, body, format);
|
const data = await uploadTrackToCompanion(track, body, format);
|
||||||
setStatus(body, `선택 1곡 ${format.toUpperCase()} 업로드 완료: ${track.title || track.id} / 대기 ${data.queued ?? "?"}개 / 처리 ${data.active || "대기"}`);
|
setStatus(body, `선택 1곡 ${format.toUpperCase()} 업로드 완료: ${track.title || track.id} / ${formatCompanionStatus(data)}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setStatus(body, `선택 1곡 ${format.toUpperCase()} 처리 실패: ${error.message || error}`);
|
setStatus(body, `선택 1곡 ${format.toUpperCase()} 처리 실패: ${error.message || error}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,7 +370,8 @@ if (-not $tracks.Count) {
|
|||||||
|
|
||||||
$libraryRoot = Resolve-LibraryRoot $OutputRoot $ArtistName
|
$libraryRoot = Resolve-LibraryRoot $OutputRoot $ArtistName
|
||||||
New-Item -ItemType Directory -Force -Path $libraryRoot | Out-Null
|
New-Item -ItemType Directory -Force -Path $libraryRoot | Out-Null
|
||||||
$workRoot = Join-Path $libraryRoot "_work"
|
$workRootName = ConvertTo-SafeName ([IO.Path]::GetFileNameWithoutExtension($manifestFile)) "work"
|
||||||
|
$workRoot = Join-Path (Join-Path $libraryRoot "_work") $workRootName
|
||||||
New-Item -ItemType Directory -Force -Path $workRoot | Out-Null
|
New-Item -ItemType Directory -Force -Path $workRoot | Out-Null
|
||||||
|
|
||||||
Write-Host "Manifest: $manifestFile"
|
Write-Host "Manifest: $manifestFile"
|
||||||
|
|||||||
+230
-65
@@ -2,7 +2,8 @@ param(
|
|||||||
[int]$Port = 17873,
|
[int]$Port = 17873,
|
||||||
[string]$OutputRoot = "\\VaultOfData\AKAMedia\음악\처리됨",
|
[string]$OutputRoot = "\\VaultOfData\AKAMedia\음악\처리됨",
|
||||||
[string]$ArtistName = "SUNO",
|
[string]$ArtistName = "SUNO",
|
||||||
[string]$FfmpegPath = ""
|
[string]$FfmpegPath = "",
|
||||||
|
[int]$MaxWorkers = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -14,9 +15,17 @@ $logs = Join-Path $scriptRoot "companion-logs"
|
|||||||
New-Item -ItemType Directory -Force -Path $inbox, $logs | Out-Null
|
New-Item -ItemType Directory -Force -Path $inbox, $logs | Out-Null
|
||||||
$queue = [System.Collections.Queue]::new()
|
$queue = [System.Collections.Queue]::new()
|
||||||
$queueIds = [System.Collections.Generic.HashSet[string]]::new()
|
$queueIds = [System.Collections.Generic.HashSet[string]]::new()
|
||||||
$activeJob = $null
|
$activeJobs = [System.Collections.ArrayList]::new()
|
||||||
|
$activeIds = [System.Collections.Generic.HashSet[string]]::new()
|
||||||
|
$stats = [ordered]@{
|
||||||
|
total = 0
|
||||||
|
completed = 0
|
||||||
|
failed = 0
|
||||||
|
skipped = 0
|
||||||
|
}
|
||||||
$lastProgressAt = [DateTime]::MinValue
|
$lastProgressAt = [DateTime]::MinValue
|
||||||
$lastProgressText = ""
|
$lastProgressText = ""
|
||||||
|
$lastDashboardAt = [DateTime]::MinValue
|
||||||
|
|
||||||
function Resolve-LibraryRoot {
|
function Resolve-LibraryRoot {
|
||||||
param(
|
param(
|
||||||
@@ -118,9 +127,13 @@ function Read-HttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Start-SunoProcess {
|
function Start-SunoProcess {
|
||||||
param([string]$ManifestPath)
|
param(
|
||||||
|
[string]$ManifestPath,
|
||||||
|
[string]$TrackId
|
||||||
|
)
|
||||||
|
|
||||||
$jobId = Get-Date -Format "yyyyMMdd-HHmmss"
|
$shortId = if ($TrackId) { "$TrackId".Substring(0, [Math]::Min(8, "$TrackId".Length)) } else { "track" }
|
||||||
|
$jobId = "{0}-{1}" -f (Get-Date -Format "yyyyMMdd-HHmmss-fff"), $shortId
|
||||||
$stdout = Join-Path $logs "$jobId.out.log"
|
$stdout = Join-Path $logs "$jobId.out.log"
|
||||||
$stderr = Join-Path $logs "$jobId.err.log"
|
$stderr = Join-Path $logs "$jobId.err.log"
|
||||||
$args = @(
|
$args = @(
|
||||||
@@ -158,41 +171,6 @@ function Save-Manifest {
|
|||||||
return $manifestPath
|
return $manifestPath
|
||||||
}
|
}
|
||||||
|
|
||||||
function Update-Queue {
|
|
||||||
if ($script:activeJob -and -not $script:activeJob.Process.HasExited) {
|
|
||||||
Publish-ActiveJobProgress
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($script:activeJob -and $script:activeJob.Process.HasExited) {
|
|
||||||
Publish-ActiveJobProgress -Force
|
|
||||||
Write-Host "Finished job $($script:activeJob.JobId) exit=$($script:activeJob.Process.ExitCode)"
|
|
||||||
$script:activeJob = $null
|
|
||||||
}
|
|
||||||
|
|
||||||
while (-not $script:activeJob -and $script:queue.Count -gt 0) {
|
|
||||||
$item = $script:queue.Dequeue()
|
|
||||||
[void]$script:queueIds.Remove($item.Id)
|
|
||||||
$manifest = [pscustomobject]@{
|
|
||||||
pageUrl = $item.PageUrl
|
|
||||||
capturedAt = (Get-Date).ToString("o")
|
|
||||||
count = 1
|
|
||||||
tracks = @($item.Track)
|
|
||||||
}
|
|
||||||
$manifestPath = Save-Manifest $manifest
|
|
||||||
$job = Start-SunoProcess $manifestPath
|
|
||||||
$script:activeJob = [pscustomobject]@{
|
|
||||||
JobId = $job.jobId
|
|
||||||
Process = $job.process
|
|
||||||
TrackId = $item.Id
|
|
||||||
Title = $item.Title
|
|
||||||
Log = $job.log
|
|
||||||
ErrorLog = $job.errorLog
|
|
||||||
}
|
|
||||||
Write-Host "Started queued job $($job.jobId): $($item.Title) [$($item.Id)]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-LastLogLine {
|
function Get-LastLogLine {
|
||||||
param([string[]]$Paths)
|
param([string[]]$Paths)
|
||||||
|
|
||||||
@@ -206,20 +184,158 @@ function Get-LastLogLine {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function Publish-ActiveJobProgress {
|
function Get-JobLine {
|
||||||
param([switch]$Force)
|
param($Job)
|
||||||
|
|
||||||
if (-not $script:activeJob) { return }
|
if (-not $Job) { return "" }
|
||||||
|
return Get-LastLogLine @($Job.ErrorLog, $Job.Log)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Publish-JobProgress {
|
||||||
|
param($Job, [switch]$Force)
|
||||||
|
|
||||||
|
if (-not $Job) { return }
|
||||||
$now = Get-Date
|
$now = Get-Date
|
||||||
if (-not $Force -and ($now - $script:lastProgressAt).TotalSeconds -lt 10) { return }
|
if (-not $Force -and ($now - $script:lastProgressAt).TotalSeconds -lt 10) { return }
|
||||||
|
|
||||||
$line = Get-LastLogLine @($script:activeJob.ErrorLog, $script:activeJob.Log)
|
$line = Get-JobLine $Job
|
||||||
if (-not $line) { return }
|
if (-not $line) { return }
|
||||||
if (-not $Force -and $line -eq $script:lastProgressText) { return }
|
$fingerprint = "$($Job.JobId):$line"
|
||||||
|
if (-not $Force -and $fingerprint -eq $script:lastProgressText) { return }
|
||||||
|
|
||||||
$script:lastProgressAt = $now
|
$script:lastProgressAt = $now
|
||||||
$script:lastProgressText = $line
|
$script:lastProgressText = $fingerprint
|
||||||
Write-Host "[$($script:activeJob.JobId)] $($script:activeJob.Title): $line"
|
Write-Host "[$($Job.JobId)] $($Job.Title): $line"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-JobSnapshot {
|
||||||
|
param($Job)
|
||||||
|
|
||||||
|
$elapsed = [int]((Get-Date) - $Job.StartedAt).TotalSeconds
|
||||||
|
return [pscustomobject]@{
|
||||||
|
jobId = $Job.JobId
|
||||||
|
pid = $Job.Process.Id
|
||||||
|
trackId = $Job.TrackId
|
||||||
|
title = $Job.Title
|
||||||
|
elapsedSeconds = $elapsed
|
||||||
|
log = Get-JobLine $Job
|
||||||
|
exitCode = if ($Job.Process.HasExited) { $Job.Process.ExitCode } else { $null }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-QueueSnapshot {
|
||||||
|
$active = @($script:activeJobs | ForEach-Object { Get-JobSnapshot $_ })
|
||||||
|
$total = [int]$script:stats.total
|
||||||
|
$done = [int]$script:stats.completed + [int]$script:stats.failed
|
||||||
|
$percent = if ($total -gt 0) { [Math]::Round(($done / $total) * 100, 1) } else { 100 }
|
||||||
|
$next = @($script:queue | Select-Object -First 5 | ForEach-Object {
|
||||||
|
[pscustomobject]@{
|
||||||
|
id = $_.Id
|
||||||
|
title = $_.Title
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return [pscustomobject]@{
|
||||||
|
maxWorkers = $MaxWorkers
|
||||||
|
queued = $script:queue.Count
|
||||||
|
activeCount = $active.Count
|
||||||
|
active = if ($active.Count) { ($active | Select-Object -First 1).title } else { "" }
|
||||||
|
activeJobs = $active
|
||||||
|
next = $next
|
||||||
|
total = $total
|
||||||
|
completed = [int]$script:stats.completed
|
||||||
|
failed = [int]$script:stats.failed
|
||||||
|
skipped = [int]$script:stats.skipped
|
||||||
|
done = $done
|
||||||
|
percent = $percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Show-Dashboard {
|
||||||
|
param([switch]$Force)
|
||||||
|
|
||||||
|
$now = Get-Date
|
||||||
|
if (-not $Force -and ($now - $script:lastDashboardAt).TotalSeconds -lt 2) { return }
|
||||||
|
$script:lastDashboardAt = $now
|
||||||
|
$snapshot = Get-QueueSnapshot
|
||||||
|
|
||||||
|
Clear-Host
|
||||||
|
Write-Host "SUNO Companion" -ForegroundColor Cyan
|
||||||
|
Write-Host "Listening: http://127.0.0.1:$Port"
|
||||||
|
Write-Host "Library: $libraryRoot"
|
||||||
|
Write-Host "Logs: $logs"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host ("Workers: {0}/{1} Queue: {2} Done: {3}/{4} Failed: {5} Progress: {6}%" -f $snapshot.activeCount, $snapshot.maxWorkers, $snapshot.queued, $snapshot.done, $snapshot.total, $snapshot.failed, $snapshot.percent)
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
if ($snapshot.activeJobs.Count) {
|
||||||
|
Write-Host "Active jobs:" -ForegroundColor Yellow
|
||||||
|
foreach ($job in $snapshot.activeJobs) {
|
||||||
|
$elapsed = [TimeSpan]::FromSeconds($job.elapsedSeconds)
|
||||||
|
Write-Host ("- {0} [{1:mm\:ss}] pid={2}" -f $job.title, $elapsed, $job.pid)
|
||||||
|
if ($job.log) { Write-Host " $($job.log)" -ForegroundColor DarkGray }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Active jobs: none" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($snapshot.next.Count) {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Next queue:" -ForegroundColor Yellow
|
||||||
|
foreach ($item in $snapshot.next) {
|
||||||
|
Write-Host "- $($item.title)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Close this window to stop the companion."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update-Queue {
|
||||||
|
for ($index = $script:activeJobs.Count - 1; $index -ge 0; $index--) {
|
||||||
|
$job = $script:activeJobs[$index]
|
||||||
|
if (-not $job.Process.HasExited) {
|
||||||
|
Publish-JobProgress $job
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Publish-JobProgress $job -Force
|
||||||
|
if ($job.Process.ExitCode -eq 0) {
|
||||||
|
$script:stats.completed++
|
||||||
|
} else {
|
||||||
|
$script:stats.failed++
|
||||||
|
}
|
||||||
|
[void]$script:activeIds.Remove($job.TrackId)
|
||||||
|
$script:activeJobs.RemoveAt($index)
|
||||||
|
Write-Host "Finished job $($job.JobId) exit=$($job.Process.ExitCode): $($job.Title)"
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($script:activeJobs.Count -lt $MaxWorkers -and $script:queue.Count -gt 0) {
|
||||||
|
$item = $script:queue.Dequeue()
|
||||||
|
[void]$script:queueIds.Remove($item.Id)
|
||||||
|
$manifest = [pscustomobject]@{
|
||||||
|
pageUrl = $item.PageUrl
|
||||||
|
capturedAt = (Get-Date).ToString("o")
|
||||||
|
count = 1
|
||||||
|
tracks = @($item.Track)
|
||||||
|
}
|
||||||
|
$manifestPath = Save-Manifest $manifest
|
||||||
|
$job = Start-SunoProcess $manifestPath $item.Id
|
||||||
|
$active = [pscustomobject]@{
|
||||||
|
JobId = $job.jobId
|
||||||
|
Process = $job.process
|
||||||
|
TrackId = $item.Id
|
||||||
|
Title = $item.Title
|
||||||
|
Log = $job.log
|
||||||
|
ErrorLog = $job.errorLog
|
||||||
|
StartedAt = Get-Date
|
||||||
|
}
|
||||||
|
[void]$script:activeJobs.Add($active)
|
||||||
|
[void]$script:activeIds.Add($item.Id)
|
||||||
|
Write-Host "Started queued job $($job.jobId): $($item.Title) [$($item.Id)]"
|
||||||
|
}
|
||||||
|
|
||||||
|
Show-Dashboard
|
||||||
}
|
}
|
||||||
|
|
||||||
function Add-TracksToQueue {
|
function Add-TracksToQueue {
|
||||||
@@ -232,7 +348,7 @@ function Add-TracksToQueue {
|
|||||||
$id = "$($track.id)".Trim()
|
$id = "$($track.id)".Trim()
|
||||||
if (-not $id) { $skipped++; continue }
|
if (-not $id) { $skipped++; continue }
|
||||||
if ($queueIds.Contains($id)) { $skipped++; continue }
|
if ($queueIds.Contains($id)) { $skipped++; continue }
|
||||||
if ($activeJob -and $activeJob.TrackId -eq $id) { $skipped++; continue }
|
if ($activeIds.Contains($id)) { $skipped++; continue }
|
||||||
$title = if ($track.title) { "$($track.title)" } else { $id }
|
$title = if ($track.title) { "$($track.title)" } else { $id }
|
||||||
$queue.Enqueue([pscustomobject]@{
|
$queue.Enqueue([pscustomobject]@{
|
||||||
Id = $id
|
Id = $id
|
||||||
@@ -243,12 +359,21 @@ function Add-TracksToQueue {
|
|||||||
[void]$queueIds.Add($id)
|
[void]$queueIds.Add($id)
|
||||||
$added += $track
|
$added += $track
|
||||||
}
|
}
|
||||||
|
$script:stats.total += @($added).Count
|
||||||
|
$script:stats.skipped += $skipped
|
||||||
Update-Queue
|
Update-Queue
|
||||||
|
$snapshot = Get-QueueSnapshot
|
||||||
return [pscustomobject]@{
|
return [pscustomobject]@{
|
||||||
added = @($added).Count
|
added = @($added).Count
|
||||||
skipped = $skipped
|
skipped = $skipped
|
||||||
queued = $queue.Count
|
queued = $snapshot.queued
|
||||||
active = if ($activeJob) { $activeJob.Title } else { "" }
|
active = $snapshot.active
|
||||||
|
activeCount = $snapshot.activeCount
|
||||||
|
maxWorkers = $snapshot.maxWorkers
|
||||||
|
completed = $snapshot.completed
|
||||||
|
failed = $snapshot.failed
|
||||||
|
total = $snapshot.total
|
||||||
|
percent = $snapshot.percent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +450,9 @@ Write-Host "SUNO companion listening on http://127.0.0.1:$Port"
|
|||||||
Write-Host "OutputRoot: $OutputRoot"
|
Write-Host "OutputRoot: $OutputRoot"
|
||||||
Write-Host "Library: $libraryRoot"
|
Write-Host "Library: $libraryRoot"
|
||||||
Write-Host "Logs: $logs"
|
Write-Host "Logs: $logs"
|
||||||
|
Write-Host "Workers: $MaxWorkers"
|
||||||
Write-Host "Press Ctrl+C to stop."
|
Write-Host "Press Ctrl+C to stop."
|
||||||
|
Show-Dashboard -Force
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while ($true) {
|
while ($true) {
|
||||||
@@ -346,8 +473,26 @@ try {
|
|||||||
|
|
||||||
if ($request.Method -eq "GET" -and $request.Path -eq "/health") {
|
if ($request.Method -eq "GET" -and $request.Path -eq "/health") {
|
||||||
Update-Queue
|
Update-Queue
|
||||||
Write-Host "Health check OK: $(Get-Date -Format 'HH:mm:ss')"
|
$snapshot = Get-QueueSnapshot
|
||||||
Write-Response $stream 200 "OK" (@{ ok = $true; outputRoot = $OutputRoot; libraryRoot = $libraryRoot; artist = $ArtistName; queued = $queue.Count; active = if ($activeJob) { $activeJob.Title } else { "" } } | ConvertTo-Json -Compress)
|
$payload = [ordered]@{
|
||||||
|
ok = $true
|
||||||
|
outputRoot = $OutputRoot
|
||||||
|
libraryRoot = $libraryRoot
|
||||||
|
artist = $ArtistName
|
||||||
|
queued = $snapshot.queued
|
||||||
|
active = $snapshot.active
|
||||||
|
activeCount = $snapshot.activeCount
|
||||||
|
activeJobs = $snapshot.activeJobs
|
||||||
|
next = $snapshot.next
|
||||||
|
maxWorkers = $snapshot.maxWorkers
|
||||||
|
total = $snapshot.total
|
||||||
|
completed = $snapshot.completed
|
||||||
|
failed = $snapshot.failed
|
||||||
|
skipped = $snapshot.skipped
|
||||||
|
done = $snapshot.done
|
||||||
|
percent = $snapshot.percent
|
||||||
|
}
|
||||||
|
Write-Response $stream 200 "OK" ($payload | ConvertTo-Json -Depth 10 -Compress)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,30 +520,38 @@ try {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
$sync = Get-MissingTracks $manifest.tracks
|
$result = Add-TracksToQueue @($manifest.tracks) "$($manifest.pageUrl)"
|
||||||
$manifest.tracks = @($sync.missing)
|
if ($result.added -eq 0) {
|
||||||
$manifest.count = @($manifest.tracks).Count
|
|
||||||
if ($manifest.count -eq 0) {
|
|
||||||
Write-Host "Process skipped: library already synced"
|
Write-Host "Process skipped: library already synced"
|
||||||
Write-Response $stream 200 "OK" (@{
|
Write-Response $stream 200 "OK" (@{
|
||||||
ok = $true
|
ok = $true
|
||||||
skipped = $true
|
skipped = $true
|
||||||
message = "library already synced"
|
message = "library already synced or already queued"
|
||||||
|
queued = $result.queued
|
||||||
|
active = $result.active
|
||||||
|
activeCount = $result.activeCount
|
||||||
|
maxWorkers = $result.maxWorkers
|
||||||
|
completed = $result.completed
|
||||||
|
failed = $result.failed
|
||||||
|
total = $result.total
|
||||||
|
percent = $result.percent
|
||||||
} | ConvertTo-Json -Compress)
|
} | ConvertTo-Json -Compress)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
$manifestPath = Join-Path $inbox ("suno-library-{0}.manifest.json" -f (Get-Date -Format "yyyyMMdd-HHmmss"))
|
Write-Host "Queued process request: added=$($result.added), queued=$($result.queued), active=$($result.activeCount)"
|
||||||
$manifest | ConvertTo-Json -Depth 50 | Set-Content -LiteralPath $manifestPath -Encoding UTF8
|
|
||||||
$job = Start-SunoProcess $manifestPath
|
|
||||||
|
|
||||||
Write-Host "Started job $($job.jobId) for $(@($manifest.tracks).Count) tracks"
|
|
||||||
Write-Response $stream 200 "OK" (@{
|
Write-Response $stream 200 "OK" (@{
|
||||||
ok = $true
|
ok = $true
|
||||||
jobId = $job.jobId
|
added = $result.added
|
||||||
pid = $job.pid
|
skipped = $result.skipped
|
||||||
log = $job.log
|
queued = $result.queued
|
||||||
errorLog = $job.errorLog
|
active = $result.active
|
||||||
|
activeCount = $result.activeCount
|
||||||
|
maxWorkers = $result.maxWorkers
|
||||||
|
completed = $result.completed
|
||||||
|
failed = $result.failed
|
||||||
|
total = $result.total
|
||||||
|
percent = $result.percent
|
||||||
} | ConvertTo-Json -Compress)
|
} | ConvertTo-Json -Compress)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -417,6 +570,12 @@ try {
|
|||||||
skipped = $result.skipped
|
skipped = $result.skipped
|
||||||
queued = $result.queued
|
queued = $result.queued
|
||||||
active = $result.active
|
active = $result.active
|
||||||
|
activeCount = $result.activeCount
|
||||||
|
maxWorkers = $result.maxWorkers
|
||||||
|
completed = $result.completed
|
||||||
|
failed = $result.failed
|
||||||
|
total = $result.total
|
||||||
|
percent = $result.percent
|
||||||
} | ConvertTo-Json -Compress)
|
} | ConvertTo-Json -Compress)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -431,6 +590,12 @@ try {
|
|||||||
skipped = $result.skipped
|
skipped = $result.skipped
|
||||||
queued = $result.queued
|
queued = $result.queued
|
||||||
active = $result.active
|
active = $result.active
|
||||||
|
activeCount = $result.activeCount
|
||||||
|
maxWorkers = $result.maxWorkers
|
||||||
|
completed = $result.completed
|
||||||
|
failed = $result.failed
|
||||||
|
total = $result.total
|
||||||
|
percent = $result.percent
|
||||||
} | ConvertTo-Json -Compress)
|
} | ConvertTo-Json -Compress)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user