feat: report STRM tree batch progress

This commit is contained in:
ShukeBta
2026-07-02 21:48:53 +08:00
parent 87928cfa4d
commit 1afc69baa0
5 changed files with 30 additions and 10 deletions
+12 -9
View File
@@ -25,15 +25,18 @@ type GenerateSTRMOptions struct {
}
type GenerateSTRMResult struct {
LibraryID string `json:"library_id"`
OutputDir string `json:"output_dir"`
Generated int `json:"generated"`
Updated int `json:"updated"`
Skipped int `json:"skipped"`
Cleaned int `json:"cleaned"`
Previewed int `json:"previewed,omitempty"`
Errors []string `json:"errors,omitempty"`
Items []GenerateSTRMItem `json:"items,omitempty"`
LibraryID string `json:"library_id"`
OutputDir string `json:"output_dir"`
Generated int `json:"generated"`
Updated int `json:"updated"`
Skipped int `json:"skipped"`
Cleaned int `json:"cleaned"`
Total int `json:"total,omitempty"`
Remaining int `json:"remaining,omitempty"`
BatchLimited bool `json:"batch_limited,omitempty"`
Previewed int `json:"previewed,omitempty"`
Errors []string `json:"errors,omitempty"`
Items []GenerateSTRMItem `json:"items,omitempty"`
}
type GenerateSTRMItem struct {
+5 -1
View File
@@ -44,8 +44,10 @@ func (s *STRMService) GenerateFromTree(ctx context.Context, opts GenerateSTRMTre
}
}
result := &GenerateSTRMResult{LibraryID: provider, OutputDir: outputDir}
sources := collectSTRMTreeSources(opts)
result.Total = len(sources)
expectedFiles := make(map[string]struct{})
for _, source := range collectSTRMTreeSources(opts) {
for i, source := range sources {
select {
case <-ctx.Done():
return result, ctx.Err()
@@ -57,6 +59,8 @@ func (s *STRMService) GenerateFromTree(ctx context.Context, opts GenerateSTRMTre
}
result.addItem(item)
if strmTreeBatchLimitReached(result, opts.BatchLimit) {
result.Remaining = len(sources) - i - 1
result.BatchLimited = result.Remaining > 0
break
}
}
@@ -155,6 +155,9 @@ func TestGenerateSTRMFromTreeBatchLimitContinuesAfterExistingFiles(t *testing.T)
if first.Generated != 2 || first.Skipped != 0 {
t.Fatalf("first batch = %#v, want two generated", first)
}
if first.Total != 3 || first.Remaining != 1 || !first.BatchLimited {
t.Fatalf("first batch progress = total %d remaining %d limited %v, want 3/1/true", first.Total, first.Remaining, first.BatchLimited)
}
if _, err := os.Stat(filepath.Join(outDir, "Movies", "C.strm")); !os.IsNotExist(err) {
t.Fatalf("first batch should not write third item, stat err=%v", err)
}
@@ -166,6 +169,9 @@ func TestGenerateSTRMFromTreeBatchLimitContinuesAfterExistingFiles(t *testing.T)
if second.Generated != 1 || second.Skipped != 2 {
t.Fatalf("second batch = %#v, want two existing skips then next generated", second)
}
if second.Total != 3 || second.Remaining != 0 || second.BatchLimited {
t.Fatalf("second batch progress = total %d remaining %d limited %v, want 3/0/false", second.Total, second.Remaining, second.BatchLimited)
}
if got := readSTRM(t, filepath.Join(outDir, "Movies", "C.strm")); !strings.Contains(got, "C.mkv") {
t.Fatalf("second batch C.strm = %q, want generated third item", got)
}
+3
View File
@@ -17,6 +17,9 @@ export type GenerateSTRMResult = {
updated: number
skipped: number
cleaned: number
total?: number
remaining?: number
batch_limited?: boolean
previewed?: number
errors?: string[]
items?: Array<{
@@ -272,8 +272,12 @@ export function StrmGenerateResultPanel({ result }: { result: GenerateSTRMResult
</div>
<div className="mt-1">
{result.previewed ? `预检 ${result.previewed} · ` : ''}
{result.total ? `共 ${result.total} · ` : ''}
新增 {result.generated} · 更新 {result.updated} · 跳过 {result.skipped} · 清理 {result.cleaned || 0}
</div>
{result.batch_limited && (
<div className="mt-1 text-amber-600">本批已达到上限,剩余 {result.remaining || 0} 个可继续运行。</div>
)}
{result.errors && result.errors.length > 0 && (
<div className="mt-2 text-red-500">
失败 {result.errors.length} 条:{result.errors.slice(0, 3).join(';')}