#!/usr/bin/env ruby # # omptagger # http://github.com/omp/omptagger # Modify and display metadata of audio files. # # Copyright 2007-2010 David Vazgenovich Shakaryan # Distributed under the terms of the GNU General Public License v3. # See http://www.gnu.org/licenses/gpl.txt for the full license text. require 'getoptlong' require 'rubygems' require 'TagLib' class Metadata def output(tag, val) spacing = 2 + @tags.keys.inject(0) do |length, object| object.length > length ? object.length : length end - tag.length puts ' ' + tag + ' ' * spacing + val end end class VorbisComment < Metadata def view puts ' Viewing tags:' if @tags.empty? puts ' No tags are set.' return end @tags.sort.each do |tag, val| val.each do |val| output(tag, val) end end end end class FLAC < VorbisComment def initialize(file) @filename = File.expand_path(file) @write = false @file = TagLib::FLAC::File.new(file) @tags = @file.xiphComment.fieldListMap.hash end end def help puts <<-end Usage: omptagger [options] [files] Options: --view -v View all tags --view-tag -t View a tag --set-tag -s Set a tag --remove -r Remove all tags --remove-tag -d Remove a tag --generate -g Generate tags based on filename --rename -m Generate filename based on tags --scheme -n Specify a file naming scheme --pretend -p Do not make any actual changes --list -l Display list of available tags --help -h Display help information Notes: * The default file naming scheme is Artist - Title. * Schemes must be specified prior to actions that use them. end exit end def list puts <<-end ┌────────────────────────┐ │ Keys Vorbis Comments │ ├────────────────────────┤ │ %a Artist │ │ %b Album │ │ %d Date │ │ %n TrackNumber │ │ %t Title │ │ %* Wildcard │ ├────────────────────────┤ │ Contact │ │ Copyright │ │ Description │ │ Genre │ │ ISRC │ │ License │ │ Location │ │ Organization │ │ Performer │ │ Version │ └────────────────────────┘ end exit end actions = Array.new options = Array.new scheme = '%a - %t' GetoptLong.new( ['--view', '-v', GetoptLong::NO_ARGUMENT], ['--view-tag', '-t', GetoptLong::REQUIRED_ARGUMENT], ['--set-tag', '-s', GetoptLong::REQUIRED_ARGUMENT], ['--remove', '-r', GetoptLong::NO_ARGUMENT], ['--remove-tag', '-d', GetoptLong::REQUIRED_ARGUMENT], ['--generate', '-g', GetoptLong::NO_ARGUMENT], ['--rename', '-m', GetoptLong::NO_ARGUMENT], ['--scheme', '-n', GetoptLong::REQUIRED_ARGUMENT], ['--pretend', '-p', GetoptLong::NO_ARGUMENT], ['--list', '-l', GetoptLong::NO_ARGUMENT], ['--help', '-h', GetoptLong::NO_ARGUMENT] ).each do |option, argument| option = option.delete('-').intern case option when :scheme scheme = argument when :help, :list, :pretend options << option when :viewtag, :settag, :removetag actions << [option, argument] when :generate, :rename actions << [option, scheme] else actions << [option] end end help if options.include?(:help) list if options.include?(:list) help if actions.empty? if ARGV.empty? puts 'No files specified.' exit end ARGV.each do |file| begin raise 'File does not exist.' unless File.exist?(file) case File.extname(file).downcase when '.flac' track = FLAC.new(file) else raise 'File extension not recognised.' end puts file + ':' actions.each do |action| track.send(*action) end rescue RuntimeError => message $stderr.puts file + ':' $stderr.puts ' ' + message end end