Remove the usage of custom types where it isn't required

This commit is contained in:
ChaoticByte 2025-03-14 19:47:23 +01:00
parent 38ec0729ba
commit 424e912f6c
No known key found for this signature in database
3 changed files with 77 additions and 86 deletions

View file

@ -38,7 +38,7 @@ func XtermSetTitle(title string) {
// Commandline // Commandline
type Arguments struct { var Arguments struct {
Url string `json:"url"` Url string `json:"url"`
FormatName string `json:"format_name"` FormatName string `json:"format_name"`
OutputFile string `json:"output_file"` OutputFile string `json:"output_file"`
@ -84,96 +84,92 @@ lurch-dl --url string The url to the video
Version: ` + core.Version) Version: ` + core.Version)
} }
func CliParseArguments() (Arguments, error) { func CliParseArguments() error {
var err error var err error
var ratelimitMbs float64 var ratelimitMbs float64
a := Arguments{} flag.BoolVar(&Arguments.Help, "h", false, "")
flag.BoolVar(&a.Help, "h", false, "") flag.BoolVar(&Arguments.Help, "help", false, "")
flag.BoolVar(&a.Help, "help", false, "") flag.BoolVar(&Arguments.VideoInfo, "info", false, "")
flag.BoolVar(&a.VideoInfo, "info", false, "") flag.StringVar(&Arguments.Url, "url", "", "")
flag.StringVar(&a.Url, "url", "", "") flag.IntVar(&Arguments.UnparsedChapterNum, "chapter", 0, "") // 0 -> chapter idx -1 -> complete stream
flag.IntVar(&a.UnparsedChapterNum, "chapter", 0, "") // 0 -> chapter idx -1 -> complete stream flag.StringVar(&Arguments.FormatName, "format", "auto", "")
flag.StringVar(&a.FormatName, "format", "auto", "") flag.StringVar(&Arguments.OutputFile, "output", "", "")
flag.StringVar(&a.OutputFile, "output", "", "") flag.StringVar(&Arguments.TimestampStart, "start", "", "")
flag.StringVar(&a.TimestampStart, "start", "", "") flag.StringVar(&Arguments.TimestampStop, "stop", "", "")
flag.StringVar(&a.TimestampStop, "stop", "", "") flag.BoolVar(&Arguments.Overwrite, "overwrite", false, "")
flag.BoolVar(&a.Overwrite, "overwrite", false, "") flag.BoolVar(&Arguments.ContinueDl, "continue", false, "")
flag.BoolVar(&a.ContinueDl, "continue", false, "")
flag.Float64Var(&ratelimitMbs, "max-rate", 10.0, "") flag.Float64Var(&ratelimitMbs, "max-rate", 10.0, "")
flag.Parse() flag.Parse()
a.Video, err = core.ParseGtvVideoUrl(a.Url) Arguments.Video, err = core.ParseGtvVideoUrl(Arguments.Url)
if err != nil { if err != nil {
return a, err return err
} }
if a.Video.Category != "streams" { if Arguments.Video.Category != "streams" {
return a, errors.New("video category '" + a.Video.Category + "' not supported") return errors.New("video category '" + Arguments.Video.Category + "' not supported")
} }
if a.TimestampStart == "" { if Arguments.TimestampStart == "" {
a.StartDuration = -1 Arguments.StartDuration = -1
} else { } else {
a.StartDuration, err = time.ParseDuration(a.TimestampStart) Arguments.StartDuration, err = time.ParseDuration(Arguments.TimestampStart)
if err != nil { if err != nil {
return a, err return err
} }
} }
if a.TimestampStop == "" { if Arguments.TimestampStop == "" {
a.StopDuration = -1 Arguments.StopDuration = -1
} else { } else {
a.StopDuration, err = time.ParseDuration(a.TimestampStop) Arguments.StopDuration, err = time.ParseDuration(Arguments.TimestampStop)
if err != nil { if err != nil {
return a, err return err
} }
} }
a.ChapterIdx = a.UnparsedChapterNum - 1 Arguments.ChapterIdx = Arguments.UnparsedChapterNum - 1
a.Ratelimit = ratelimitMbs * 1_000_000.0 // MB/s -> B/s Arguments.Ratelimit = ratelimitMbs * 1_000_000.0 // MB/s -> B/s
if a.Ratelimit <= 0 { if Arguments.Ratelimit <= 0 {
return a, errors.New("the value of --max-rate must be greater than 0") return errors.New("the value of --max-rate must be greater than 0")
} }
return a, err return err
} }
// Main // Main
func CliRun() int { func CliRun() int {
cli := Cli{}
defer fmt.Print("\n") defer fmt.Print("\n")
// cli arguments & help text // cli arguments & help text
flag.Usage = CliShowHelp flag.Usage = CliShowHelp
args, err := CliParseArguments() err := CliParseArguments()
if args.Help { if Arguments.Help {
CliShowHelp() CliShowHelp()
return 0 return 0
} else if args.Url == "" || err != nil { } else if Arguments.Url == "" || err != nil {
CliShowHelp() CliShowHelp()
if err != nil { if err != nil {
cli.ErrorMessage(err) CliErrorMessage(err)
} }
return 1 return 1
} }
// detect terminal features // detect terminal features
XtermDetectFeatures() XtermDetectFeatures()
//
api := core.GtvApi{};
// Get video metadata // Get video metadata
if CliXtermTitle { if CliXtermTitle {
XtermSetTitle("lurch-dl - Fetching video metadata ...") XtermSetTitle("lurch-dl - Fetching video metadata ...")
} }
streamEp, err := api.GetStreamEpisode(args.Video.Id) streamEp, err := core.GetStreamEpisode(Arguments.Video.Id)
if err != nil { if err != nil {
cli.ErrorMessage(err) CliErrorMessage(err)
return 1 return 1
} }
fmt.Print("\n") fmt.Print("\n")
fmt.Printf("Title: %s\n", streamEp.Title) fmt.Printf("Title: %s\n", streamEp.Title)
// Check and list chapters/formats and exit // Check and list chapters/formats and exit
if args.ChapterIdx >= 0 { if Arguments.ChapterIdx >= 0 {
if args.ChapterIdx >= len(streamEp.Chapters) { if Arguments.ChapterIdx >= len(streamEp.Chapters) {
cli.ErrorMessage(&core.ChapterNotFoundError{ChapterNum: args.UnparsedChapterNum}) CliErrorMessage(&core.ChapterNotFoundError{ChapterNum: Arguments.UnparsedChapterNum})
CliAvailableChapters(streamEp.Chapters) CliAvailableChapters(streamEp.Chapters)
return 1 return 1
} }
} }
if args.VideoInfo { if Arguments.VideoInfo {
fmt.Printf("Episode: %s\n", streamEp.Episode) fmt.Printf("Episode: %s\n", streamEp.Episode)
fmt.Printf("Length: %s\n", streamEp.Length) fmt.Printf("Length: %s\n", streamEp.Length)
fmt.Printf("Views: %d\n", streamEp.Views) fmt.Printf("Views: %d\n", streamEp.Views)
@ -195,42 +191,42 @@ func CliRun() int {
CliAvailableChapters(streamEp.Chapters) CliAvailableChapters(streamEp.Chapters)
return 0 return 0
} }
format, err := streamEp.GetFormatByName(args.FormatName) format, err := streamEp.GetFormatByName(Arguments.FormatName)
if err != nil { if err != nil {
cli.ErrorMessage(err) CliErrorMessage(err)
CliAvailableFormats(streamEp.Formats) CliAvailableFormats(streamEp.Formats)
return 1 return 1
} }
fmt.Printf("Format: %v\n", format.Name) fmt.Printf("Format: %v\n", format.Name)
// chapter // chapter
targetChapter := core.Chapter{Index: -1} // set Index to -1 for noop targetChapter := core.Chapter{Index: -1} // set Index to -1 for noop
if len(streamEp.Chapters) > 0 && args.ChapterIdx >= 0 { if len(streamEp.Chapters) > 0 && Arguments.ChapterIdx >= 0 {
targetChapter = streamEp.Chapters[args.ChapterIdx] targetChapter = streamEp.Chapters[Arguments.ChapterIdx]
fmt.Printf("Chapter: %v. %v\n", args.UnparsedChapterNum, targetChapter.Title) fmt.Printf("Chapter: %v. %v\n", Arguments.UnparsedChapterNum, targetChapter.Title)
} }
// We already set the output file correctly so we can output it // We already set the output file correctly so we can output it
if args.OutputFile == "" { if Arguments.OutputFile == "" {
args.OutputFile = streamEp.GetProposedFilename(args.ChapterIdx) Arguments.OutputFile = streamEp.GetProposedFilename(Arguments.ChapterIdx)
} }
// Start Download // Start Download
fmt.Printf("Output: %v\n", args.OutputFile) fmt.Printf("Output: %v\n", Arguments.OutputFile)
fmt.Print("\n") fmt.Print("\n")
successful := false successful := false
aborted := false aborted := false
for p := range api.DownloadEpisode( for p := range core.DownloadEpisode(
streamEp, streamEp,
targetChapter, targetChapter,
args.FormatName, Arguments.FormatName,
args.OutputFile, Arguments.OutputFile,
args.Overwrite, Arguments.Overwrite,
args.ContinueDl, Arguments.ContinueDl,
args.StartDuration, Arguments.StartDuration,
args.StopDuration, Arguments.StopDuration,
args.Ratelimit, Arguments.Ratelimit,
make(chan os.Signal, 1), make(chan os.Signal, 1),
) { // Iterate over download progress ) { // Iterate over download progress
if p.Error != nil { if p.Error != nil {
cli.ErrorMessage(p.Error) CliErrorMessage(p.Error)
return 1 return 1
} }
if p.Success { if p.Success {
@ -238,7 +234,7 @@ func CliRun() int {
} else if p.Aborted { } else if p.Aborted {
aborted = true aborted = true
} else { } else {
cli.DownloadProgress(p.Progress, p.Rate, p.Delaying, p.Waiting, p.Retries, p.Title) CliDownloadProgress(p.Progress, p.Rate, p.Delaying, p.Waiting, p.Retries, p.Title)
} }
} }
fmt.Print("\n") fmt.Print("\n")
@ -246,7 +242,7 @@ func CliRun() int {
fmt.Print("\nAborted. ") fmt.Print("\nAborted. ")
return 130 return 130
} else if !successful { } else if !successful {
cli.ErrorMessage(errors.New("download failed")) CliErrorMessage(errors.New("download failed"))
return 1 return 1
} else { return 0 } } else { return 0 }
} }
@ -270,9 +266,7 @@ func CliAvailableFormats(formats []core.VideoFormat) {
fmt.Print("\n") fmt.Print("\n")
} }
type Cli struct{} func CliDownloadProgress(progress float32, rate float64, delaying bool, waiting bool, retries int, title string) {
func (cli *Cli) DownloadProgress(progress float32, rate float64, delaying bool, waiting bool, retries int, title string) {
if retries > 0 { if retries > 0 {
if retries == 1 { if retries == 1 {
fmt.Print("\n") fmt.Print("\n")
@ -291,7 +285,7 @@ func (cli *Cli) DownloadProgress(progress float32, rate float64, delaying bool,
} }
} }
func (cli *Cli) ErrorMessage(err error) { func CliErrorMessage(err error) {
fmt.Print("\n") fmt.Print("\n")
fmt.Println("An error occured:", err) fmt.Println("An error occured:", err)
} }

View file

@ -25,6 +25,18 @@ const RatelimitDelayAfter = 5.0 // in Seconds; Delay the next chunk download aft
const ApiBaseurlStreamEpisodeInfo = "https://api.gronkh.tv/v1/video/info?episode=%s" const ApiBaseurlStreamEpisodeInfo = "https://api.gronkh.tv/v1/video/info?episode=%s"
const ApiBaseurlStreamEpisodePlInfo = "https://api.gronkh.tv/v1/video/playlist?episode=%s" const ApiBaseurlStreamEpisodePlInfo = "https://api.gronkh.tv/v1/video/playlist?episode=%s"
type DownloadProgress struct {
Aborted bool
Error error
Success bool
Delaying bool
Progress float32
Rate float64
Retries int
Title string
Waiting bool
}
var ApiHeadersBase = http.Header{ var ApiHeadersBase = http.Header{
"User-Agent": {"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"}, "User-Agent": {"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"},
"Accept-Language": {"de,en-US;q=0.7,en;q=0.3"}, "Accept-Language": {"de,en-US;q=0.7,en;q=0.3"},
@ -48,9 +60,7 @@ var ApiHeadersVideoAdditional = http.Header{
"Accept": {"*/*"}, "Accept": {"*/*"},
} }
type GtvApi struct{} func GetStreamEpisode(episode string) (StreamEpisode, error) {
func (api *GtvApi) GetStreamEpisode(episode string) (StreamEpisode, error) {
ep := StreamEpisode{} ep := StreamEpisode{}
ep.Episode = episode ep.Episode = episode
info_data, err := httpGet( info_data, err := httpGet(
@ -93,7 +103,7 @@ func (api *GtvApi) GetStreamEpisode(episode string) (StreamEpisode, error) {
return ep, err return ep, err
} }
func (api *GtvApi) GetStreamChunkList(video VideoFormat) (ChunkList, error) { func GetStreamChunkList(video VideoFormat) (ChunkList, error) {
baseUrl := video.Url[:strings.LastIndex(video.Url, "/")] baseUrl := video.Url[:strings.LastIndex(video.Url, "/")]
data, err := httpGet(video.Url, []http.Header{ApiHeadersBase, ApiHeadersMetaAdditional}, time.Second*10) data, err := httpGet(video.Url, []http.Header{ApiHeadersBase, ApiHeadersMetaAdditional}, time.Second*10)
if err != nil { if err != nil {
@ -103,7 +113,7 @@ func (api *GtvApi) GetStreamChunkList(video VideoFormat) (ChunkList, error) {
return chunklist, err return chunklist, err
} }
func (api *GtvApi) DownloadEpisode( func DownloadEpisode(
ep StreamEpisode, ep StreamEpisode,
chapter Chapter, chapter Chapter,
formatName string, formatName string,
@ -181,7 +191,7 @@ func (api *GtvApi) DownloadEpisode(
} }
// download // download
format, _ := ep.GetFormatByName(formatName) // we don't have to check the error, as it was already checked by CliRun() format, _ := ep.GetFormatByName(formatName) // we don't have to check the error, as it was already checked by CliRun()
chunklist, err := api.GetStreamChunkList(format) chunklist, err := GetStreamChunkList(format)
chunklist = chunklist.Cut(startDuration, stopDuration) chunklist = chunklist.Cut(startDuration, stopDuration)
if err != nil { if err != nil {
yield(DownloadProgress{Error: err}) yield(DownloadProgress{Error: err})

View file

@ -1,13 +0,0 @@
package core
type DownloadProgress struct {
Aborted bool
Error error
Success bool
Delaying bool
Progress float32
Rate float64
Retries int
Title string
Waiting bool
}