feat: watch command for optimize

This commit is contained in:
Antoine Aflalo
2024-08-27 14:58:21 -04:00
parent 7104121fcf
commit cd9bd387fa

134
cmd/watch_command.go Normal file
View File

@@ -0,0 +1,134 @@
package cmd
import (
"fmt"
"github.com/belphemur/CBZOptimizer/converter"
"github.com/belphemur/CBZOptimizer/converter/constant"
"github.com/belphemur/CBZOptimizer/utils"
"github.com/pablodz/inotifywaitgo/inotifywaitgo"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/thediveo/enumflag/v2"
"log"
"runtime"
"strings"
"sync"
)
func init() {
if runtime.GOOS != "linux" {
return
}
command := &cobra.Command{
Use: "watch [folder]",
Short: "Watch a folder for new CBZ files",
Long: "Watch a folder for new CBZ files.\nIt will watch a folder for new CBZ files and optimize them.",
RunE: WatchCommand,
Args: cobra.ExactArgs(1),
}
formatFlag := enumflag.New(&converterType, "format", constant.CommandValue, enumflag.EnumCaseInsensitive)
_ = formatFlag.RegisterCompletion(command, "format", constant.HelpText)
command.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
_ = viper.BindPFlag("quality", command.Flags().Lookup("quality"))
command.Flags().BoolP("override", "o", false, "Override the original CBZ files")
_ = viper.BindPFlag("override", command.Flags().Lookup("override"))
command.PersistentFlags().VarP(
formatFlag,
"format", "f",
fmt.Sprintf("Format to convert the images to: %s", constant.ListAll()))
command.PersistentFlags().Lookup("format").NoOptDefVal = constant.DefaultConversion.String()
_ = viper.BindPFlag("format", command.PersistentFlags().Lookup("format"))
AddCommand(command)
}
func WatchCommand(cmd *cobra.Command, args []string) error {
path := args[0]
if path == "" {
return fmt.Errorf("path is required")
}
if !utils.IsValidFolder(path) {
return fmt.Errorf("the path needs to be a folder")
}
quality, err := cmd.Flags().GetUint8("quality")
if err != nil {
return fmt.Errorf("invalid quality value")
}
override, err := cmd.Flags().GetBool("override")
if err != nil {
return fmt.Errorf("invalid quality value")
}
chapterConverter, err := converter.Get(converterType)
if err != nil {
return fmt.Errorf("failed to get chapterConverter: %v", err)
}
err = chapterConverter.PrepareConverter()
if err != nil {
return fmt.Errorf("failed to prepare converter: %v", err)
}
events := make(chan inotifywaitgo.FileEvent)
errors := make(chan error)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
inotifywaitgo.WatchPath(&inotifywaitgo.Settings{
Dir: path,
FileEvents: events,
ErrorChan: errors,
Options: &inotifywaitgo.Options{
Recursive: true,
Events: []inotifywaitgo.EVENT{
inotifywaitgo.MOVE,
inotifywaitgo.CLOSE_WRITE,
},
Monitor: true,
},
Verbose: true,
})
}()
wg.Add(1)
go func() {
defer wg.Done()
for event := range events {
log.Printf("[Event]%s, %v\n", event.Filename, event.Events)
if !strings.HasSuffix(strings.ToLower(event.Filename), ".cbz") {
continue
}
for _, e := range event.Events {
switch e {
case inotifywaitgo.CLOSE_WRITE, inotifywaitgo.MOVE:
err := utils.Optimize(chapterConverter, event.Filename, quality, override)
if err != nil {
errors <- fmt.Errorf("error processing file %s: %w", event.Filename, err)
}
default:
// ignored
}
}
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for err := range errors {
log.Printf("Error: %v\n", err)
}
}()
wg.Wait()
return nil
}