2009/03/02

@LastFmRankをRuby化

2008年1月にPerlで作ったTwitterアカウント@LastFmRankが、開発サーバのEtch->Lenny化に伴い、2008年12月より動かなくなっていたため、Ruby化。
ちょっとだけど、初めてNokogiriを使った。あと、週刊ランキング機能もあったんだけど、そっちは未着手。そのうちやります。

2009/03/03 Update:Last.fm APIが新しくなっていたり、Sortを間違えていたりしたので、全面的に修正した。
2009/03/04 Update:URLも投稿するように変更した。

#! /usr/bin/ruby -Ku

require 'rubygems'
gem 'twitter4r'
require 'time'
require 'twitter'
require 'pit'

require 'open-uri'
require 'nokogiri'
require 'rexml/document'

require 'date'
require 'kconv'
$KCODE = "UTF8"

# Twitter4R バグ回避
require 'cgi'
class Hash
def to_http_str
self.map{|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
end
end

# TinyURL化メソッド
def tinyurl(link)
url = "http://tinyurl.com/api-create.php?url=" + link
open(url) do |http|
res = http.read
return res
end
end

begin
userlist = Array.new
tracks = Array.new

# Nokogiriでついったー部Last.fm部のHTMLを解析
# Last.fmユーザページへのLinkからユーザIDを抽出
doc = Nokogiri::HTML(open('http://twitter.g.hatena.ne.jp/keyword/Last.fm%E9%83%A8'))
doc.xpath('//a[@href]').each do |href|
user = href.get_attribute("href")
if user =~ /.*http:\/\/www\.last.*\/user\// then
user.gsub!(/.*\/user\//,"")
user.gsub!(/\//,"")
userlist << user
end
end

apikey = "YOURAPIKEY"
# 全ユーザIDの最新再生曲情報を取得
userlist.each do |uname|
begin
open('http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=' + uname + '&api_key=' + apikey) do |http|
xml = http.read
doc=nil
doc=REXML::Document.new xml
day = DateTime.parse(doc.elements['/lfm/recenttracks/track/date'].text).to_s
turl = tinyurl(doc.elements['/lfm/recenttracks/track/url'].text)
tracks << [day, uname, doc.elements['/lfm/recenttracks/track/artist'].text, doc.elements['/lfm/recenttracks/track/name'].text, turl]
end
sleep 3
rescue
next
end
end

# 日付で逆ソート
tracks.sort! {|x,y| y[0] <=> x[0]}

txt = "ついったー部 Now Playing! 【" + tracks[0][2] + ":" + tracks[0][3] + "】 by " + tracks[0][1] + " " + tracks[0][4]
mess = Kconv.kconv(txt,Kconv::UTF8)

config = Pit.get("LastFmRank")
cl = Twitter::Client.new(config)
cl.status(:post,mess)

rescue
print "RuntimeError: ", $!, "\n";
end
exit