2024-06-02 19:53:33 +00:00
|
|
|
package ytdlp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"path"
|
|
|
|
"sync"
|
2024-06-02 21:20:43 +00:00
|
|
|
"time"
|
2024-06-02 19:53:33 +00:00
|
|
|
|
|
|
|
"git.kmsign.ru/royalcat/tstor/pkg/ctxbilly"
|
|
|
|
"git.kmsign.ru/royalcat/tstor/src/vfs"
|
|
|
|
"github.com/go-git/go-billy/v5/osfs"
|
|
|
|
"github.com/royalcat/ctxio"
|
2024-06-02 21:20:43 +00:00
|
|
|
"github.com/royalcat/ctxprogress"
|
2024-06-02 19:53:33 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func NewService(dataDir string) *Service {
|
2024-06-02 21:20:43 +00:00
|
|
|
s := &Service{
|
2024-06-02 19:53:33 +00:00
|
|
|
dataDir: dataDir,
|
|
|
|
sources: make(map[string]ytdlpSource, 0),
|
|
|
|
}
|
2024-06-02 21:20:43 +00:00
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
ctx := context.Background()
|
|
|
|
ctx = ctxprogress.New(ctx)
|
|
|
|
ctxprogress.AddCallback(ctx, func(p ctxprogress.Progress) {
|
|
|
|
cur, total := p.Progress()
|
|
|
|
fmt.Printf("updating sources: %d/%d\n", cur, total)
|
|
|
|
})
|
|
|
|
|
|
|
|
err := s.Update(ctx)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to update sources:", err)
|
|
|
|
}
|
|
|
|
time.Sleep(time.Minute)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return s
|
2024-06-02 19:53:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Service struct {
|
|
|
|
mu sync.Mutex
|
|
|
|
|
|
|
|
dataDir string
|
|
|
|
sources map[string]ytdlpSource
|
|
|
|
}
|
|
|
|
|
2024-06-02 21:20:43 +00:00
|
|
|
func (c *Service) addSource(s ytdlpSource) {
|
2024-06-02 19:53:33 +00:00
|
|
|
c.mu.Lock()
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
|
|
|
c.sources[s.Name()] = s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Service) sourceDir(s ytdlpSource) string {
|
|
|
|
return path.Join(c.dataDir, s.Name())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Service) Update(ctx context.Context) error {
|
|
|
|
for name, s := range c.sources {
|
|
|
|
if ctx.Err() != nil {
|
|
|
|
return ctx.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
dir := c.sourceDir(s)
|
|
|
|
err := s.Download(ctx, nil, dir)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to fetch source %s: %w", name, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Service) BuildFS(ctx context.Context, f vfs.File) (vfs.Filesystem, error) {
|
|
|
|
data, err := ctxio.ReadAll(ctx, f)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to read source file: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var s ytdlpSource
|
|
|
|
err = json.Unmarshal(data, &s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-06-02 21:20:43 +00:00
|
|
|
c.addSource(s)
|
2024-06-02 19:53:33 +00:00
|
|
|
|
|
|
|
downloadFS := ctxbilly.WrapFileSystem(osfs.New(c.sourceDir(s)))
|
|
|
|
|
2024-06-02 21:20:43 +00:00
|
|
|
return newSourceFS(path.Base(f.Name()), downloadFS, c, s), nil
|
2024-06-02 19:53:33 +00:00
|
|
|
}
|