#
# License:: GPL v2
-require 'open-uri'
-
class ::LastFmEvent
+ SELECTOR = /<tr class="vevent.*?<\/tr>/m
# matches are:
# 1. day 2. moth 3. year 4. url_who 5. who 6. url_where 7. where 8. how_many
- REGEXP = /<tr class="vevent\s+\w+\s+\S+?-(\d\d)-(\d\d)-(\d\d\d\d)\s*">.*?<a class="url summary" href="(\/event\/\d+)">(.*?)<\/a>.*?<a href="(\/venue\/\d+)">(.*?)<\/a>.*?<td class="attendance">(.*?)<\/td>\s+<\/tr>/m
+ # TODO festival have TWO dates -------+
+ # TODO event type -------------+ |
+ # V V
+ MATCHER = /<tr class="vevent\s+\w+\s+(?:\S+\s+)?\S+?-(\d\d)-(\d\d)-(\d\d\d\d)\s*">.*?<a class="url summary" href="(\/event\/\d+)">(.*?)<\/a>.*?<a href="(\/venue\/\d+)">(.*?)<\/a>.*?<td>(?:(.*?) attending\s+)?.*?<\/td>\s+<\/tr>/m
attr_accessor :url, :date, :artist, :location, :attendance
def initialize(url, date, artist, location, attendance)
@url = url
end
class LastFmPlugin < Plugin
- BotConfig.register BotConfigIntegerValue.new('lastfm.max_events',
+ Config.register Config::IntegerValue.new('lastfm.max_events',
:default => 25, :validate => Proc.new{|v| v > 1},
:desc => "Maximum number of events to display.")
- BotConfig.register BotConfigIntegerValue.new('lastfm.default_events',
+ Config.register Config::IntegerValue.new('lastfm.default_events',
:default => 3, :validate => Proc.new{|v| v > 1},
:desc => "Default number of events to display.")
artist = params[:who].to_s if params[:who]
page = nil
spec = location ? "in #{location}" : "by #{artist}"
+ query = location ? "?findloc=#{CGI.escape(location)}" : "?s=#{CGI.escape(artist)}&findloc="
begin
- if location
- esc = CGI.escape(location)
- page = @bot.httputil.get "#{LASTFM}/events/?findloc=#{esc}"
- else
- esc = CGI.escape(artist)
- page = @bot.httputil.get "#{LASTFM}/events?s=#{esc}&findloc="
- end
-
+ page = @bot.httputil.get LASTFM + "/events/" + query
if page
events = Array.new
disp_events = Array.new
- pre_events = page.scan(LastFmEvent::REGEXP)
+ pre_events = page.scan(LastFmEvent::SELECTOR)
# debug pre_events.inspect
if pre_events.empty?
# We may not find any even because the page gives a list
if page.match(/<a href="(\/events\/\?l=[^"]+)">/)
debug "Rechecking with #{$1}"
page = @bot.httputil.get(LASTFM+$1)
- pre_events = page.scan(LastFmEvent::REGEXP) if page
+ debug page
+ pre_events = page.scan(LastFmEvent::SELECTOR) if page
+ debug pre_events
end
if pre_events.empty?
m.reply "No events found #{spec}, sorry"
return
end
end
- pre_events.each { |day, month, year, url_who, who, url_where, where, how_many|
+ pre_events.each { |s| s.scan(LastFmEvent::MATCHER) { |day, month, year, url_who, who, url_where, where, how_many|
date = Time.utc(year.to_i, month.to_i, day.to_i)
url = LASTFM + url_who
if who.match(/<strong>(.*?)<\/strong>(.+)?/)
debug where.inspect
loc = where.ircify_html
end
- attendance = how_many.ircify_html
+ attendance = how_many ? how_many.ircify_html : ''
events << LastFmEvent.new(url, date, artist, loc, attendance)
- }
+ } }
# debug events.inspect
events[0...num].each { |event|
end
wiki = "This artist doesn't have a description yet. You can help by writing it: #{url}/+wiki?action=edit"
- if page.match(/<div class="wikiAbstract">(.*?)<\/div>/m)
+ if page.match(/<div (?:class|id)="wikiAbstract">(.*?)<\/div>/m)
wiki = $1.ircify_html
end
action = :neighbours if action == :neighbors
user = params[:user]
begin
- data = open("http://ws.audioscrobbler.com/1.0/user/#{user}/#{action}.txt")
+ data = @bot.httputil.get("http://ws.audioscrobbler.com/1.0/user/#{user}/#{action}.txt")
m.reply "#{action} for #{user}:"
m.reply data.to_a[0..3].map{|l| l.split(',',2)[-1].chomp}.join(", ")
rescue
end
plugin = LastFmPlugin.new
-plugin.map 'lastfm [:num] event[s] in *location', :action => :find_event, :requirements => { :num => /\d+/ }
-plugin.map 'lastfm [:num] event[s] by *who', :action => :find_event, :requirements => { :num => /\d+/ }
-plugin.map 'lastfm [:num] event[s] [for] *who', :action => :find_event, :requirements => { :num => /\d+/ }
-plugin.map 'lastfm artist *who', :action => :find_artist
-plugin.map 'lastfm group *who', :action => :find_artist
+plugin.map 'lastfm [:num] event[s] in *location', :action => :find_event, :requirements => { :num => /\d+/ }, :thread => true
+plugin.map 'lastfm [:num] event[s] by *who', :action => :find_event, :requirements => { :num => /\d+/ }, :thread => true
+plugin.map 'lastfm [:num] event[s] [for] *who', :action => :find_event, :requirements => { :num => /\d+/ }, :thread => true
+plugin.map 'lastfm artist *who', :action => :find_artist, :thread => true
+plugin.map 'lastfm group *who', :action => :find_artist, :thread => true
plugin.map 'lastfm track *dunno', :action => :find_track
plugin.map 'lastfm song *dunno', :action => :find_track
plugin.map 'lastfm album *dunno', :action => :find_album
-plugin.map 'lastfm :action *user'
+plugin.map 'lastfm :action *user', :thread => true