Refactoring, added remaining custom errors
This commit is contained in:
parent
424e912f6c
commit
ee3518ab5c
5 changed files with 77 additions and 36 deletions
39
cli/cli.go
39
cli/cli.go
|
@ -3,7 +3,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -50,12 +49,11 @@ var Arguments struct {
|
|||
Help bool `json:"-"`
|
||||
VideoInfo bool `json:"-"`
|
||||
ListFormats bool `json:"-"`
|
||||
UnparsedChapterNum int `json:"chapter_num"`
|
||||
ChapterNum int `json:"chapter_num"`
|
||||
// Parsed
|
||||
Video core.GtvVideo `json:"-"`
|
||||
StartDuration time.Duration `json:"-"`
|
||||
StopDuration time.Duration `json:"-"`
|
||||
ChapterIdx int `json:"-"`
|
||||
Ratelimit float64 `json:"-"`
|
||||
}
|
||||
|
||||
|
@ -91,7 +89,7 @@ func CliParseArguments() error {
|
|||
flag.BoolVar(&Arguments.Help, "help", false, "")
|
||||
flag.BoolVar(&Arguments.VideoInfo, "info", false, "")
|
||||
flag.StringVar(&Arguments.Url, "url", "", "")
|
||||
flag.IntVar(&Arguments.UnparsedChapterNum, "chapter", 0, "") // 0 -> chapter idx -1 -> complete stream
|
||||
flag.IntVar(&Arguments.ChapterNum, "chapter", 0, "") // 0 -> chapter idx -1 -> complete stream
|
||||
flag.StringVar(&Arguments.FormatName, "format", "auto", "")
|
||||
flag.StringVar(&Arguments.OutputFile, "output", "", "")
|
||||
flag.StringVar(&Arguments.TimestampStart, "start", "", "")
|
||||
|
@ -104,9 +102,6 @@ func CliParseArguments() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if Arguments.Video.Category != "streams" {
|
||||
return errors.New("video category '" + Arguments.Video.Category + "' not supported")
|
||||
}
|
||||
if Arguments.TimestampStart == "" {
|
||||
Arguments.StartDuration = -1
|
||||
} else {
|
||||
|
@ -123,10 +118,9 @@ func CliParseArguments() error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
Arguments.ChapterIdx = Arguments.UnparsedChapterNum - 1
|
||||
Arguments.Ratelimit = ratelimitMbs * 1_000_000.0 // MB/s -> B/s
|
||||
if Arguments.Ratelimit <= 0 {
|
||||
return errors.New("the value of --max-rate must be greater than 0")
|
||||
return &GenericCliAgumentError{Msg: "the value of --max-rate must be greater than 0"}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -162,13 +156,16 @@ func CliRun() int {
|
|||
fmt.Print("\n")
|
||||
fmt.Printf("Title: %s\n", streamEp.Title)
|
||||
// Check and list chapters/formats and exit
|
||||
if Arguments.ChapterIdx >= 0 {
|
||||
if Arguments.ChapterIdx >= len(streamEp.Chapters) {
|
||||
CliErrorMessage(&core.ChapterNotFoundError{ChapterNum: Arguments.UnparsedChapterNum})
|
||||
CliAvailableChapters(streamEp.Chapters)
|
||||
return 1
|
||||
}
|
||||
targetChapter, err := streamEp.GetChapterByNumber(Arguments.ChapterNum)
|
||||
if err != nil {
|
||||
CliErrorMessage(err)
|
||||
CliAvailableChapters(streamEp.Chapters)
|
||||
return 1
|
||||
}
|
||||
if Arguments.ChapterNum > 0 && len(streamEp.Chapters) > 0 {
|
||||
fmt.Printf("Chapter: %v. %v\n", Arguments.ChapterNum, targetChapter.Title)
|
||||
}
|
||||
// Video Info
|
||||
if Arguments.VideoInfo {
|
||||
fmt.Printf("Episode: %s\n", streamEp.Episode)
|
||||
fmt.Printf("Length: %s\n", streamEp.Length)
|
||||
|
@ -198,22 +195,16 @@ func CliRun() int {
|
|||
return 1
|
||||
}
|
||||
fmt.Printf("Format: %v\n", format.Name)
|
||||
// chapter
|
||||
targetChapter := core.Chapter{Index: -1} // set Index to -1 for noop
|
||||
if len(streamEp.Chapters) > 0 && Arguments.ChapterIdx >= 0 {
|
||||
targetChapter = streamEp.Chapters[Arguments.ChapterIdx]
|
||||
fmt.Printf("Chapter: %v. %v\n", Arguments.UnparsedChapterNum, targetChapter.Title)
|
||||
}
|
||||
// We already set the output file correctly so we can output it
|
||||
if Arguments.OutputFile == "" {
|
||||
Arguments.OutputFile = streamEp.GetProposedFilename(Arguments.ChapterIdx)
|
||||
Arguments.OutputFile = streamEp.GetProposedFilename(targetChapter)
|
||||
}
|
||||
// Start Download
|
||||
fmt.Printf("Output: %v\n", Arguments.OutputFile)
|
||||
fmt.Print("\n")
|
||||
successful := false
|
||||
aborted := false
|
||||
for p := range core.DownloadEpisode(
|
||||
for p := range core.DownloadStreamEpisode(
|
||||
streamEp,
|
||||
targetChapter,
|
||||
Arguments.FormatName,
|
||||
|
@ -242,7 +233,7 @@ func CliRun() int {
|
|||
fmt.Print("\nAborted. ")
|
||||
return 130
|
||||
} else if !successful {
|
||||
CliErrorMessage(errors.New("download failed"))
|
||||
CliErrorMessage(&GenericDownloadError{})
|
||||
return 1
|
||||
} else { return 0 }
|
||||
}
|
||||
|
|
15
cli/errors.go
Normal file
15
cli/errors.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
type GenericCliAgumentError struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (err *GenericCliAgumentError) Error() string {
|
||||
return err.Msg
|
||||
}
|
||||
|
||||
type GenericDownloadError struct {}
|
||||
|
||||
func (err *GenericDownloadError) Error() string {
|
||||
return "download failed"
|
||||
}
|
|
@ -35,7 +35,7 @@ type FileExistsError struct {
|
|||
}
|
||||
|
||||
func (err *FileExistsError) Error() string {
|
||||
return "File '" + err.Filename + "' already exists. See the available options on how to proceed."
|
||||
return "file '" + err.Filename + "' already exists - see the available options on how to proceed"
|
||||
}
|
||||
|
||||
type FormatNotFoundError struct {
|
||||
|
@ -43,7 +43,7 @@ type FormatNotFoundError struct {
|
|||
}
|
||||
|
||||
func (err *FormatNotFoundError) Error() string {
|
||||
return "Format " + err.FormatName + " is not available."
|
||||
return "format " + err.FormatName + " is not available"
|
||||
}
|
||||
|
||||
type ChapterNotFoundError struct {
|
||||
|
@ -51,5 +51,27 @@ type ChapterNotFoundError struct {
|
|||
}
|
||||
|
||||
func (err *ChapterNotFoundError) Error() string {
|
||||
return fmt.Sprintf("Chapter %v not found.", err.ChapterNum)
|
||||
return fmt.Sprintf("chapter %v not found", err.ChapterNum)
|
||||
}
|
||||
|
||||
type VideoCategoryUnsupportedError struct {
|
||||
Category string
|
||||
}
|
||||
|
||||
func (err *VideoCategoryUnsupportedError) Error() string {
|
||||
return fmt.Sprintf("video category '%v' not supported", err.Category)
|
||||
}
|
||||
|
||||
type GtvVideoUrlParseError struct {
|
||||
Url string
|
||||
}
|
||||
|
||||
func (err *GtvVideoUrlParseError) Error() string {
|
||||
return fmt.Sprintf("Could not parse URL %v", err.Url)
|
||||
}
|
||||
|
||||
type DownloadInfoFileReadError struct {}
|
||||
|
||||
func (err *DownloadInfoFileReadError) Error() string {
|
||||
return "could not read download info file, can't continue download"
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package core
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
|
@ -113,7 +112,7 @@ func GetStreamChunkList(video VideoFormat) (ChunkList, error) {
|
|||
return chunklist, err
|
||||
}
|
||||
|
||||
func DownloadEpisode(
|
||||
func DownloadStreamEpisode(
|
||||
ep StreamEpisode,
|
||||
chapter Chapter,
|
||||
formatName string,
|
||||
|
@ -128,7 +127,7 @@ func DownloadEpisode(
|
|||
return func (yield func(DownloadProgress) bool) {
|
||||
// Set automatic values
|
||||
if outputFile == "" {
|
||||
outputFile = ep.GetProposedFilename(chapter.Index)
|
||||
outputFile = ep.GetProposedFilename(chapter)
|
||||
}
|
||||
if chapter.Index >= 0 {
|
||||
if startDuration < 0 {
|
||||
|
@ -167,7 +166,7 @@ func DownloadEpisode(
|
|||
if continueDl {
|
||||
infoFileData, err := os.ReadFile(infoFilename)
|
||||
if err != nil {
|
||||
yield(DownloadProgress{Error: errors.New("could not access download info file, can't continue download")})
|
||||
yield(DownloadProgress{Error: &DownloadInfoFileReadError{}})
|
||||
return
|
||||
}
|
||||
i, err := strconv.ParseInt(string(infoFileData), 10, 32)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
|
@ -40,10 +39,13 @@ func ParseGtvVideoUrl(url string) (GtvVideo, error) {
|
|||
video := GtvVideo{}
|
||||
match := videoUrlRegex.FindStringSubmatch(url)
|
||||
if len(match) < 2 {
|
||||
return video, errors.New("Could not parse URL " + url)
|
||||
return video, &GtvVideoUrlParseError{Url: url}
|
||||
}
|
||||
video.Category = match[1]
|
||||
video.Id = match[2]
|
||||
if video.Category != "streams" {
|
||||
return video, &VideoCategoryUnsupportedError{Category: video.Category}
|
||||
}
|
||||
return video, nil
|
||||
}
|
||||
|
||||
|
@ -109,9 +111,21 @@ func (ep *StreamEpisode) GetFormatByName(formatName string) (VideoFormat, error)
|
|||
}
|
||||
}
|
||||
|
||||
func (ep *StreamEpisode) GetProposedFilename(chapterIdx int) string {
|
||||
if chapterIdx >= 0 && chapterIdx < len(ep.Chapters) {
|
||||
return fmt.Sprintf("GTV%04s - %v. %s.ts", ep.Episode, chapterIdx+1, sanitizeUnicodeFilename(ep.Chapters[chapterIdx].Title))
|
||||
func (ep *StreamEpisode) GetChapterByNumber(number int) (Chapter, error) {
|
||||
chapter := Chapter{Index: -1} // set Index to -1 for noop
|
||||
idx := number-1
|
||||
if idx >= 0 && idx >= len(ep.Chapters) {
|
||||
return chapter, &ChapterNotFoundError{ChapterNum: number}
|
||||
}
|
||||
if len(ep.Chapters) > 0 && idx >= 0 {
|
||||
chapter = ep.Chapters[idx]
|
||||
}
|
||||
return chapter, nil
|
||||
}
|
||||
|
||||
func (ep *StreamEpisode) GetProposedFilename(chapter Chapter) string {
|
||||
if chapter.Index >= 0 && chapter.Index < len(ep.Chapters) {
|
||||
return fmt.Sprintf("GTV%04s - %v. %s.ts", ep.Episode, chapter.Index, sanitizeUnicodeFilename(ep.Chapters[chapter.Index].Title))
|
||||
} else {
|
||||
return sanitizeUnicodeFilename(ep.Title) + ".ts"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue