// cueSheetForFile returns parsed CUE file for the given audio file. // Example. Given a FLAC file path it returns a CUE sheet found in the // same directory which describes the FLAC file. func cueSheetForFile(p *Path) (*cue.Sheet, error) { base := p.Base() parent, err := p.Parent() if err != nil { return nil, err } file, err := os.Open(parent.File()) if err != nil { return nil, err } defer file.Close() names, err := file.Readdirnames(-1) if err != nil { return nil, err } for _, name := range names { if ext(name) == cueExt { child, err := parent.Child(name) if err != nil { continue } sheet, err := cue.ParseFile(child.File()) if err != nil { return nil, err } for _, f := range sheet.Files { if f.Name == base { return sheet, nil } } } } return nil, nil }
// readTracks returns sorted tracks list in the given directory. // Parameter is garanteed to be a folder. func readTracks(p *Path) ([]Entry, error) { file, err := os.Open(p.File()) if err != nil { return nil, err } defer file.Close() names, err := file.Readdirnames(-1) if err != nil { return nil, err } sort.Strings(names) // Process CUE files first and then only audio files which was not // found inside CUE ones. tracks := make([]Entry, 0, len(names)) // Standalone audio files. standaloneFiles := make([]string, 0, len(names)) // Files used in CUEs. As far as tracks for them were generated from // corresponding CUE file they must not be processed as standalone. cueFiles := make([]string, 0, len(names)) for _, name := range names { cp, err := p.Child(name) if err != nil { return nil, err } if cp.IsDir() { continue } if cp.Ext() == cueExt { sheet, err := cue.ParseFile(cp.File()) if err != nil { continue } cueTracks, err := cueSheetTracks(p, sheet) if err != nil { continue } tracks = append(tracks, cueTracks...) for _, f := range sheet.Files { cueFiles = append( cueFiles, f.Name) } } else { standaloneFiles = append(standaloneFiles, name) } } // Now process non-cue audio files. sort.Strings(cueFiles) for _, name := range standaloneFiles { if stringsPresent(cueFiles, name) { continue } pp, err := p.Child(name) if err != nil { // TODO: Log ignored file. } else { ext := strings.ToLower(pp.Ext()) if format(ext) != nil { track, err := pp.Track() if err != nil { panic("not track") } tracks = append(tracks, track) } } } return tracks, nil }