예제 #1
0
파일: main.go 프로젝트: songtools/songtools
func findFormat(name, path string, buffer *bytes.Buffer, filter func(*format.Format) bool) (*format.Format, error) {
	formats := format.Formats{}

	if name != "" {
		f, ok := format.ByName(name)
		if !ok {
			return nil, fmt.Errorf("unable to find format %q", name)
		}

		formats = append(formats, f)
	} else if path != "" {
		ext := filepath.Ext(path)
		if ext != "" {
			formats = format.RegisteredFormats()
			formats = formats.Filter(func(f *format.Format) bool {
				for _, e := range f.Extensions {
					if strings.ToLower(e) == ext {
						return true
					}
				}

				return false
			})
		}
	}

	formats = formats.Filter(filter)

	if len(formats) > 0 {
		return formats[0], nil
	}

	return nil, fmt.Errorf("unable to find format")
}
예제 #2
0
파일: main.go 프로젝트: songtools/songtools
func (cmd *options) execute(args []string) error {

	if len(args) > 1 {
		return fmt.Errorf("too many positional arguments")
	}

	var err error
	in := os.Stdin
	file := ""
	if len(args) == 1 {
		file = args[0]
		in, err = os.Open(file)
		if err != nil {
			return fmt.Errorf("unable to open %q: %v", file, err)
		}
	}

	inBytes, err := ioutil.ReadAll(in)
	if err != nil {
		return fmt.Errorf("unable to read: %v", err)
	}

	input := bytes.NewBuffer(inBytes)

	readFormat, err := findReadFormat(cmd.CurrentFormat, file, input)
	if err != nil {
		return fmt.Errorf("unable to find input format for %q: %v", file, err)
	}

	writeFormat := readFormat
	if cmd.ToFormat != "" {
		var ok bool
		if writeFormat, ok = format.ByName(cmd.ToFormat); !ok {
			return fmt.Errorf("unable to find output format %q", cmd.ToFormat)
		}
	}

	if writeFormat.Writer == nil {
		return fmt.Errorf("the input format %q is unable to be used for writing", readFormat.Name)
	}

	song, err := readFormat.Reader.Read(input)
	if err != nil {
		return fmt.Errorf("unable to parse %q: %v", file, err)
	}

	setSongTitleIfNecessary(file, song)

	if cmd.ToKey != "" {
		fromKey := songtools.Key(cmd.CurrentKey)

		if fromKey == "" && song.Key == "" {
			return fmt.Errorf("unable to get current key")
		} else if fromKey == "" {
			fromKey = song.Key
		}

		toKey := songtools.Key(cmd.ToKey)

		noteNames, interval, err := songtools.NoteNamesAndIntervalFromKeyToKey(fromKey, toKey)
		if err != nil {
			return fmt.Errorf("unable to get note names and interval: %v", err)
		}

		song, err = songtools.TransposeSong(song, interval, noteNames)
		if err != nil {
			return fmt.Errorf("unable to transpose from %q to %q: %v", fromKey, toKey, err)
		}

		song.Key = toKey
	}

	out := os.Stdout
	defer out.Close()

	if cmd.Out == "<unset>" {
		name := song.Title
		if name == "" && file == "" {
			return fmt.Errorf("'out' was specified, but the song does not have a title and the input was not a file")
		} else if name == "" {
			_, file := filepath.Split(file)
			ext := filepath.Ext(file)
			name = strings.TrimSuffix(file, ext)
		}

		if len(writeFormat.Extensions) > 0 {
			name += writeFormat.Extensions[0]
		}

		cmd.Out = name
	}

	if cmd.Out != "" {
		out, err = os.OpenFile(cmd.Out, os.O_CREATE, 0666)
		if err != nil {
			return fmt.Errorf("unable to open %q: %v", cmd.Out, err)
		}
	}

	return writeFormat.Writer.Write(out, song)
}