Skip to content

Instantly share code, notes, and snippets.

@wesrog
Created December 5, 2008 18:28
Show Gist options
  • Save wesrog/32444 to your computer and use it in GitHub Desktop.
Save wesrog/32444 to your computer and use it in GitHub Desktop.
Last.fm Tagger CLI
# Last.fm Tagger v0.7
#
# Author:
# [email protected]
#
# Abstract:
# For each selected track in iTunes, retrieve the genre from Last.fm and accordingly tag the track.
# Use -q to subdue confirmations
#
# Todo:
# Option to tag artist if no tag exists in last.fm records
# Retrieve all tags above <count>50</count>, prompt for tag choice
begin require 'rubygems'; rescue LoadError; end
%W{rbosa cgi rexml/document}.map { |i| require i }
OSA.utf8_strings = true
class Artist
attr_reader :name, :genre
def initialize(name='', genre='')
@name, @genre = name, genre
query unless name == ''
end
def query
puts %{Querying last.fm for: "#{@name}"...}
begin
doc = REXML::Document.new(Net::HTTP.get(URI("http://ws.audioscrobbler.com/1.0/artist/#{URI.escape(CGI.escape(@name))}/toptags.xml")))
rescue EOFError => e
puts "#{Color.error} Request timed out! Trying again..."
query
end
genre = REXML::XPath.first(doc, "//toptags/tag/name")
genre.nil? ? @genre = "" : @genre = genre.text.strip
@name = name.strip
end
end
class LastfmTagger
@@tagged, @@skipped = 0, 0
def initialize
itunes = OSA.app('iTunes')
@selection = itunes.selection.get
if @selection.empty?
$stderr.puts "#{Color.error} Please select some tracks in iTunes"
else
# construct pseudo Artist to satify @selection loop
@artist = Artist.new
end
end
def process
@selection.each do |track|
# check if artist differs; if so, reinstantiate @artist
if @artist.name.downcase != track.artist.strip.downcase
@artist = Artist.new(track.artist)
# no need to write tag if it is identical, therefore skip until it differs
if track.genre.strip.downcase == @artist.genre.downcase
puts "#{Color.pass} Identical genres. Skipping..."
@@skipped += 1
@input = 'n'
elsif @artist.genre == ""
puts %{#{Color.pass} No tags found for "#{@artist.name}".}
@@skipped += 1
@input = 'n'
else
@input = confirm
end
end
track.genre = @artist.genre if @input == 'y'
end
puts "Done. Tagged #{@@tagged} artists. Skipped #{@@skipped}."
end
def confirm
print %{#{Color.success} Tagging "#{@artist.name}" as "#{@artist.genre}". }
@@tagged += 1
# add some space when in quiet mode
if quiet?
puts
return 'y'
end
print %{Continue? (Y/N) }
gets.chomp.downcase
end
# handles -q argument
def quiet?
return true if ARGV[0] == '-q'
end
end
class Color
def self.pass
"[ \e[33mPASS\e[0m ]"
end
def self.success
"[ \e[32mSUCCESS\e[0m ]"
end
def self.error
"[ \e[31mERROR\e[0m ]"
end
end
LastfmTagger.new.process
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment