Skip to content

Instantly share code, notes, and snippets.

@youpy
Created February 4, 2009 18:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youpy/58251 to your computer and use it in GitHub Desktop.
Save youpy/58251 to your computer and use it in GitHub Desktop.
love ☆☆☆☆☆ track
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'json'
require 'pp'
require 'digest/md5'
require 'net/https'
require 'pit'
require 'cgi'
$KCODE = "UTF8"
def main
config = Pit.get("last.fm", :require => {
"api_key" => "your api key in last.fm",
"api_secret" => "your api secret in last.fm"
})
lastfm = Lastfm.new(
config['api_key'],
config['api_secret'],
REST::Connection.new('http://ws.audioscrobbler.com/2.0/'))
unless session = config['session']
token = lastfm.get_token
auth(lastfm.api_key, token)
session = lastfm.get_session(token)
Pit.set('last.fm', :data => {
"session" => session
}.merge(config))
end
itunes_status = ITunesStatus::get_instance
if itunes_status.playing?
current_track = itunes_status.current_track
if current_track[:rating] > 80
lastfm.love(session, current_track[:artist], current_track[:name])
end
end
end
def auth(api_key, token)
auth_url = 'http://www.last.fm/api/auth/?api_key=' + api_key + '&token=' + token
unless system('open', auth_url)
print 'open ' + auth_url + ' in your browser and '
end
print 'after authorization, push any key:'
STDIN.gets.chomp
puts
end
module ITunesStatus
def get_instance
case RUBY_PLATFORM
when /darwin/
Mac.new
when /win/
Windows.new
else
raise "not implemented yet"
end
end
class Mac
def initialize
require 'rbosa'
OSA.utf8_strings = true
@itunes = OSA.app('iTunes')
end
def playing?
@itunes.player_state.to_s == 'playing'
end
def current_track
{
:name => @itunes.current_track.name,
:artist => @itunes.current_track.artist,
:rating => @itunes.current_track.rating
}
end
end
class Windows
def initialize
require 'win32ole'
@itunes = WIN32OLE.new("iTunes.Application")
end
def playing?
@itunes.CurrentTrack
end
def current_track
{
:name => @itunes.CurrentTrack.Name,
:artist => @itunes.CurrentTrack.Artist,
:rating => @itunes.CurrentTrack.Rating
}
end
end
module_function :get_instance
end
class Lastfm
attr_reader :api_key, :api_secret
def initialize(api_key, api_secret, connection)
@api_key = api_key
@api_secret = api_secret
@connection = connection
end
def get_token
request('auth.getToken')['token']
end
def get_session(token)
response = request('auth.getSession', {
:token => token,
})
response['session']['key']
end
def love(session, artist, name)
# FIXME: response format will not be JSON...API bug?
request('track.love', {
:track => name,
:artist => artist,
:sk => session
}, 'post')
end
private
def request(method, params = {}, http_method = 'get')
params[:method] = method
params[:api_key] = @api_key
# http://www.lastfm.jp/group/Last.fm+Web+Services/forum/21604/_/497978
#params[:format] = format
sig = params.to_a.sort_by do |param|
param.first.to_s
end.inject('') do |result, param|
result + param.join('')
end + @api_secret
params.update(:api_sig => Digest::MD5.hexdigest(sig), :format => 'json')
json = JSON.parse(@connection.send(http_method, '', params))
pp json
json
end
end
module REST
class Connection
def initialize(base_url)
@base_url = base_url
end
def get(resource, args = nil)
url = URI.join(@base_url, resource)
if args
url.query = query(args)
end
req = Net::HTTP::Get.new(url.request_uri)
request(req, url)
end
def post(resource, args = nil)
url = URI.join(@base_url, resource)
req = Net::HTTP::Post.new(url.request_uri)
if args
req.body = query(args)
end
request(req, url)
end
def request(req, url)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.port == 443)
res = http.start() { |conn| conn.request(req) }
res.body
end
def query(params)
params.map { |k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
end
end
end
main
# moved to examples/love_daemon.rb in http://github.com/youpy/ruby-itunes-observer/tree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment