Implementing a streaming setup with Usenet
This commit is contained in:
145
pkg/usenet/processor.go
Normal file
145
pkg/usenet/processor.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package usenet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/sirrobot01/decypharr/internal/config"
|
||||
"github.com/sirrobot01/decypharr/internal/nntp"
|
||||
"github.com/sirrobot01/decypharr/pkg/arr"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Processor handles NZB processing and download orchestration
|
||||
type Processor struct {
|
||||
store Store
|
||||
parser *NZBParser
|
||||
downloadWorker *DownloadWorker
|
||||
logger zerolog.Logger
|
||||
client *nntp.Client
|
||||
}
|
||||
|
||||
// ProcessRequest represents a request to process an NZB
|
||||
type ProcessRequest struct {
|
||||
NZBContent []byte
|
||||
Name string
|
||||
Arr *arr.Arr
|
||||
Action string // "download", "symlink", "none"
|
||||
DownloadDir string
|
||||
}
|
||||
|
||||
// NewProcessor creates a new usenet processor
|
||||
func NewProcessor(config *config.Usenet, logger zerolog.Logger, store Store, client *nntp.Client) (*Processor, error) {
|
||||
processor := &Processor{
|
||||
store: store,
|
||||
logger: logger.With().Str("component", "usenet-processor").Logger(),
|
||||
client: client,
|
||||
}
|
||||
|
||||
// Initialize download worker
|
||||
processor.downloadWorker = NewDownloadWorker(config, client, processor)
|
||||
processor.parser = NewNZBParser(client, nil, processor.logger)
|
||||
|
||||
return processor, nil
|
||||
}
|
||||
|
||||
// Process processes an NZB for download/streaming
|
||||
func (p *Processor) Process(ctx context.Context, req *ProcessRequest) (*NZB, error) {
|
||||
if len(req.NZBContent) == 0 {
|
||||
return nil, fmt.Errorf("NZB content is empty")
|
||||
}
|
||||
|
||||
// Validate NZB content
|
||||
if err := ValidateNZB(req.NZBContent); err != nil {
|
||||
return nil, fmt.Errorf("invalid NZB content: %w", err)
|
||||
}
|
||||
nzb, err := p.process(ctx, req)
|
||||
if err != nil {
|
||||
p.logger.Error().
|
||||
Err(err).
|
||||
Msg("Failed to process NZB content")
|
||||
return nil, fmt.Errorf("failed to process NZB content: %w", err)
|
||||
}
|
||||
return nzb, nil
|
||||
}
|
||||
|
||||
func (p *Processor) process(ctx context.Context, req *ProcessRequest) (*NZB, error) {
|
||||
nzb, err := p.parser.Parse(ctx, req.Name, req.Arr.Name, req.NZBContent)
|
||||
if err != nil {
|
||||
p.logger.Error().
|
||||
Err(err).
|
||||
Msg("Failed to parse NZB content")
|
||||
return nil, fmt.Errorf("failed to parse NZB content: %w", err)
|
||||
}
|
||||
if nzb == nil {
|
||||
p.logger.Error().
|
||||
Msg("Parsed NZB is nil")
|
||||
return nil, fmt.Errorf("parsed NZB is nil")
|
||||
}
|
||||
p.logger.Info().
|
||||
Str("nzb_id", nzb.ID).
|
||||
Msg("Successfully parsed NZB content")
|
||||
|
||||
if existing := p.store.Get(nzb.ID); existing != nil {
|
||||
p.logger.Info().Str("nzb_id", nzb.ID).Msg("NZB already exists")
|
||||
return existing, nil
|
||||
}
|
||||
|
||||
p.logger.Info().
|
||||
Str("nzb_id", nzb.ID).
|
||||
Msg("Creating new NZB download job")
|
||||
|
||||
downloadDir := req.DownloadDir
|
||||
if req.Arr != nil {
|
||||
downloadDir = filepath.Join(downloadDir, req.Arr.Name)
|
||||
}
|
||||
|
||||
job := &DownloadJob{
|
||||
NZB: nzb,
|
||||
Action: req.Action,
|
||||
DownloadDir: downloadDir,
|
||||
Callback: func(completedNZB *NZB, err error) {
|
||||
if err != nil {
|
||||
p.logger.Error().
|
||||
Err(err).
|
||||
Str("nzb_id", completedNZB.ID).
|
||||
Msg("Download job failed")
|
||||
return
|
||||
}
|
||||
p.logger.Info().
|
||||
Str("nzb_id", completedNZB.ID).
|
||||
Msg("Download job completed successfully")
|
||||
},
|
||||
}
|
||||
// Check availability before submitting the job
|
||||
//if err := p.downloadWorker.CheckAvailability(ctx, job); err != nil {
|
||||
// p.logger.Error().
|
||||
// Err(err).
|
||||
// Str("nzb_id", nzb.ID).
|
||||
// Msg("NZB availability check failed")
|
||||
// return nil, fmt.Errorf("availability check failed for NZB %s: %w", nzb.ID, err)
|
||||
//}
|
||||
// Mark NZB as downloaded but not completed
|
||||
nzb.Downloaded = true
|
||||
nzb.AddedOn = time.Now()
|
||||
p.store.AddToQueue(nzb)
|
||||
|
||||
if err := p.store.Add(nzb); err != nil {
|
||||
return nil, err
|
||||
} // Add the downloaded NZB to the store asynchronously
|
||||
p.logger.Info().
|
||||
Str("nzb_id", nzb.ID).
|
||||
Msg("NZB added to queue")
|
||||
|
||||
go func() {
|
||||
if err := p.downloadWorker.Process(ctx, job); err != nil {
|
||||
p.logger.Error().
|
||||
Err(err).
|
||||
Str("nzb_id", nzb.ID).
|
||||
Msg("Failed to submit download job")
|
||||
}
|
||||
}()
|
||||
|
||||
return nzb, nil
|
||||
}
|
||||
Reference in New Issue
Block a user