--Boundary-00 PY0G1htRWIYx/V Content-Type: Multipart/Mixed; boundaryoundary-00 PY0G1htRWIYx/V" --Boundary-00 PY0G1htRWIYx/V Content-Type: text/plain; charset tf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Here's my solution. Should be pretty straightforward. id3_tags.rb takes a list of filenames as arguments: $ ./id3_tags.rb 04_Prepare_Yourself.mp3 05_Moonloop.mp3 04_Prepare_Yourself.mp3: song: Prepare Yourself track: 4 artist: Porcupine Tree comment: some comment year: 1995 album: The Sky Moves Sideways genre: Progressive Rock 05_Moonloop.mp3: song: Moonloop track: 5 artist: Porcupine Tree comment: test comment year: 1995 album: The Sky Moves Sideways genre: Progressive Rock -- Jesse Merriman jessemerriman / warpmail.net http://www.jessemerriman.com/ --Boundary-00 PY0G1htRWIYx/V Content-Type: application/x-ruby; name ashy.rb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename ashy.rb" #!/usr/bin/env ruby # Ruby Quiz 136: ID3 Tags class Hash def map_keys! # This is kind of heavy, but we can't just iterate through like map_vals! # because earlier keys might map to later keys, and we'd lose stuff. # Consider {1 a, 2 b}.map_keys! { |k| k+1 } pairs o_a.map { |pair| [yield(pair.first), pair.last] } clear pairs.each { |pair| self[pair.first] air.last } self end def map_vals! each { |k, v| self[k] ield(v) } self end end --Boundary-00 PY0G1htRWIYx/V Content-Type: application/x-ruby; name enres.rb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename enres.rb" #!/usr/bin/env ruby # Ruby Quiz 136: ID3 Tags require 'hashy' # Genre codes, taken from `mp3info -G` # The only edits were adding backslashes before spaces within genre names. Genres ash[*%w{ 123 A\ Cappella 25 Euro-Techno 13 Pop 74 Acid\ Jazz 54 Eurodance 109 Porn\ Groove 73 Acid\ Punk 84 Fast-Fusion 117 Power\ Ballad 34 Acid 81 Folk/Rock 23 Pranks 99 Acoustic 115 Folklore 108 Primus 40 Alt.\ Rock 80 Folk 92 Progressive\ Rock 20 Alternative 119 Freestyle 93 Psychedelic\ Rock 26 Ambient 5 Funk 67 Psychedelic 145 Anime 30 Fusion 121 Punk\ Rock 90 Avantgarde 36 Game 43 Punk 116 Ballad 59 Gangsta\ Rap 14 R&B 41 Bass 126 Goa 15 Rap 135 Beat 38 Gospel 68 Rave 85 Bebob 91 Gothic\ Rock 16 Reggae 96 Big\ Band 49 Gothic 76 Retro 138 Black\ Metal 6 Grunge 87 Revival 89 Bluegrass 79 Hard\ Rock 118 Rhythmic\ Soul 0 Blues 129 Hardcore 78 Rock\ &\ Roll 107 Booty\ Bass 137 Heavy\ Metal 17 Rock 132 BritPop 7 Hip-Hop 143 Salsa 65 Cabaret 35 House 114 Samba 88 Celtic 100 Humour 110 Satire 104 Chamber\ Music 131 Indie 69 Showtunes 102 Chanson 19 Industrial 21 Ska 97 Chorus 46 Instrumental\ Pop 111 Slow\ Jam 136 Christian\ Gangsta\ Rap 47 Instrumental\ Rock 95 Slow\ Rock 61 Christian\ Rap 33 Instrumental 105 Sonata 141 Christian\ Rock 146 JPop 42 Soul 1 Classic\ Rock 29 Jazz+Funk 37 Sound\ Clip 32 Classical 8 Jazz 24 Soundtrack 128 Club-House 63 Jungle 56 Southern\ Rock 112 Club 86 Latin 44 Space 57 Comedy 71 Lo-Fi 101 Speech 140 Contemporary\ Christian 45 Meditative 83 Swing 2 Country 142 Merengue 94 Symphonic\ Rock 139 Crossover 9 Metal 106 Symphony 58 Cult 77 Musical 147 Synthpop 125 Dance\ Hall 82 National\ Folk 113 Tango 3 Dance 64 Native\ American 51 Techno-Industrial 50 Darkwave 133 Negerpunk 18 Techno 22 Death\ Metal 10 New\ Age 130 Terror 4 Disco 66 New\ Wave 144 Thrash\ Metal 55 Dream 39 Noise 60 Top\ 40 127 Drum\ &\ Bass 11 Oldies 70 Trailer 122 Drum\ Solo 103 Opera 31 Trance 120 Duet 12 Other 72 Tribal 98 Easy\ Listening 75 Polka 27 Trip-Hop 52 Electronic 134 Polsk\ Punk 28 Vocal 48 Ethnic 53 Pop-Folk 124 Euro-House 62 Pop/Funk }].map_keys! { |k| k.to_i } --Boundary-00 PY0G1htRWIYx/V Content-Type: application/x-ruby; name d3_tags.rb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename d3_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})(.)$/ Null \000" # 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..28] Null and com[29..29] ! ull fields[:track] om[29..29][0] 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-00 PY0G1htRWIYx/V-- --Boundary-00 PY0G1htRWIYx/V--