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-16 21:34:46 +00:00
|
|
|
"github.com/royalcat/kv"
|
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) {
|
2024-06-16 21:34:46 +00:00
|
|
|
info, err := c.cachedinfo.Get(ctx)
|
|
|
|
if err == nil {
|
2024-06-14 22:14:44 +00:00
|
|
|
return info, nil
|
2024-06-02 19:53:33 +00:00
|
|
|
}
|
2024-06-16 21:34:46 +00:00
|
|
|
if err != kv.ErrKeyNotFound {
|
|
|
|
return info, err
|
|
|
|
}
|
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
|
|
|
}
|