--Boundary-00XZ0GzHHsrFl7ks
Content-Type: Multipart/Mixed;
  boundaryoundary-00XZ0GzHHsrFl7ks"

--Boundary-00XZ0GzHHsrFl7ks
Content-Type: text/plain;
  charsettf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Sunday 26 August 2007, Jesse Merriman wrote:
> Here's my solution. Should be pretty straightforward.

Here's a very slightly improved version of id3_tags.rb (which still requires
the other two files I submitted, unchanged). The only change is less ugly
use of String#[], and no more Null constant.


-- 
Jesse Merriman
jessemerriman / warpmail.net
http://www.jessemerriman.com/

--Boundary-00XZ0GzHHsrFl7ks
Content-Type: application/x-ruby;
  named3_tags.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filenamed3_tags.rb"

#!/usr/bin/env ruby
# Ruby Quiz 136: ID3 Tags

require 'genres'
require 'hashy'

#       TAG song  artist  album  year comment genre
Tag  ^TAG(.{30})(.{30})(.{30})(.{4})(.{30})(.)$/

# Retrieve the last n bytes of a file.
def get_last_bytes n, filename
  File.open(filename) do |f|
    f.seek -n, IO::SEEK_END
    f.read
  end
end

# Determine whether the last bytes of a file are a valid ID3 tag.
def valid? str; str[0..2] 'TAG'; end

# Parse the last bytes of a file into a Hash containing the tags.
def parse str
  if m  ag.match(str)
    fields   :song m[1], :artist  m[2], :album m[3],
               :year m[4], :comment m[5], :genre Genres[m[6][0]] }

    com  ields[:comment]
    if com[28].zero?  and not com[29].zero?
      fields[:track]  om[29]
      fields[:comment]  om[0..27]
    end

    fields.map_vals! { |v| (v.is_a?(String) ? v.strip : v) }
  else
    nil
  end
end

if $0 __FILE__
  ARGV.each do |file|
    if File.exists? file and File.readable? file
      puts "#{file}:"
      bytes  et_last_bytes 128, file

      if valid? bytes
        parse(bytes).each { |field, val| puts "  #{field}: #{val}" }
      else
        puts 'No ID3 tag found.'
      end
      puts
    else
      $stderr.puts "Can't read #{file}"
    end
  end
end

--Boundary-00XZ0GzHHsrFl7ks--
--Boundary-00XZ0GzHHsrFl7ks--