feat: add watch flag
This commit is contained in:
parent
a928611a8d
commit
dfbb807e41
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
|
@ -14,6 +15,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -52,6 +54,7 @@ func main() {
|
|||
&cli.BoolFlag{Name: "skip-noop", Aliases: []string{"n"}, Usage: "skip noop decoder", Required: false, Value: true},
|
||||
&cli.BoolFlag{Name: "update-metadata", Usage: "update metadata & album art from network", Required: false, Value: false},
|
||||
&cli.BoolFlag{Name: "overwrite", Usage: "overwrite output file without asking", Required: false, Value: false},
|
||||
&cli.BoolFlag{Name: "watch", Usage: "watch the input dir and process new files", Required: false, Value: false},
|
||||
|
||||
&cli.BoolFlag{Name: "supported-ext", Usage: "show supported file extensions and exit", Required: false, Value: false},
|
||||
},
|
||||
|
@ -66,6 +69,7 @@ func main() {
|
|||
logger.Fatal("run app failed", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func printSupportedExtensions() {
|
||||
var exts []string
|
||||
for ext := range common.DecoderRegistry {
|
||||
|
@ -76,6 +80,7 @@ func printSupportedExtensions() {
|
|||
fmt.Printf("%s: %d\n", ext, len(common.DecoderRegistry[ext]))
|
||||
}
|
||||
}
|
||||
|
||||
func appMain(c *cli.Context) (err error) {
|
||||
if c.Bool("supported-ext") {
|
||||
printSupportedExtensions()
|
||||
|
@ -134,7 +139,12 @@ func appMain(c *cli.Context) (err error) {
|
|||
}
|
||||
|
||||
if inputStat.IsDir() {
|
||||
wacthDir := c.Bool("watch")
|
||||
if !wacthDir {
|
||||
return proc.processDir(input)
|
||||
} else {
|
||||
return proc.watchDir(input)
|
||||
}
|
||||
} else {
|
||||
return proc.processFile(input)
|
||||
}
|
||||
|
@ -150,6 +160,60 @@ type processor struct {
|
|||
overwriteOutput bool
|
||||
}
|
||||
|
||||
func (p *processor) watchDir(inputDir string) error {
|
||||
if err := p.processDir(inputDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create watcher: %w", err)
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if event.Has(fsnotify.Create) || event.Has(fsnotify.Write) {
|
||||
// try open with exclusive mode, to avoid file is still writing
|
||||
f, err := os.OpenFile(event.Name, os.O_RDONLY, os.ModeExclusive)
|
||||
if err != nil {
|
||||
logger.Debug("failed to open file exclusively", zap.String("path", event.Name), zap.Error(err))
|
||||
time.Sleep(1 * time.Second) // wait for file writing complete
|
||||
continue
|
||||
}
|
||||
_ = f.Close()
|
||||
|
||||
if err := p.processFile(event.Name); err != nil {
|
||||
logger.Warn("failed to process file", zap.String("path", event.Name), zap.Error(err))
|
||||
}
|
||||
}
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
logger.Error("file watcher got error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = watcher.Add(inputDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to watch dir %s: %w", inputDir, err)
|
||||
}
|
||||
|
||||
signalCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||
defer stop()
|
||||
|
||||
<-signalCtx.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *processor) processDir(inputDir string) error {
|
||||
items, err := os.ReadDir(inputDir)
|
||||
if err != nil {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,6 +3,7 @@ module unlock-music.dev/cli
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/go-flac/flacpicture v0.2.0
|
||||
github.com/go-flac/flacvorbis v0.1.0
|
||||
github.com/go-flac/go-flac v0.3.1
|
||||
|
@ -22,5 +23,6 @@ require (
|
|||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
)
|
||||
|
|
5
go.sum
5
go.sum
|
@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/ddliu/go-httpclient v0.5.1 h1:ys4KozrhBaGdI1yuWIFwNNILqhnMU9ozTvRNfCTorvs=
|
||||
github.com/ddliu/go-httpclient v0.5.1/go.mod h1:8QVbjq00YK2f2MQyiKuWMdaKOFRcoD9VuubkNCNOuZo=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-flac/flacpicture v0.2.0 h1:rS/ZOR/ZxlEwMf3yOPFcTAmGyoV6rDtcYdd+6CwWQAw=
|
||||
github.com/go-flac/flacpicture v0.2.0/go.mod h1:M4a1J0v6B5NHsck4GA1yZg0vFQzETVPd3kuj6Ow+q9o=
|
||||
github.com/go-flac/flacvorbis v0.1.0 h1:xStJfPrZ/IoA2oBUEwgrlaSf+Opo6/YuQfkqVhkP0cM=
|
||||
|
@ -46,6 +48,9 @@ golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
|||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
Loading…
Reference in New Issue
Block a user