From 19bc6c466e8a5c04089289dbdafbcadcc6534e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Mon, 21 Oct 2024 03:57:56 +0900 Subject: [PATCH] refactor: allow multi-part extensions (#102) --- algo/common/dispatch.go | 29 +++++++++++++++--------- cmd/um/main.go | 49 +++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/algo/common/dispatch.go b/algo/common/dispatch.go index 45d1804..34fc282 100644 --- a/algo/common/dispatch.go +++ b/algo/common/dispatch.go @@ -18,25 +18,32 @@ type DecoderParams struct { } type NewDecoderFunc func(p *DecoderParams) Decoder -type decoderItem struct { - noop bool - decoder NewDecoderFunc +type DecoderFactory struct { + noop bool + Suffix string + Create NewDecoderFunc } -var DecoderRegistry = make(map[string][]decoderItem) +var DecoderRegistry []DecoderFactory func RegisterDecoder(ext string, noop bool, dispatchFunc NewDecoderFunc) { - DecoderRegistry[ext] = append(DecoderRegistry[ext], - decoderItem{noop: noop, decoder: dispatchFunc}) + DecoderRegistry = append(DecoderRegistry, + DecoderFactory{noop: noop, Create: dispatchFunc, Suffix: "." + strings.TrimPrefix(ext, ".")}) } -func GetDecoder(filename string, skipNoop bool) (rs []NewDecoderFunc) { - ext := strings.ToLower(strings.TrimLeft(filepath.Ext(filename), ".")) - for _, dec := range DecoderRegistry[ext] { +func GetDecoder(filename string, skipNoop bool) []DecoderFactory { + var result []DecoderFactory + // Some extensions contains multiple dots, e.g. ".kgm.flac", hence iterate + // all decoders for each extension. + name := strings.ToLower(filepath.Base(filename)) + for _, dec := range DecoderRegistry { + if !strings.HasSuffix(name, dec.Suffix) { + continue + } if skipNoop && dec.noop { continue } - rs = append(rs, dec.decoder) + result = append(result, dec) } - return + return result } diff --git a/cmd/um/main.go b/cmd/um/main.go index 04774e9..bace514 100644 --- a/cmd/um/main.go +++ b/cmd/um/main.go @@ -75,12 +75,21 @@ func main() { func printSupportedExtensions() { var exts []string - for ext := range common.DecoderRegistry { + extSet := make(map[string]int) + for _, factory := range common.DecoderRegistry { + ext := strings.TrimPrefix(factory.Suffix, ".") + if n, ok := extSet[ext]; ok { + extSet[ext] = n + 1 + } else { + extSet[ext] = 1 + } + } + for ext := range extSet { exts = append(exts, ext) } sort.Strings(exts) for _, ext := range exts { - fmt.Printf("%s: %d\n", ext, len(common.DecoderRegistry[ext])) + fmt.Printf("%s: %d\n", ext, extSet[ext]) } } @@ -276,7 +285,19 @@ func (p *processor) processFile(filePath string) error { return nil } -func (p *processor) process(inputFile string, allDec []common.NewDecoderFunc) error { +func (p *processor) findDecoder(decoders []common.DecoderFactory, params *common.DecoderParams) (*common.Decoder, *common.DecoderFactory, error) { + for _, factory := range decoders { + dec := factory.Create(params) + err := dec.Validate() + if err == nil { + return &dec, &factory, nil + } + logger.Warn("try decode failed", zap.Error(err)) + } + return nil, nil, errors.New("no any decoder can resolve the file") +} + +func (p *processor) process(inputFile string, allDec []common.DecoderFactory) error { file, err := os.Open(inputFile) if err != nil { return err @@ -284,26 +305,16 @@ func (p *processor) process(inputFile string, allDec []common.NewDecoderFunc) er defer file.Close() logger := logger.With(zap.String("source", inputFile)) - decParams := &common.DecoderParams{ + pDec, decoderFactory, err := p.findDecoder(allDec, &common.DecoderParams{ Reader: file, Extension: filepath.Ext(inputFile), FilePath: inputFile, Logger: logger, + }) + if err != nil { + return err } - - var dec common.Decoder - for _, decFunc := range allDec { - dec = decFunc(decParams) - if err := dec.Validate(); err == nil { - break - } else { - logger.Warn("try decode failed", zap.Error(err)) - dec = nil - } - } - if dec == nil { - return errors.New("no any decoder can resolve the file") - } + dec := *pDec params := &ffmpeg.UpdateMetadataParams{} @@ -365,7 +376,7 @@ func (p *processor) process(inputFile string, allDec []common.NewDecoderFunc) er return fmt.Errorf("get relative dir failed: %w", err) } - inFilename := strings.TrimSuffix(filepath.Base(inputFile), filepath.Ext(inputFile)) + inFilename := strings.TrimSuffix(filepath.Base(inputFile), decoderFactory.Suffix) outPath := filepath.Join(p.outputDir, inputRelDir, inFilename+params.AudioExt) if !p.overwriteOutput {