layout: непомещающееся целевое имя уводит задачу в review вместо failed
- предел длины компонента (255 байт) проверяется в BuildLinks до первой операции с ФС: ни каталога, ни ссылки при отказе не создаётся - причина пустого предпросмотра считается на показе (ReviewData.PreviewError) и печатается в панели действий и в карточке Telegram: у задачи без записанной причины взять её больше неоткуда
This commit is contained in:
+30
-10
@@ -325,7 +325,15 @@ func (w *Worker) linkPlan(ctx context.Context, d *store.Download, plan recognize
|
||||
|
||||
links, err := w.layouter.BuildLinks(toLayoutPlan(plan, savePath, providerTag(provider, providerID), folderBase))
|
||||
if err != nil {
|
||||
w.transition(ctx, *d, store.StateReview, reasonBuild, err.Error())
|
||||
// Непомещающееся имя — свой код причины: этот отказ человек чинит
|
||||
// подсказкой названия, а прочие отказы построения (пустое название,
|
||||
// серия без номера) — нет, и слепить их в один код значило бы потерять
|
||||
// эту разницу.
|
||||
code := reasonBuild
|
||||
if errors.Is(err, layout.ErrNameTooLong) {
|
||||
code = reasonNameTooLong
|
||||
}
|
||||
w.transition(ctx, *d, store.StateReview, code, err.Error())
|
||||
return fmt.Errorf("build links: %w", err)
|
||||
}
|
||||
|
||||
@@ -953,14 +961,21 @@ func candMediaType(rec *store.Recognition) recognize.MediaType {
|
||||
type ReviewData struct {
|
||||
Download store.Download
|
||||
Recognition *store.Recognition
|
||||
Plan recognize.Plan // эффективный (с применёнными правками)
|
||||
Preview []layout.Link // целевые пути активного источника (Src — относительный)
|
||||
Candidates []store.MetadataCandidate // кандидаты базы для ручного выбора
|
||||
Sources []SourceOption // единый список источников совпадения (нейронка + кандидаты)
|
||||
Provider string // эффективный провайдер (с учётом выбора)
|
||||
ProviderID string // эффективный id в базе
|
||||
Hints []string
|
||||
Overrides map[string]string
|
||||
Plan recognize.Plan // эффективный (с применёнными правками)
|
||||
Preview []layout.Link // целевые пути активного источника (Src — относительный)
|
||||
// PreviewError — почему предпросмотр не построился, человекочитаемо (пусто —
|
||||
// построился либо строить было нечего). Считается НА ПОКАЗЕ, поэтому всегда
|
||||
// относится к текущему эффективному плану — в отличие от error_msg загрузки,
|
||||
// который остался от последнего перехода и после смены источника устаревает.
|
||||
// Задача в review без записанной причины (обычный «нет матча») иначе оставила
|
||||
// бы экран без объяснения, почему пропала кнопка «Применить».
|
||||
PreviewError string
|
||||
Candidates []store.MetadataCandidate // кандидаты базы для ручного выбора
|
||||
Sources []SourceOption // единый список источников совпадения (нейронка + кандидаты)
|
||||
Provider string // эффективный провайдер (с учётом выбора)
|
||||
ProviderID string // эффективный id в базе
|
||||
Hints []string
|
||||
Overrides map[string]string
|
||||
}
|
||||
|
||||
// MatchURL — ссылка на подтверждённую запись метабазы для этой загрузки. Общий
|
||||
@@ -1082,8 +1097,12 @@ func (w *Worker) ReviewData(ctx context.Context, id string) (*ReviewData, error)
|
||||
rd.Preview = links
|
||||
} else {
|
||||
// Видимая деградация: без превью на экране ревью пропадает
|
||||
// кнопка «Применить» — не рядовой Debug, а WARN.
|
||||
// кнопка «Применить» — не рядовой Debug, а WARN. Причину
|
||||
// отдаём транспорту: молча пропавшая кнопка неотличима от
|
||||
// поломки, а у задачи без записанной причины взять её больше
|
||||
// неоткуда.
|
||||
log.Warn("review data build preview failed", "error", lerr)
|
||||
rd.PreviewError = lerr.Error()
|
||||
}
|
||||
}
|
||||
// Единый список источников: нейронка + кандидаты, каждый с
|
||||
@@ -1267,6 +1286,7 @@ const (
|
||||
reasonBuild = "build" // не удалось построить план ссылок
|
||||
reasonPersist = "persist" // ссылки на диске, но учёт не записан
|
||||
reasonCollision = "collision" // целевой путь уже занят (layout.ErrCollision)
|
||||
reasonNameTooLong = "name_too_long" // компонент целевого пути длиннее предела (layout.ErrNameTooLong)
|
||||
reasonTitleFolderDesync = "title_folder_desync" // ≥2 разных живых папок тайтла с одним матчем
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user