mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-06 21:36:37 +08:00
feat: report STRM tree batch progress
This commit is contained in:
@@ -25,15 +25,18 @@ type GenerateSTRMOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GenerateSTRMResult struct {
|
type GenerateSTRMResult struct {
|
||||||
LibraryID string `json:"library_id"`
|
LibraryID string `json:"library_id"`
|
||||||
OutputDir string `json:"output_dir"`
|
OutputDir string `json:"output_dir"`
|
||||||
Generated int `json:"generated"`
|
Generated int `json:"generated"`
|
||||||
Updated int `json:"updated"`
|
Updated int `json:"updated"`
|
||||||
Skipped int `json:"skipped"`
|
Skipped int `json:"skipped"`
|
||||||
Cleaned int `json:"cleaned"`
|
Cleaned int `json:"cleaned"`
|
||||||
Previewed int `json:"previewed,omitempty"`
|
Total int `json:"total,omitempty"`
|
||||||
Errors []string `json:"errors,omitempty"`
|
Remaining int `json:"remaining,omitempty"`
|
||||||
Items []GenerateSTRMItem `json:"items,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 {
|
type GenerateSTRMItem struct {
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ func (s *STRMService) GenerateFromTree(ctx context.Context, opts GenerateSTRMTre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := &GenerateSTRMResult{LibraryID: provider, OutputDir: outputDir}
|
result := &GenerateSTRMResult{LibraryID: provider, OutputDir: outputDir}
|
||||||
|
sources := collectSTRMTreeSources(opts)
|
||||||
|
result.Total = len(sources)
|
||||||
expectedFiles := make(map[string]struct{})
|
expectedFiles := make(map[string]struct{})
|
||||||
for _, source := range collectSTRMTreeSources(opts) {
|
for i, source := range sources {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return result, ctx.Err()
|
return result, ctx.Err()
|
||||||
@@ -57,6 +59,8 @@ func (s *STRMService) GenerateFromTree(ctx context.Context, opts GenerateSTRMTre
|
|||||||
}
|
}
|
||||||
result.addItem(item)
|
result.addItem(item)
|
||||||
if strmTreeBatchLimitReached(result, opts.BatchLimit) {
|
if strmTreeBatchLimitReached(result, opts.BatchLimit) {
|
||||||
|
result.Remaining = len(sources) - i - 1
|
||||||
|
result.BatchLimited = result.Remaining > 0
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,9 @@ func TestGenerateSTRMFromTreeBatchLimitContinuesAfterExistingFiles(t *testing.T)
|
|||||||
if first.Generated != 2 || first.Skipped != 0 {
|
if first.Generated != 2 || first.Skipped != 0 {
|
||||||
t.Fatalf("first batch = %#v, want two generated", first)
|
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) {
|
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)
|
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 {
|
if second.Generated != 1 || second.Skipped != 2 {
|
||||||
t.Fatalf("second batch = %#v, want two existing skips then next generated", second)
|
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") {
|
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)
|
t.Fatalf("second batch C.strm = %q, want generated third item", got)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ export type GenerateSTRMResult = {
|
|||||||
updated: number
|
updated: number
|
||||||
skipped: number
|
skipped: number
|
||||||
cleaned: number
|
cleaned: number
|
||||||
|
total?: number
|
||||||
|
remaining?: number
|
||||||
|
batch_limited?: boolean
|
||||||
previewed?: number
|
previewed?: number
|
||||||
errors?: string[]
|
errors?: string[]
|
||||||
items?: Array<{
|
items?: Array<{
|
||||||
|
|||||||
@@ -272,8 +272,12 @@ export function StrmGenerateResultPanel({ result }: { result: GenerateSTRMResult
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
{result.previewed ? `预检 ${result.previewed} · ` : ''}
|
{result.previewed ? `预检 ${result.previewed} · ` : ''}
|
||||||
|
{result.total ? `共 ${result.total} · ` : ''}
|
||||||
新增 {result.generated} · 更新 {result.updated} · 跳过 {result.skipped} · 清理 {result.cleaned || 0}
|
新增 {result.generated} · 更新 {result.updated} · 跳过 {result.skipped} · 清理 {result.cleaned || 0}
|
||||||
</div>
|
</div>
|
||||||
|
{result.batch_limited && (
|
||||||
|
<div className="mt-1 text-amber-600">本批已达到上限,剩余 {result.remaining || 0} 个可继续运行。</div>
|
||||||
|
)}
|
||||||
{result.errors && result.errors.length > 0 && (
|
{result.errors && result.errors.length > 0 && (
|
||||||
<div className="mt-2 text-red-500">
|
<div className="mt-2 text-red-500">
|
||||||
失败 {result.errors.length} 条:{result.errors.slice(0, 3).join(';')}
|
失败 {result.errors.length} 条:{result.errors.slice(0, 3).join(';')}
|
||||||
|
|||||||
Reference in New Issue
Block a user