refactor: isolate playback and upload use cases
ci / module boundaries / boundaries (push) Successful in 6s
ci / api / api (push) Successful in 47s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m2s
ci / db / db (push) Successful in 1m4s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m30s
ci / ts / ts (packages + web) (push) Successful in 2m54s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m14s
ci / module boundaries / boundaries (push) Successful in 6s
ci / api / api (push) Successful in 47s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m2s
ci / db / db (push) Successful in 1m4s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m30s
ci / ts / ts (packages + web) (push) Successful in 2m54s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m14s
This commit is contained in:
1 parent
c84f90e2cc
commit
e158558da3
56 files changed
+3337
-2196
No files matched your search
@@ -0,0 +1,69 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"pipu/api/internal/auth"
|
||||
"pipu/api/internal/platform/apperr"
|
||||
)
|
||||
|
||||
type ScanStore interface {
|
||||
GetSource(context.Context, uuid.UUID) (Source, error)
|
||||
RetryFailedAnalysis(context.Context) (int, error)
|
||||
}
|
||||
type ScanStarter interface {
|
||||
Start(Source, string, bool) error
|
||||
}
|
||||
|
||||
// ScanService owns explicit and scheduled scan starts.
|
||||
type ScanService struct {
|
||||
store ScanStore
|
||||
scanner ScanStarter
|
||||
board *ProgressBoard
|
||||
root func(Source) (string, error)
|
||||
}
|
||||
|
||||
// StartScan запускает скан источника в фоне.
|
||||
// RetryAnalysis возвращает в очередь треки, которые анализатор не смог обработать (например, пока диск
|
||||
// не был смонтирован).
|
||||
func (s *ScanService) RetryAnalysis(ctx context.Context) (int, error) {
|
||||
if err := requirePerm(ctx, auth.PermManageLibrary); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return s.store.RetryFailedAnalysis(ctx)
|
||||
}
|
||||
|
||||
func (s *ScanService) StartScan(ctx context.Context, id uuid.UUID, full bool) (Progress, error) {
|
||||
if err := requirePerm(ctx, auth.PermManageLibrary); err != nil {
|
||||
return Progress{}, err
|
||||
}
|
||||
src, err := s.store.GetSource(ctx, id)
|
||||
if err != nil {
|
||||
return Progress{}, notFound(err)
|
||||
}
|
||||
if err := s.startScan(src, full); err != nil {
|
||||
return Progress{}, err
|
||||
}
|
||||
p, _ := s.board.Get(id)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (s *ScanService) startScan(src Source, full bool) error {
|
||||
if src.Status != "mounted" {
|
||||
return apperr.New(http.StatusConflict, CodeSourceOffline, "source is not connected")
|
||||
}
|
||||
root, err := s.root(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.scanner.Start(src, root, full); errors.Is(err, ErrScanRunning) {
|
||||
return apperr.Conflict(CodeScanRunning, "scan is already running")
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user