Infra ADR-0004 renamed the Gitea host. Bulk replace across go.mod and all .go import paths. Build and tests pass unchanged. Closes #20 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dt6aHEDWRjkK14Voi6HnGh
53 lines
2.0 KiB
Go
53 lines
2.0 KiB
Go
package web
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"git.d-ma.be/mathias/tapir/internal/domain"
|
|
)
|
|
|
|
// Processor runs the core summarization use case for a single already-discovered
|
|
// video — resolve its transcript, summarize, deliver to the store. *usecase.Engine
|
|
// wrapped with the store satisfies it (wired in cmd/tapir). Optional on App: a nil
|
|
// Processor means queue-only — the "Summarize" button only flips the DB flag and
|
|
// the next `tapir run` does the work.
|
|
type Processor interface {
|
|
ProcessVideo(ctx context.Context, userID, videoID string) error
|
|
}
|
|
|
|
// VideoFetcher resolves an arbitrary YouTube video id to its metadata for the
|
|
// paste-a-URL flow (Feature 2). It is a Data API call, NOT the rate-limited
|
|
// caption path. Returns domain.ErrVideoNotFound for a deleted/private/typo'd id.
|
|
// cmd/tapir wires a per-user YouTube adapter; nil disables the paste route.
|
|
type VideoFetcher interface {
|
|
FetchVideo(ctx context.Context, userID, videoID string) (domain.Video, error)
|
|
}
|
|
|
|
// ProcessingSet tracks the (user, video) ids currently being summarized in-process
|
|
// so the status endpoint can show the animation until the summary lands. It is
|
|
// ephemeral (single-instance Stage-1): a restart drops it, and the DB holds the
|
|
// durable state — the summary is present, or summarize_requested is still set so
|
|
// `tapir run` retries. The zero value is ready to use; methods are concurrency-safe.
|
|
type ProcessingSet struct {
|
|
m sync.Map
|
|
}
|
|
|
|
// Add marks a key in-flight.
|
|
func (p *ProcessingSet) Add(key string) { p.m.Store(key, struct{}{}) }
|
|
|
|
// Remove clears a key once its summarization finishes (success or failure).
|
|
func (p *ProcessingSet) Remove(key string) { p.m.Delete(key) }
|
|
|
|
// Has reports whether a key is currently in-flight.
|
|
func (p *ProcessingSet) Has(key string) bool {
|
|
_, ok := p.m.Load(key)
|
|
return ok
|
|
}
|
|
|
|
// processingKey scopes the in-flight key by user so one user's summarization is
|
|
// never confused with another's for the same video id.
|
|
func processingKey(userID, videoID string) string {
|
|
return userID + "|" + videoID
|
|
}
|