# ============================================================================= # Winamp Log File Parser # Written in Ruby - 5/26 # ============================================================================= # ============================================================================= # Global variables # ============================================================================= popularity = Hash.new popularityArtist = Hash.new # ============================================================================= # Class Definitions # ============================================================================= class Song attr_writer :timeslistened attr_reader :description, :timeslistened def initialize(description, artist, track, datetime) @description = description @artist = artist @track = track @datetime = datetime @timeslistened = 1 end end class Artist attr_writer :timeslistened attr_reader :name, :timeslistened def initialize(name) @name = name @timeslistened = 1 end end # ============================================================================= # Program # ============================================================================= if ARGV[0] == nil or ARGV[0] == "" puts "Need to specify the log file" exit end if ARGV[1] != nil outfile = File.new(ARGV[1], "w") $> = outfile end unless FileTest.exists?(ARGV[0]) puts "Couldn't find file: #{ARGV[0]}" exit end infile = File.new(ARGV[0]) # Process each line in the logfile infile.each_line { |logfile_line| # strip the date / time logfile_line =~ /[[].*[]]/ datetime = $& description = $` a = description.split('-') for i in 0...a.length a[i] = a[i].strip end artist = a[0].strip track = a[1..a.length].join(" ") #puts "Listened: #{datetime}" #puts "Artist: #{artist}" #puts "Song: #{track}" #puts "Description: #{description}" # Add the song to the hash or increment the number of times we've seen it if popularity[description] == nil thisSong = Song.new(description, artist, track, datetime) popularity[description] = thisSong else popularity[description].timeslistened += 1 end # Same with artist hash if popularityArtist[artist] == nil popularityArtist[artist] = Artist.new(artist) else popularityArtist[artist].timeslistened += 1 end } rank = 1 puts "\n[Song popularity]\n\n" # Sort based on timeslistened and print hash popularity.sort {|x, y| y[1].timeslistened <=> x[1].timeslistened }.each { |tSong| percentage = tSong[1].timeslistened.to_f / popularity.size.to_f * 100.0 percentageString = sprintf("%2.1f", percentage) puts "#{rank}. #{tSong[1].description.strip}, #{tSong[1].timeslistened}, (#{percentageString}%)" rank += 1 } puts "\n[Artist popularity]\n\n" rank = 1 # Sort based on timeslistened and print hash popularityArtist.sort { |a,b| b[1].timeslistened <=> a[1].timeslistened }.each { |tArtist| percentage = tArtist[1].timeslistened.to_f / popularity.size.to_f * 100.0 percentageString = sprintf("%2.1f", percentage) puts "#{rank}. #{tArtist[1].name.strip}, #{tArtist[1].timeslistened}, (#{percentageString}%)" rank += 1 }