Добавил логи
This commit is contained in:
+35
-22
@@ -81,14 +81,14 @@ func (w *Worker) recognizeOne(ctx context.Context, id int64) {
|
||||
// относительных путей файлов в абсолютные при раскладке.
|
||||
func (w *Worker) runRecognize(ctx context.Context, d store.Download) (recognize.Result, string, error) {
|
||||
if !d.Infohash.Valid {
|
||||
return recognize.Result{}, "", fmt.Errorf("нет infohash")
|
||||
return recognize.Result{}, "", fmt.Errorf("no infohash")
|
||||
}
|
||||
t, ok, err := w.torrentByInfohash(ctx, d.Infohash.String)
|
||||
if err != nil {
|
||||
return recognize.Result{}, "", err
|
||||
}
|
||||
if !ok {
|
||||
return recognize.Result{}, "", fmt.Errorf("торрент не найден в qBittorrent")
|
||||
return recognize.Result{}, "", fmt.Errorf("torrent not found in qBittorrent")
|
||||
}
|
||||
files, err := w.qbt.Files(ctx, t.Hash)
|
||||
if err != nil {
|
||||
@@ -209,7 +209,7 @@ func (w *Worker) Apply(ctx context.Context, id int64) error {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if w.layouter == nil {
|
||||
return fmt.Errorf("apply: раскладчик не сконфигурирован")
|
||||
return fmt.Errorf("apply: layouter not configured")
|
||||
}
|
||||
|
||||
d, err := w.store.GetDownload(ctx, id)
|
||||
@@ -217,7 +217,7 @@ func (w *Worker) Apply(ctx context.Context, id int64) error {
|
||||
return fmt.Errorf("apply: %w", err)
|
||||
}
|
||||
if d.State != store.StateReview && d.State != store.StateDeferred {
|
||||
return fmt.Errorf("apply: задача %d в состоянии %s (ожидалось review/deferred)", id, d.State)
|
||||
return fmt.Errorf("apply: download %d is in state %s (expected review/deferred)", id, d.State)
|
||||
}
|
||||
|
||||
plan, tag, err := w.effectivePlan(ctx, id)
|
||||
@@ -226,7 +226,7 @@ func (w *Worker) Apply(ctx context.Context, id int64) error {
|
||||
}
|
||||
t, ok, err := w.torrentByInfohash(ctx, d.Infohash.String)
|
||||
if err != nil || !ok {
|
||||
return fmt.Errorf("apply: торрент не найден: %v", err)
|
||||
return fmt.Errorf("apply: torrent not found: %v", err)
|
||||
}
|
||||
|
||||
w.transition(ctx, *d, store.StateLinking, "", "")
|
||||
@@ -243,7 +243,7 @@ func (w *Worker) linkPlan(ctx context.Context, d *store.Download, plan recognize
|
||||
links, err := w.layouter.BuildLinks(toLayoutPlan(plan, savePath, providerTag))
|
||||
if err != nil {
|
||||
w.transition(ctx, *d, store.StateReview, "build", err.Error())
|
||||
return fmt.Errorf("построение ссылок: %w", err)
|
||||
return fmt.Errorf("build links: %w", err)
|
||||
}
|
||||
|
||||
batch := w.newID()
|
||||
@@ -263,7 +263,7 @@ func (w *Worker) linkPlan(ctx context.Context, d *store.Download, plan recognize
|
||||
}
|
||||
if len(fl) > 0 {
|
||||
if err := w.store.CreateFileLinks(ctx, fl); err != nil {
|
||||
return fmt.Errorf("запись ссылок: %w", err)
|
||||
return fmt.Errorf("persist links: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ func (w *Worker) linkPlan(ctx context.Context, d *store.Download, plan recognize
|
||||
func (w *Worker) Refine(ctx context.Context, id int64, hint string) error {
|
||||
hint = strings.TrimSpace(hint)
|
||||
if hint == "" {
|
||||
return fmt.Errorf("refine: пустая подсказка")
|
||||
return fmt.Errorf("refine: empty hint")
|
||||
}
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
@@ -297,6 +297,7 @@ func (w *Worker) Refine(ctx context.Context, id int64, hint string) error {
|
||||
if err := w.store.AddHint(ctx, id, hint); err != nil {
|
||||
return fmt.Errorf("refine: %w", err)
|
||||
}
|
||||
w.log.Info("review: hint added, re-recognizing", "download_id", id, "hint", hint)
|
||||
w.transition(ctx, *d, store.StateRecognizing, "", "")
|
||||
return nil
|
||||
}
|
||||
@@ -305,7 +306,7 @@ func (w *Worker) Refine(ctx context.Context, id int64, hint string) error {
|
||||
// — чтобы LLM пересобрал роли файлов под новый тип.
|
||||
func (w *Worker) SetType(ctx context.Context, id int64, mediaType string) error {
|
||||
if mediaType != string(recognize.MediaMovie) && mediaType != string(recognize.MediaSeries) {
|
||||
return fmt.Errorf("set type: недопустимый тип %q", mediaType)
|
||||
return fmt.Errorf("set type: invalid type %q", mediaType)
|
||||
}
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
@@ -333,7 +334,7 @@ func (w *Worker) SetType(ctx context.Context, id int64, mediaType string) error
|
||||
func (w *Worker) IgnoreFile(ctx context.Context, id int64, src string) error {
|
||||
src = strings.TrimSpace(src)
|
||||
if src == "" {
|
||||
return fmt.Errorf("ignore: пустой путь")
|
||||
return fmt.Errorf("ignore: empty path")
|
||||
}
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
@@ -353,6 +354,7 @@ func (w *Worker) IgnoreFile(ctx context.Context, id int64, src string) error {
|
||||
if err := w.store.SetOverride(ctx, id, ovrIgnoredFiles, string(b)); err != nil {
|
||||
return fmt.Errorf("ignore: %w", err)
|
||||
}
|
||||
w.log.Info("review: file ignored", "download_id", id, "src", src)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -366,7 +368,7 @@ func (w *Worker) Defer(ctx context.Context, id int64) error {
|
||||
return fmt.Errorf("defer: %w", err)
|
||||
}
|
||||
if d.State.IsTerminal() {
|
||||
return fmt.Errorf("defer: задача %d терминальна (%s)", id, d.State)
|
||||
return fmt.Errorf("defer: download %d is terminal (%s)", id, d.State)
|
||||
}
|
||||
w.transition(ctx, *d, store.StateDeferred, "", "")
|
||||
return nil
|
||||
@@ -378,7 +380,7 @@ func (w *Worker) Undo(ctx context.Context, id int64) error {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if w.layouter == nil {
|
||||
return fmt.Errorf("undo: раскладчик не сконфигурирован")
|
||||
return fmt.Errorf("undo: layouter not configured")
|
||||
}
|
||||
|
||||
d, err := w.store.GetDownload(ctx, id)
|
||||
@@ -386,14 +388,14 @@ func (w *Worker) Undo(ctx context.Context, id int64) error {
|
||||
return fmt.Errorf("undo: %w", err)
|
||||
}
|
||||
if d.State != store.StateDone {
|
||||
return fmt.Errorf("undo: задача %d в состоянии %s (ожидалось done)", id, d.State)
|
||||
return fmt.Errorf("undo: download %d is in state %s (expected done)", id, d.State)
|
||||
}
|
||||
batch, err := w.store.LatestBatchID(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("undo: %w", err)
|
||||
}
|
||||
if batch == "" {
|
||||
return fmt.Errorf("undo: нечего откатывать")
|
||||
return fmt.Errorf("undo: nothing to revert")
|
||||
}
|
||||
rows, err := w.store.ListFileLinksByBatch(ctx, batch)
|
||||
if err != nil {
|
||||
@@ -422,7 +424,7 @@ func (w *Worker) requireReviewable(ctx context.Context, id int64, op string) (*s
|
||||
return nil, fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
if d.State != store.StateReview && d.State != store.StateDeferred {
|
||||
return nil, fmt.Errorf("%s: задача %d в состоянии %s (ожидалось review/deferred)", op, id, d.State)
|
||||
return nil, fmt.Errorf("%s: download %d is in state %s (expected review/deferred)", op, id, d.State)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
@@ -448,7 +450,7 @@ func (w *Worker) ChooseCandidate(ctx context.Context, id, candidateID int64) err
|
||||
return fmt.Errorf("choose candidate: %w", err)
|
||||
}
|
||||
if rec == nil || cand == nil || cand.RecognitionID != rec.ID {
|
||||
return fmt.Errorf("choose candidate: кандидат %d не относится к текущему распознаванию", candidateID)
|
||||
return fmt.Errorf("choose candidate: candidate %d does not belong to the current recognition", candidateID)
|
||||
}
|
||||
|
||||
pins := map[string]string{ovrProvider: cand.Provider, ovrProviderID: cand.ProviderID}
|
||||
@@ -478,10 +480,10 @@ func (w *Worker) SetProviderID(ctx context.Context, id int64, provider, provider
|
||||
switch provider {
|
||||
case "tmdb", "tvdb", "imdb":
|
||||
default:
|
||||
return fmt.Errorf("set provider: недопустимый провайдер %q (tmdb/tvdb/imdb)", provider)
|
||||
return fmt.Errorf("set provider: invalid provider %q (tmdb/tvdb/imdb)", provider)
|
||||
}
|
||||
if providerID == "" {
|
||||
return fmt.Errorf("set provider: пустой id")
|
||||
return fmt.Errorf("set provider: empty id")
|
||||
}
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
@@ -495,6 +497,8 @@ func (w *Worker) SetProviderID(ctx context.Context, id int64, provider, provider
|
||||
if err := w.store.SetOverride(ctx, id, ovrProviderID, providerID); err != nil {
|
||||
return fmt.Errorf("set provider: %w", err)
|
||||
}
|
||||
w.log.Info("review: provider set manually",
|
||||
"download_id", id, "provider", provider, "provider_id", providerID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -512,6 +516,7 @@ func (w *Worker) ClearProvider(ctx context.Context, id int64) error {
|
||||
if err := w.store.SetOverride(ctx, id, ovrProviderID, ""); err != nil {
|
||||
return fmt.Errorf("clear provider: %w", err)
|
||||
}
|
||||
w.log.Info("review: provider cleared (no metadata base)", "download_id", id)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -557,19 +562,27 @@ func (w *Worker) ReviewData(ctx context.Context, id int64) (*ReviewData, error)
|
||||
if rec != nil {
|
||||
if cands, cerr := w.store.ListCandidatesByRecognition(ctx, rec.ID); cerr == nil {
|
||||
rd.Candidates = cands
|
||||
} else {
|
||||
w.log.Debug("review data: list candidates failed (skipped)",
|
||||
"download_id", id, "err", cerr)
|
||||
}
|
||||
}
|
||||
if rec != nil && rec.Plan.Valid {
|
||||
var plan recognize.Plan
|
||||
if err := json.Unmarshal([]byte(rec.Plan.String), &plan); err == nil {
|
||||
if err := json.Unmarshal([]byte(rec.Plan.String), &plan); err != nil {
|
||||
w.log.Warn("review data: unmarshal plan failed", "download_id", id, "err", err)
|
||||
} else {
|
||||
plan = applyOverrides(plan, overrides)
|
||||
rd.Plan = plan
|
||||
// Превью строим по относительным путям с provider-тегом; ошибку
|
||||
// игнорируем — просто покажем причины без превью.
|
||||
// логируем на Debug — просто покажем причины без превью.
|
||||
if w.layouter != nil {
|
||||
tag := providerTag(prov, pid)
|
||||
if links, lerr := w.layouter.BuildLinks(toLayoutPlan(plan, "", tag)); lerr == nil {
|
||||
rd.Preview = links
|
||||
} else {
|
||||
w.log.Debug("review data: build preview failed (skipped)",
|
||||
"download_id", id, "err", lerr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,11 +598,11 @@ func (w *Worker) effectivePlan(ctx context.Context, id int64) (recognize.Plan, s
|
||||
return recognize.Plan{}, "", err
|
||||
}
|
||||
if rec == nil || !rec.Plan.Valid {
|
||||
return recognize.Plan{}, "", fmt.Errorf("нет плана распознавания")
|
||||
return recognize.Plan{}, "", fmt.Errorf("no recognition plan")
|
||||
}
|
||||
var plan recognize.Plan
|
||||
if err := json.Unmarshal([]byte(rec.Plan.String), &plan); err != nil {
|
||||
return recognize.Plan{}, "", fmt.Errorf("разбор плана: %w", err)
|
||||
return recognize.Plan{}, "", fmt.Errorf("parse plan: %w", err)
|
||||
}
|
||||
overrides, err := w.store.ListOverrides(ctx, id)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user