From 1b072f42d358ddab93e8e5cc95bb4ecbda37c116 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Sat, 16 Nov 2024 23:38:44 -0600 Subject: [PATCH 1/5] =?UTF-8?q?=E2=9C=A8=20Support=20alternate=20source=20?= =?UTF-8?q?per=20show?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- convids/logic.go | 89 +++++++++++++++++++++++++++++++++-------------- convids/models.go | 1 + 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/convids/logic.go b/convids/logic.go index 80ef641..63fe2bc 100644 --- a/convids/logic.go +++ b/convids/logic.go @@ -39,21 +39,32 @@ type GroupPrinter func(name string, group Shows) var ErrNoFiles = errors.New("no files processed") var ErrSkipped = errors.New("skipped") -func processFile(conf *Config, walk ShowWalker, show *Show, file os.DirEntry) (processed bool, processError, cbError error) { +type processInput struct { + file os.DirEntry + source string + show *Show + extRe *regexp.Regexp + skips []string + walk ShowWalker +} + +func processFile(input processInput) (processed bool, processError, cbError error) { + file := input.file if file.IsDir() { return } - if !conf.extRe.MatchString(file.Name()) { + if !input.extRe.MatchString(file.Name()) { return } + show := input.show var found bool found, processError = show.Match(file.Name()) if processError != nil || !found { return } - path := fp.Join(conf.Source, file.Name()) - for _, ext := range conf.Skip { + path := fp.Join(input.source, file.Name()) + for _, ext := range input.skips { if !strings.HasPrefix(ext, ".") { ext = "." + ext } @@ -64,13 +75,31 @@ func processFile(conf *Config, walk ShowWalker, show *Show, file os.DirEntry) (p } } - cbError = walk(show, path) + cbError = input.walk(show, path) if cbError == nil { processed = true } return } +type fileMap map[string][]os.DirEntry + +func (fm fileMap) GetFiles(path string) []os.DirEntry { + files, ok := fm[path] + if ok { + return files + } + fm.ReadPath(path) + return fm[path] +} + +func (fm fileMap) ReadPath(path string) { + if _, ok := fm[path]; ok { + return + } + fm[path], _ = os.ReadDir(path) +} + func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err error) { err = ensureExtRe(d.Config) if err != nil { @@ -80,33 +109,41 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e cb = DryRun(os.Stdout) } count := 0 + allFiles := fileMap{} var files []os.DirEntry - files, err = os.ReadDir(d.Config.Source) + if err != nil { return } for s := range d.AllShows(gp) { - for _, file := range files { - processed, processErr, cbErr := processFile(d.Config, cb, s, file) - if !processed && processErr == nil && cbErr == nil { - continue + if len(s.Sources) == 0 { + s.Sources = []string{d.Config.Source} + } + for _, source := range s.Sources { + files = allFiles.GetFiles(source) + for _, file := range files { + pIn := processInput{file, source, s, d.Config.extRe, d.Config.Skip, cb} + processed, processErr, cbErr := processFile(pIn) + if !processed && processErr == nil && cbErr == nil { + continue + } + if errors.Is(processErr, ErrSkipped) { + continue + } + if processErr != nil { + return processErr + } + if cbErr != nil && stopOnError { + return cbErr + } + if cbErr == nil && processed { + count++ + } + if cbErr != nil { + err = cbErr + } + break } - if errors.Is(processErr, ErrSkipped) { - continue - } - if processErr != nil { - return processErr - } - if cbErr != nil && stopOnError { - return cbErr - } - if cbErr == nil && processed { - count++ - } - if cbErr != nil { - err = cbErr - } - break } } if err == nil && count < 1 { diff --git a/convids/models.go b/convids/models.go index b7ad695..58b8992 100644 --- a/convids/models.go +++ b/convids/models.go @@ -25,6 +25,7 @@ type Show struct { Pattern string Name string Anime bool + Sources []string re *regexp.Regexp } From 56fd7bf0b492ab6627c0938d8ef51ada89aa7a95 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Mon, 18 Nov 2024 13:26:05 -0600 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=90=9B=20Don't=20process=20multiple?= =?UTF-8?q?=20files=20per=20show=20if=20multiple=20source=20directories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- convids/logic.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/convids/logic.go b/convids/logic.go index 63fe2bc..bcd41b8 100644 --- a/convids/logic.go +++ b/convids/logic.go @@ -119,6 +119,7 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e if len(s.Sources) == 0 { s.Sources = []string{d.Config.Source} } + showstart: for _, source := range s.Sources { files = allFiles.GetFiles(source) for _, file := range files { @@ -142,7 +143,7 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e if cbErr != nil { err = cbErr } - break + break showstart } } } From 1abe398c7aa1297d1a6aac982187399b2a40e549 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Tue, 3 Dec 2024 15:20:06 -0600 Subject: [PATCH 3/5] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Context=20not=20Cotext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cli/context/signal.go | 6 +++++- cmd/convids/main.go | 3 +-- cmd/cool-down/main.go | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cli/context/signal.go b/cli/context/signal.go index cf8f620..0edd75b 100644 --- a/cli/context/signal.go +++ b/cli/context/signal.go @@ -7,7 +7,11 @@ import ( "syscall" ) -func SelfCancelingCotext(ctx context.Context) (context.Context, context.CancelFunc) { +func SelfCancelingContextFromBackground() (context.Context, context.CancelFunc) { + return SelfCancelingContext(context.Background()) +} + +func SelfCancelingContext(ctx context.Context) (context.Context, context.CancelFunc) { c, done := context.WithCancel(ctx) ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) diff --git a/cmd/convids/main.go b/cmd/convids/main.go index d938934..b8b82ac 100644 --- a/cmd/convids/main.go +++ b/cmd/convids/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "os" @@ -26,7 +25,7 @@ func main() { os.Exit(2) } - ctx, done := c.SelfCancelingCotext(context.Background()) + ctx, done := c.SelfCancelingContextFromBackground() defer done() var walker convids.ShowWalker diff --git a/cmd/cool-down/main.go b/cmd/cool-down/main.go index 234a06a..29efed5 100644 --- a/cmd/cool-down/main.go +++ b/cmd/cool-down/main.go @@ -10,7 +10,7 @@ import ( ) func main() { - ctx, done := c.SelfCancelingCotext(context.Background()) + ctx, done := c.SelfCancelingContext(context.Background()) defer done() ctx = chill.Chill(ctx) s := spin.Spin(ctx, "Waiting for CPU to cool...") From 64b22425678c4ed35cd6dbd5e5fd354ae8532ed8 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Tue, 3 Dec 2024 15:22:35 -0600 Subject: [PATCH 4/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Move=20cli=20code=20to?= =?UTF-8?q?=20internal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/convids/main.go | 19 +++++++---------- internal/cli/convids/flags.go | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 internal/cli/convids/flags.go diff --git a/cmd/convids/main.go b/cmd/convids/main.go index b8b82ac..caaf276 100644 --- a/cmd/convids/main.go +++ b/cmd/convids/main.go @@ -9,28 +9,23 @@ import ( e "codeberg.org/danjones000/utils/cli/err" "codeberg.org/danjones000/utils/cli/spin" "codeberg.org/danjones000/utils/convids" - "github.com/spf13/pflag" + ccli "codeberg.org/danjones000/utils/internal/cli/convids" ) const dataPath = "shows.yml" func main() { - loop := pflag.BoolP("loop", "l", false, "Loop") - help := pflag.BoolP("help", "h", false, "Get Help") - dryRun := pflag.BoolP("dry-run", "d", false, "Do a dry run") - pflag.Parse() - - if *help { - pflag.Usage() - os.Exit(2) + flags, err := ccli.ParseFlags(os.Args[0], os.Args[1:]) + e.HandleErr(err) + if *ccli.Help { + flags.Usage() } ctx, done := c.SelfCancelingContextFromBackground() defer done() var walker convids.ShowWalker - if *dryRun { - *loop = false + if *ccli.DryRun { walker = convids.DryRun(os.Stdout) } else { gs := convids.GetShow(ctx) @@ -52,7 +47,7 @@ func main() { groupPrinter := convids.PrintGroupName(os.Stdout) - if *loop { + if *ccli.Loop { fmt.Println("looping") for err == nil { err = convids.WalkFiles(data, false, groupPrinter, walker) diff --git a/internal/cli/convids/flags.go b/internal/cli/convids/flags.go new file mode 100644 index 0000000..af2b2af --- /dev/null +++ b/internal/cli/convids/flags.go @@ -0,0 +1,39 @@ +package convids + +import ( + "fmt" + + "github.com/spf13/pflag" +) + +var Help *bool +var Loop *bool +var DryRun *bool + +func GetFlags(name string) *pflag.FlagSet { + flags := pflag.NewFlagSet(name, pflag.ExitOnError) + + Help = flags.BoolP("help", "h", false, "Get Help") + Loop = flags.BoolP("loop", "l", false, "Loop") + DryRun = flags.BoolP("dry-run", "d", false, "Do a dry run (won't loop)") + + flags.Usage = func() { + fmt.Printf("Usage of %s:\n", name) + flags.PrintDefaults() + } + return flags +} + +func ParseFlags(name string, args []string) (*pflag.FlagSet, error) { + flags := GetFlags(name) + err := flags.Parse(args) + if err != nil { + return nil, err + } + + if *DryRun { + flags.Set("loop", "false") + } + + return flags, nil +} From ac0baba3a8bfce29c33fc508da42ec758762e1a6 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Wed, 4 Dec 2024 11:48:05 -0600 Subject: [PATCH 5/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Move=20convids=20cmd?= =?UTF-8?q?=20code=20to=20internal=20App?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/convids/main.go | 41 ++--------------------- convids/logic.go | 11 +++++-- internal/cli/convids/app.go | 60 ++++++++++++++++++++++++++++++++++ internal/cli/convids/walker.go | 29 ++++++++++++++++ 4 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 internal/cli/convids/app.go create mode 100644 internal/cli/convids/walker.go diff --git a/cmd/convids/main.go b/cmd/convids/main.go index caaf276..802bd0a 100644 --- a/cmd/convids/main.go +++ b/cmd/convids/main.go @@ -4,58 +4,21 @@ import ( "fmt" "os" - "codeberg.org/danjones000/utils/chill" c "codeberg.org/danjones000/utils/cli/context" e "codeberg.org/danjones000/utils/cli/err" - "codeberg.org/danjones000/utils/cli/spin" - "codeberg.org/danjones000/utils/convids" ccli "codeberg.org/danjones000/utils/internal/cli/convids" ) const dataPath = "shows.yml" func main() { - flags, err := ccli.ParseFlags(os.Args[0], os.Args[1:]) - e.HandleErr(err) - if *ccli.Help { - flags.Usage() - } - ctx, done := c.SelfCancelingContextFromBackground() defer done() - var walker convids.ShowWalker - if *ccli.DryRun { - walker = convids.DryRun(os.Stdout) - } else { - gs := convids.GetShow(ctx) - - walker = func(s *convids.Show, path string) error { - ct := chill.Chill(ctx) - msg := fmt.Sprintf("Waiting for CPU to cool, for %s", path) - sp := spin.Spin(ct, msg) - err := sp.Wait() - if err != nil { - return err - } - return gs(s, path) - } - } - - data, err := convids.NewData(dataPath) + app, err := ccli.NewApp(ctx, os.Args[0], os.Args[1:], dataPath, os.Stdout, os.Stdin, os.Stderr) e.HandleErr(err) - groupPrinter := convids.PrintGroupName(os.Stdout) - - if *ccli.Loop { - fmt.Println("looping") - for err == nil { - err = convids.WalkFiles(data, false, groupPrinter, walker) - fmt.Println(err) - } - } else { - err = convids.WalkFiles(data, false, groupPrinter, walker) - } + err = app.Run(ctx) e.HandleErr(err) fmt.Println("Done!") diff --git a/convids/logic.go b/convids/logic.go index bcd41b8..6d90c2b 100644 --- a/convids/logic.go +++ b/convids/logic.go @@ -162,13 +162,18 @@ func DryRun(out io.Writer) ShowWalker { } func GetShow(ctx context.Context) ShowWalker { + return GetShowWithIO(ctx, os.Stdin, os.Stdout, os.Stderr) +} + +func GetShowWithIO(ctx context.Context, stdin io.Reader, stdout io.Writer, stderr io.Writer) ShowWalker { return func(s *Show, path string) error { cmd := exec.CommandContext(ctx, "get-shows", s.Folder, path) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdin = stdin + cmd.Stdout = stdout + cmd.Stderr = stderr return cmd.Run() } + } func PrintGroupName(out io.Writer) GroupPrinter { diff --git a/internal/cli/convids/app.go b/internal/cli/convids/app.go new file mode 100644 index 0000000..6bd349b --- /dev/null +++ b/internal/cli/convids/app.go @@ -0,0 +1,60 @@ +package convids + +import ( + "context" + "fmt" + "io" + + conutils "codeberg.org/danjones000/utils/convids" + "github.com/spf13/pflag" +) + +type App struct { + Name string + Data *conutils.Data + flags *pflag.FlagSet + stdout io.Writer + stderr io.Writer + stdin io.Reader + walker conutils.ShowWalker + groupPrinter conutils.GroupPrinter +} + +func NewApp(ctx context.Context, name string, args []string, dataPath string, stdout io.Writer, stdin io.Reader, stderr io.Writer) (*App, error) { + a := App{Name: name, stdout: stdout, stdin: stdin, stderr: stderr} + var err error + a.flags, err = ParseFlags(name, args) + if err != nil { + return nil, err + } + + a.walker = GetWalker(ctx, *DryRun, stdin, stdout, stderr) + a.Data, err = conutils.NewData(dataPath) + if err != nil { + return nil, err + } + a.groupPrinter = conutils.PrintGroupName(stdout) + + return &a, nil +} + +func (a *App) Run(ctx context.Context) error { + if *Loop { + return a.runInLoop(ctx) + } + return a.run(ctx) +} + +func (a *App) run(ctx context.Context) error { + return conutils.WalkFiles(a.Data, false, a.groupPrinter, a.walker) +} + +func (a *App) runInLoop(ctx context.Context) error { + fmt.Fprintln(a.stdout, "Looping") + var err error + for err == nil { + err = a.run(ctx) + fmt.Fprintln(a.stdout, err) + } + return err +} diff --git a/internal/cli/convids/walker.go b/internal/cli/convids/walker.go new file mode 100644 index 0000000..a7dc85c --- /dev/null +++ b/internal/cli/convids/walker.go @@ -0,0 +1,29 @@ +package convids + +import ( + "context" + "fmt" + "io" + + "codeberg.org/danjones000/utils/chill" + "codeberg.org/danjones000/utils/cli/spin" + conutils "codeberg.org/danjones000/utils/convids" +) + +func GetWalker(ctx context.Context, dryRun bool, in io.Reader, out, errOut io.Writer) conutils.ShowWalker { + if dryRun { + return conutils.DryRun(out) + } + + gs := conutils.GetShowWithIO(ctx, in, out, errOut) + return func(s *conutils.Show, path string) error { + ct := chill.Chill(ctx) + msg := fmt.Sprintf("Waiting for CPU to cool, for %s", path) + sp := spin.Spin(ct, msg) + err := sp.Wait() + if err != nil { + return err + } + return gs(s, path) + } +}