Добавил ручную перепривязку
This commit is contained in:
@@ -92,6 +92,7 @@ func NewRouter(d Deps) (http.Handler, error) {
|
||||
r.Post("/ui/downloads/{id}/nobase", s.handleNoBase)
|
||||
r.Post("/ui/downloads/{id}/defer", s.handleDefer)
|
||||
r.Post("/ui/downloads/{id}/undo", s.handleUndo)
|
||||
r.Post("/ui/downloads/{id}/relink", s.handleRelink)
|
||||
|
||||
// REST API.
|
||||
r.Route("/api", func(r chi.Router) {
|
||||
@@ -126,6 +127,7 @@ type downloadView struct {
|
||||
Terminal bool
|
||||
Reviewable bool // review/deferred — есть экран ревью
|
||||
Undoable bool // done — можно откатить раскладку
|
||||
Relinkable bool // reverted — можно перепривязать заново
|
||||
}
|
||||
|
||||
func (s *server) handleIndex(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -304,6 +306,7 @@ func toView(d store.Download) downloadView {
|
||||
Terminal: d.State.IsTerminal(),
|
||||
Reviewable: d.State == store.StateReview || d.State == store.StateDeferred,
|
||||
Undoable: d.State == store.StateDone,
|
||||
Relinkable: d.State == store.StateReverted,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ type fakeReviewer struct {
|
||||
applied []int64
|
||||
deferred []int64
|
||||
undone []int64
|
||||
relinked []int64
|
||||
cleared []int64
|
||||
}
|
||||
|
||||
@@ -235,6 +236,10 @@ func (f *fakeReviewer) Undo(_ context.Context, id int64) error {
|
||||
f.undone = append(f.undone, id)
|
||||
return nil
|
||||
}
|
||||
func (f *fakeReviewer) Relink(_ context.Context, id int64) error {
|
||||
f.relinked = append(f.relinked, id)
|
||||
return nil
|
||||
}
|
||||
func (f *fakeReviewer) ChooseCandidate(_ context.Context, id, candidateID int64) error {
|
||||
if f.chosen == nil {
|
||||
f.chosen = map[int64]int64{}
|
||||
@@ -444,3 +449,17 @@ func TestUndoAndDefer(t *testing.T) {
|
||||
t.Errorf("undo=%v defer=%v", rv.undone, rv.deferred)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRelink(t *testing.T) {
|
||||
rv := &fakeReviewer{data: seriesReviewData()}
|
||||
srv := newServer(t, httpapi.Deps{Ingestor: &fakeIngestor{}, Commander: &fakeCommander{},
|
||||
Reader: &fakeReader{}, Reviewer: rv})
|
||||
cl := noRedirectClient()
|
||||
|
||||
if _, err := cl.Post(srv.URL+"/ui/downloads/1/relink", "", nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rv.relinked) != 1 || rv.relinked[0] != 1 {
|
||||
t.Errorf("relinked = %v, want [1]", rv.relinked)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ type Reviewer interface {
|
||||
IgnoreFile(ctx context.Context, id int64, src string) error
|
||||
Defer(ctx context.Context, id int64) error
|
||||
Undo(ctx context.Context, id int64) error
|
||||
Relink(ctx context.Context, id int64) error
|
||||
ChooseCandidate(ctx context.Context, id, candidateID int64) error
|
||||
SetProviderID(ctx context.Context, id int64, provider, providerID string) error
|
||||
ClearProvider(ctx context.Context, id int64) error
|
||||
@@ -233,6 +234,22 @@ func (s *server) handleUndo(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// handleRelink повторно привязывает откатанную задачу: перезапускает
|
||||
// распознавание, задача пройдёт recognizing → review для подтверждения.
|
||||
func (s *server) handleRelink(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := pathID(r)
|
||||
if err != nil {
|
||||
redirectErr(w, r, "некорректный id")
|
||||
return
|
||||
}
|
||||
if err := s.deps.Reviewer.Relink(r.Context(), id); err != nil {
|
||||
s.deps.Logger.Warn("review action failed", "action", "relink", "id", id, "err", err)
|
||||
redirectErr(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// reviewAction — общий помощник: выполнить действие и вернуться на страницу
|
||||
// ревью (с ошибкой в ?err при неудаче).
|
||||
func (s *server) reviewAction(w http.ResponseWriter, r *http.Request, fn func(context.Context, int64) error) {
|
||||
|
||||
Reference in New Issue
Block a user