release: v1.1.3 — dual-domain separation and URL options
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
Add admin/image domain separation with host isolation middleware, optional hide-folder public URLs, GitHub release update check, and Lucky/Nginx deployment docs. Switch license to GPL-3.0-only.
This commit is contained in:
1 parent
55effa204e
commit
d8c1303c32
41 files changed
+2170
-299
No files matched your search
@@ -1,146 +0,0 @@
|
||||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Assign userId to image .meta.json files that are missing it (shows as 系统/API).
|
||||
|
||||
.PARAMETER DataDir
|
||||
PicHost data directory (contains images/, twikoo/, pichost.db). Default: ./data
|
||||
|
||||
.PARAMETER UserId
|
||||
Target user id. If omitted, uses the first admin from pichost.db.
|
||||
|
||||
.PARAMETER Apply
|
||||
Actually write files. Without this flag, only prints what would change (dry-run).
|
||||
|
||||
.EXAMPLE
|
||||
cd D:\Ou\PicHost
|
||||
.\scripts\assign-image-owner.ps1
|
||||
|
||||
.EXAMPLE
|
||||
.\scripts\assign-image-owner.ps1 -DataDir D:\pic-host\data -Apply
|
||||
|
||||
.EXAMPLE
|
||||
.\scripts\assign-image-owner.ps1 -UserId 1 -Apply
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $DataDir = (Join-Path (Get-Location) 'data'),
|
||||
[int] $UserId = 0,
|
||||
[switch] $Apply
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Resolve-AdminUserId {
|
||||
param([string] $DbPath)
|
||||
|
||||
if (-not (Test-Path -LiteralPath $DbPath)) {
|
||||
Write-Warning "pichost.db not found at $DbPath; using UserId = 1"
|
||||
return 1
|
||||
}
|
||||
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$nodeFile = Join-Path $env:TEMP "pichost-read-admin-$PID.mjs"
|
||||
@'
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
const db = new DatabaseSync(process.argv[2]);
|
||||
const row = db.prepare("SELECT id FROM users WHERE role = 'admin' ORDER BY id ASC LIMIT 1").get();
|
||||
if (!row) process.exit(2);
|
||||
process.stdout.write(String(row.id));
|
||||
db.close();
|
||||
'@ | Set-Content -LiteralPath $nodeFile -Encoding utf8
|
||||
|
||||
Push-Location $repoRoot
|
||||
try {
|
||||
$output = & node $nodeFile $DbPath 2>&1
|
||||
if ($LASTEXITCODE -eq 2) {
|
||||
throw "No admin user in database. Run /setup first or pass -UserId explicitly."
|
||||
}
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to read admin from database: $output"
|
||||
}
|
||||
return [int]$output
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
Remove-Item -LiteralPath $nodeFile -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
function Read-MetaJson {
|
||||
param([string] $Path)
|
||||
$raw = [System.IO.File]::ReadAllText($Path, [System.Text.UTF8Encoding]::new($false))
|
||||
return $raw | ConvertFrom-Json
|
||||
}
|
||||
|
||||
function Write-MetaJson {
|
||||
param(
|
||||
[string] $Path,
|
||||
[object] $Meta
|
||||
)
|
||||
# Compact single-line JSON, same style as PicHost putImage()
|
||||
$json = $Meta | ConvertTo-Json -Compress -Depth 10
|
||||
$utf8 = [System.Text.UTF8Encoding]::new($false)
|
||||
[System.IO.File]::WriteAllText($Path, $json, $utf8)
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $DataDir)) {
|
||||
throw "DataDir not found: $DataDir"
|
||||
}
|
||||
|
||||
$resolved = Resolve-Path -LiteralPath $DataDir
|
||||
$DataDir = if ($resolved.ProviderPath) { $resolved.ProviderPath } else { $resolved.Path }
|
||||
|
||||
if ($UserId -le 0) {
|
||||
$UserId = Resolve-AdminUserId -DbPath (Join-Path $DataDir 'pichost.db')
|
||||
}
|
||||
|
||||
Write-Host "DataDir : $DataDir"
|
||||
Write-Host "UserId : $UserId"
|
||||
Write-Host "Mode : $(if ($Apply) { 'APPLY (will modify files)' } else { 'DRY-RUN (pass -Apply to write)' })"
|
||||
Write-Host ''
|
||||
|
||||
$metaFiles = Get-ChildItem -LiteralPath $DataDir -Recurse -File -Filter '*.meta.json' |
|
||||
Where-Object { $_.Name -notlike 'pichost.db*' }
|
||||
|
||||
if (-not $metaFiles) {
|
||||
Write-Host 'No .meta.json files found under DataDir.'
|
||||
exit 0
|
||||
}
|
||||
|
||||
$patched = 0
|
||||
$skipped = 0
|
||||
$errors = 0
|
||||
|
||||
foreach ($file in $metaFiles) {
|
||||
try {
|
||||
$meta = Read-MetaJson -Path $file.FullName
|
||||
$current = $meta.PSObject.Properties['userId']
|
||||
$hasUserId = $null -ne $current -and $null -ne $current.Value
|
||||
|
||||
if ($hasUserId) {
|
||||
$skipped++
|
||||
continue
|
||||
}
|
||||
|
||||
$relative = [System.IO.Path]::GetRelativePath($DataDir, $file.FullName)
|
||||
Write-Host "[patch] $relative -> userId $UserId"
|
||||
|
||||
if ($Apply) {
|
||||
$meta | Add-Member -NotePropertyName userId -NotePropertyValue $UserId -Force
|
||||
Write-MetaJson -Path $file.FullName -Meta $meta
|
||||
}
|
||||
|
||||
$patched++
|
||||
}
|
||||
catch {
|
||||
$errors++
|
||||
Write-Warning "Failed: $($file.FullName) — $_"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "Done. patched=$patched skipped(already had userId)=$skipped errors=$errors"
|
||||
if (-not $Apply -and $patched -gt 0) {
|
||||
Write-Host 'Re-run with -Apply to write changes.'
|
||||
}
|
||||
Reference in new issue
Block a user