feat(editor): add translation launcher workflow
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$toolRoot = Split-Path -Parent $PSCommandPath
|
||||
$projectRoot = (Resolve-Path (Join-Path $toolRoot "..\..")).Path
|
||||
$serverPath = Join-Path $toolRoot "server.py"
|
||||
$reviewRoot = Join-Path $projectRoot "epub_review_sessions"
|
||||
$venvRoot = Join-Path $toolRoot ".venv"
|
||||
$venvPython = Join-Path $venvRoot "Scripts\python.exe"
|
||||
$requirements = Join-Path $toolRoot "requirements.txt"
|
||||
$versionFile = Join-Path $toolRoot "version.py"
|
||||
$defaultPort = 5177
|
||||
|
||||
$env:PYTHONIOENCODING = "utf-8"
|
||||
|
||||
function Get-PythonCommand {
|
||||
$pyLauncher = Get-Command py -ErrorAction SilentlyContinue
|
||||
if ($pyLauncher) {
|
||||
return [pscustomobject]@{ Exe = $pyLauncher.Source; Args = @("-3") }
|
||||
}
|
||||
|
||||
$python = Get-Command python -ErrorAction SilentlyContinue
|
||||
if ($python) {
|
||||
return [pscustomobject]@{ Exe = $python.Source; Args = @() }
|
||||
}
|
||||
|
||||
throw "Python was not found. Install Python 3, then run this launcher again."
|
||||
}
|
||||
|
||||
function Invoke-PythonCommand {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Exe,
|
||||
[string[]]$Args = @()
|
||||
)
|
||||
|
||||
& $Exe @Args
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
function Test-FlaskInstalled {
|
||||
& $venvPython -c "import importlib.util, sys; sys.exit(0 if importlib.util.find_spec('flask') else 1)" 2>$null
|
||||
return ($LASTEXITCODE -eq 0)
|
||||
}
|
||||
|
||||
function Get-ExpectedVersion {
|
||||
if (!(Test-Path $versionFile)) {
|
||||
return ""
|
||||
}
|
||||
$content = Get-Content -Raw -Encoding UTF8 $versionFile
|
||||
$match = [regex]::Match($content, 'version\s*=\s*"([^"]+)"')
|
||||
if ($match.Success) {
|
||||
return $match.Groups[1].Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
function Test-LocalPortOpen {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$Port
|
||||
)
|
||||
|
||||
$client = New-Object System.Net.Sockets.TcpClient
|
||||
try {
|
||||
$async = $client.BeginConnect("127.0.0.1", $Port, $null, $null)
|
||||
if (!$async.AsyncWaitHandle.WaitOne(100, $false)) {
|
||||
return $false
|
||||
}
|
||||
$client.EndConnect($async)
|
||||
return $true
|
||||
} catch {
|
||||
return $false
|
||||
} finally {
|
||||
$client.Close()
|
||||
}
|
||||
}
|
||||
|
||||
function Get-RunningEditorUrl {
|
||||
$expectedVersion = Get-ExpectedVersion
|
||||
for ($port = $defaultPort; $port -lt ($defaultPort + 100); $port++) {
|
||||
if (!(Test-LocalPortOpen -Port $port)) {
|
||||
continue
|
||||
}
|
||||
$url = "http://127.0.0.1:$port"
|
||||
try {
|
||||
$versionPayload = Invoke-RestMethod -Uri "$url/api/version" -TimeoutSec 1 -ErrorAction Stop
|
||||
if (!$expectedVersion -or $versionPayload.version -eq $expectedVersion) {
|
||||
return "http://localhost:$port"
|
||||
}
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
$runningUrl = Get-RunningEditorUrl
|
||||
if ($runningUrl) {
|
||||
Write-Host "EPUB review editor is already running."
|
||||
Start-Process $runningUrl
|
||||
Write-Host $runningUrl
|
||||
Write-Host "review root: $reviewRoot"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (!(Test-Path $venvPython)) {
|
||||
Write-Host "Creating local Python environment..."
|
||||
$python = Get-PythonCommand
|
||||
$venvArgs = @()
|
||||
if ($python.Args) {
|
||||
$venvArgs += $python.Args
|
||||
}
|
||||
$venvArgs += @("-m", "venv", $venvRoot)
|
||||
if ((Invoke-PythonCommand -Exe $python.Exe -Args $venvArgs) -ne 0) {
|
||||
throw "Failed to create local Python environment."
|
||||
}
|
||||
}
|
||||
|
||||
if (!(Test-FlaskInstalled)) {
|
||||
Write-Host "Installing review editor dependencies..."
|
||||
& $venvPython -m pip install -r $requirements
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to install dependencies from requirements.txt."
|
||||
}
|
||||
if (!(Test-FlaskInstalled)) {
|
||||
throw "Dependencies were installed, but Flask is still unavailable in the local Python environment."
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Starting EPUB review editor..."
|
||||
& $venvPython $serverPath --review-root $reviewRoot --daemon
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to start EPUB review editor."
|
||||
}
|
||||
Reference in New Issue
Block a user