141 lines
2.9 KiB
Go
141 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"math"
|
|
|
|
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/subscription/data"
|
|
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/subscription/domain"
|
|
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/subscription/task"
|
|
"github.com/robfig/cron/v3"
|
|
)
|
|
|
|
type Service struct {
|
|
r domain.Repository
|
|
runner task.TaskRunner
|
|
}
|
|
|
|
func New(r domain.Repository, runner task.TaskRunner) domain.Service {
|
|
s := &Service{
|
|
r: r,
|
|
runner: runner,
|
|
}
|
|
|
|
// very crude recoverer
|
|
initial, _ := s.List(context.Background(), 0, math.MaxInt)
|
|
if initial != nil {
|
|
for _, v := range initial.Data {
|
|
s.runner.Submit(&v)
|
|
}
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
func fromDB(model *data.Subscription) domain.Subscription {
|
|
return domain.Subscription{
|
|
Id: model.Id,
|
|
URL: model.URL,
|
|
Params: model.Params,
|
|
CronExpr: model.CronExpr,
|
|
}
|
|
}
|
|
|
|
func toDB(dto *domain.Subscription) data.Subscription {
|
|
return data.Subscription{
|
|
Id: dto.Id,
|
|
URL: dto.URL,
|
|
Params: dto.Params,
|
|
CronExpr: dto.CronExpr,
|
|
}
|
|
}
|
|
|
|
// Delete implements domain.Service.
|
|
func (s *Service) Delete(ctx context.Context, id string) error {
|
|
return s.r.Delete(ctx, id)
|
|
}
|
|
|
|
// GetCursor implements domain.Service.
|
|
func (s *Service) GetCursor(ctx context.Context, id string) (int64, error) {
|
|
return s.r.GetCursor(ctx, id)
|
|
}
|
|
|
|
// List implements domain.Service.
|
|
func (s *Service) List(ctx context.Context, start int64, limit int) (
|
|
*domain.PaginatedResponse[[]domain.Subscription],
|
|
error,
|
|
) {
|
|
dbSubs, err := s.r.List(ctx, start, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
subs := make([]domain.Subscription, len(*dbSubs))
|
|
|
|
for i, v := range *dbSubs {
|
|
subs[i] = fromDB(&v)
|
|
}
|
|
|
|
var (
|
|
first int64
|
|
next int64
|
|
)
|
|
|
|
if len(subs) > 0 {
|
|
first, err = s.r.GetCursor(ctx, subs[0].Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
next, err = s.r.GetCursor(ctx, subs[len(subs)-1].Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return &domain.PaginatedResponse[[]domain.Subscription]{
|
|
First: first,
|
|
Next: next,
|
|
Data: subs,
|
|
}, nil
|
|
}
|
|
|
|
// Submit implements domain.Service.
|
|
func (s *Service) Submit(ctx context.Context, sub *domain.Subscription) (*domain.Subscription, error) {
|
|
if sub.CronExpr == "" {
|
|
sub.CronExpr = "*/5 * * * *"
|
|
}
|
|
|
|
_, err := cron.ParseStandard(sub.CronExpr)
|
|
if err != nil {
|
|
return nil, errors.Join(errors.New("failed parsing cron expression"), err)
|
|
}
|
|
|
|
subDB, err := s.r.Submit(ctx, &data.Subscription{
|
|
URL: sub.URL,
|
|
Params: sub.Params,
|
|
CronExpr: sub.CronExpr,
|
|
})
|
|
|
|
retval := fromDB(subDB)
|
|
|
|
if err := s.runner.Submit(sub); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &retval, err
|
|
}
|
|
|
|
// UpdateByExample implements domain.Service.
|
|
func (s *Service) UpdateByExample(ctx context.Context, example *domain.Subscription) error {
|
|
_, err := cron.ParseStandard(example.CronExpr)
|
|
if err != nil {
|
|
return errors.Join(errors.New("failed parsing cron expression"), err)
|
|
}
|
|
|
|
e := toDB(example)
|
|
|
|
return s.r.UpdateByExample(ctx, &e)
|
|
}
|