tstor/src/sources/ytdlp/controller.go

111 lines
2.5 KiB
Go
Raw Normal View History

2024-06-02 19:53:33 +00:00
package ytdlp
import (
"context"
2024-06-14 22:14:44 +00:00
"os"
2024-06-02 19:53:33 +00:00
"git.kmsign.ru/royalcat/tstor/pkg/ctxbilly"
2024-06-14 22:14:44 +00:00
"git.kmsign.ru/royalcat/tstor/pkg/kvsingle"
"git.kmsign.ru/royalcat/tstor/pkg/rlog"
"git.kmsign.ru/royalcat/tstor/pkg/ytdlp"
"git.kmsign.ru/royalcat/tstor/src/tasks"
2024-06-02 19:53:33 +00:00
"github.com/royalcat/ctxio"
2024-06-02 21:20:43 +00:00
"github.com/royalcat/ctxprogress"
2024-06-02 19:53:33 +00:00
)
2024-06-14 22:14:44 +00:00
type Controller struct {
datafs ctxbilly.Filesystem
source Source
client *ytdlp.Client
cachedinfo *kvsingle.Value[string, ytdlp.Info]
}
2024-06-02 21:20:43 +00:00
2024-06-14 22:14:44 +00:00
func newYtdlpController(datafs ctxbilly.Filesystem, source Source, client *ytdlp.Client) *Controller {
return &Controller{
datafs: datafs,
source: source,
client: client,
}
}
2024-06-02 21:20:43 +00:00
2024-06-14 22:14:44 +00:00
func (c *Controller) Source() Source {
return c.source
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
const sizeApprox = 1024 * 1024 * 1024
func (c *Controller) Update(ctx context.Context, updater tasks.Updater) error {
log := updater.Logger()
ctxprogress.New(ctx)
ctxprogress.Set(ctx, ctxprogress.RangeProgress{Current: 0, Total: 10})
plst, err := c.client.Playlist(ctx, c.source.Url)
ctxprogress.Set(ctx, ctxprogress.RangeProgress{Current: 1, Total: 10})
ctxprogress.Range(ctx, plst, func(ctx context.Context, _ int, e ytdlp.Entry) bool {
if e.OriginalURL == "" {
log.Error("no URL in entry", rlog.Error(err))
return true
}
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
info, err := c.Info(ctx)
if err != nil {
log.Error("error getting info", rlog.Error(err))
return true
}
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
dwl := info.RequestedDownloads[0]
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
fileinfo, err := c.datafs.Stat(ctx, dwl.Filename)
if err != nil {
log.Error("error getting file info", rlog.Error(err))
return true
}
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
if fileinfo.Size()+sizeApprox > dwl.FilesizeApprox && fileinfo.Size()-sizeApprox < dwl.FilesizeApprox {
log.Debug("file already downloaded", "filename", dwl.Filename)
return true
}
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
file, err := c.datafs.OpenFile(ctx, dwl.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
log.Error("error opening destination file", rlog.Error(err))
return true
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
err = c.client.Download(ctx, info.OriginalURL, ctxio.IoWriter(ctx, file))
2024-06-02 19:53:33 +00:00
if err != nil {
2024-06-14 22:14:44 +00:00
return false
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
return true
})
ctxprogress.Set(ctx, ctxprogress.RangeProgress{Current: 2, Total: 2})
if err != nil {
return err
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
2024-06-02 19:53:33 +00:00
return nil
}
2024-06-14 22:14:44 +00:00
func (c *Controller) Info(ctx context.Context) (ytdlp.Info, error) {
info, found, err := c.cachedinfo.Get(ctx)
2024-06-02 19:53:33 +00:00
if err != nil {
2024-06-14 22:14:44 +00:00
return info, err
}
if found {
return info, nil
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
info, err = c.Info(ctx)
2024-06-02 19:53:33 +00:00
if err != nil {
2024-06-14 22:14:44 +00:00
return info, err
2024-06-02 19:53:33 +00:00
}
2024-06-14 22:14:44 +00:00
err = c.cachedinfo.Set(ctx, info)
if err != nil {
return info, err
}
return info, nil
}
2024-06-02 19:53:33 +00:00
2024-06-14 22:14:44 +00:00
func (c *Controller) Downloaded() error {
return nil
2024-06-02 19:53:33 +00:00
}