Refactored downloader

This commit is contained in:
2021-12-22 01:22:33 +01:00
parent 4b9583b08f
commit 23ca1168df
21 changed files with 544 additions and 177 deletions

View File

@@ -0,0 +1,10 @@
package downloadhandler
type OnDownloadEventHandler interface {
OnTickEvent(downloadId string, progress string)
}
type DownloadHandler interface {
OnProgress(eventHandler OnDownloadEventHandler)
Download(link string, outputDir string, downloadId string) error
}

View File

@@ -0,0 +1,98 @@
package downloadhandler
import (
"fmt"
"github.com/ovh/configstore"
"go.uber.org/zap"
"log"
"os/exec"
"regexp"
"strings"
"time"
)
type YoutubeDlDownloader struct {
progressUpdate bool
checkFrequencyMs time.Duration
logger *zap.SugaredLogger
onDownloadEventHandler OnDownloadEventHandler
}
func NewYoutubeDlDownloader(logger *zap.SugaredLogger) DownloadHandler {
var checkFrequencyMs int64
var featureProgressUpdate bool
var err error
checkFrequencyMs, err = configstore.GetItemValueInt("download_frequency_update_ms")
featureProgressUpdate, err = configstore.GetItemValueBool("download_progress_update")
if err != nil {
panic(err)
}
_, err = exec.Command("youtube-dl", "--version").Output()
if err != nil {
log.Fatal("Youtube download (youtube-dl) isn't installed on the device")
}
return &YoutubeDlDownloader{
checkFrequencyMs: time.Duration(checkFrequencyMs),
progressUpdate: featureProgressUpdate,
logger: logger,
onDownloadEventHandler: nil,
}
}
func (y *YoutubeDlDownloader) OnProgress(eventHandler OnDownloadEventHandler) {
y.onDownloadEventHandler = eventHandler
}
func (y *YoutubeDlDownloader) Download(link string, outputDir string, downloadId string) error {
filePath := fmt.Sprintf("%s/%s", outputDir, "%(title)s-%(id)s.%(ext)s")
command := exec.Command("youtube-dl",
"-R 3",
"-o",
filePath,
link,
)
stdout, err := command.StdoutPipe()
if y.progressUpdate {
go func() {
for true {
bytes := make([]byte, 1024)
_, err = stdout.Read(bytes)
if err != nil {
return
}
output := string(bytes)
if err = y.getParameters(output, link, downloadId); err != nil {
return
}
time.Sleep(time.Millisecond * y.checkFrequencyMs)
}
}()
}
return command.Run()
}
func (y *YoutubeDlDownloader) getParameters(output string, link string, downloadId string) error {
compile := regexp.MustCompile(`[a-z\[\]\s]+([\d\.]+).[a-z\s]+([\d\.]+)([a-zA-Z]+)[a-z\s]+`)
res := compile.FindAllStringSubmatch(output, -1)
if len(res) != 0 && strings.Contains(res[0][0], "download") && len(res[0]) >= 2 {
progress := res[0][1]
y.logger.Debugw("progress",
"percentage", progress,
"link", link)
if y.onDownloadEventHandler != nil {
y.onDownloadEventHandler.OnTickEvent(downloadId, progress)
}
}
return nil
}

View File

@@ -0,0 +1,98 @@
package downloadhandler
import (
"fmt"
"github.com/ovh/configstore"
"go.uber.org/zap"
"log"
"os/exec"
"regexp"
"strings"
"time"
)
type YtDlpDownloader struct {
progressUpdate bool
checkFrequencyMs time.Duration
logger *zap.SugaredLogger
onDownloadEventHandler OnDownloadEventHandler
}
func NewYtDlpDownloader(logger *zap.SugaredLogger) DownloadHandler {
var checkFrequencyMs int64
var featureProgressUpdate bool
var err error
checkFrequencyMs, err = configstore.GetItemValueInt("download_frequency_update_ms")
featureProgressUpdate, err = configstore.GetItemValueBool("download_progress_update")
if err != nil {
panic(err)
}
_, err = exec.Command("yt-dlp", "--version").Output()
if err != nil {
log.Fatal("Youtube download (youtube-dl) isn't installed on the device")
}
return &YtDlpDownloader{
checkFrequencyMs: time.Duration(checkFrequencyMs),
progressUpdate: featureProgressUpdate,
logger: logger,
onDownloadEventHandler: nil,
}
}
func (y *YtDlpDownloader) OnProgress(eventHandler OnDownloadEventHandler) {
y.onDownloadEventHandler = eventHandler
}
func (y *YtDlpDownloader) Download(link string, outputDir string, downloadId string) error {
filePath := fmt.Sprintf("%s/%s", outputDir, "%(title)s-%(id)s.%(ext)s")
command := exec.Command("yt-dlp",
"-R 3",
"-o",
filePath,
link,
)
stdout, err := command.StdoutPipe()
if y.progressUpdate {
go func() {
for true {
bytes := make([]byte, 1024)
_, err = stdout.Read(bytes)
if err != nil {
return
}
output := string(bytes)
if err = y.getParameters(output, link, downloadId); err != nil {
return
}
time.Sleep(time.Millisecond * y.checkFrequencyMs)
}
}()
}
return command.Run()
}
func (y *YtDlpDownloader) getParameters(output string, link string, downloadId string) error {
compile := regexp.MustCompile(`[a-z\[\]\s]+([\d\.]+).[a-z\s\~]+([\d\.]+)([a-zA-Z]+)[a-z\s]+`)
res := compile.FindAllStringSubmatch(output, -1)
if len(res) != 0 && strings.Contains(res[0][0], "download") && len(res[0]) >= 2 {
progress := res[0][1]
y.logger.Debugw("progress",
"percentage", progress,
"link", link)
if y.onDownloadEventHandler != nil {
y.onDownloadEventHandler.OnTickEvent(downloadId, progress)
}
}
return nil
}