plugins/opensearchbot.nb
# -*-ruby-*- #
# Copyright (C) 2011 Kazuhiro NISHIYAMA
#
# This program is free software with ABSOLUTELY NO WARRANTY.
# You can re-distribute and/or modify this program under
# the same terms of the Ruby's license.
#
=begin
== Usage with irc client
bing> keyword
-> search keyword by bing
googlecode> keyword
-> search keyword by Google Code Search Data API (Deprecated)
koders> keyword
-> search keyword by koders
== Configuration:
BotConfig << {
:name => :OpenSearchBot,
:bot_name => 'bing',
:ch => //,
:referer => 'https://github.com/nadoka/nadoka',
:ch_kcode => :jis,
:html => 'http://www.bing.com/search?q={searchTerms}',
:rss => 'http://api.search.live.com/rss.aspx?source=web&query={searchTerms}'
,
}
BotConfig << {
:name => :OpenSearchBot,
:bot_name => 'googlecode',
:ch => //,
:ch_kcode => :jis,
:referer => 'https://github.com/nadoka/nadoka',
# Google Code Search Data API (Deprecated)
# http://code.google.com/intl/ja/apis/codesearch/docs/2.0/developers_guide.h
tml
:html => 'http://www.google.com/codesearch?q={searchTerms}',
:rss => 'http://www.google.com/codesearch/feeds/search?q={searchTerms}',
}
BotConfig << {
:name => :OpenSearchBot,
:bot_name => 'koders',
:ch => //,
:referer => 'https://github.com/nadoka/nadoka',
:ch_kcode => :jis,
# http://www.koders.com/search/KodersDescriptionOS1_1.xml
:html => 'http://www.koders.com/?s={searchTerms}',
:rss => 'http://www.koders.com/?s={searchTerms}&results=code&output=rss&OSve
rsion=1.1',
}
=end
require 'open-uri'
require 'uri'
require 'cgi'
class OpenSearch
def initialize(options)
@html = options[:html]
@rss = options[:rss]
@referer = options[:referer] || 'https://github.com/nadoka/nadoka'
end
def result(key)
escaped_key = CGI.escape(key)
link = @html.sub(/\{searchTerms\}/) { escaped_key }
uri = @rss.sub(/\{searchTerms\}/) { escaped_key }
open(uri, "Referer" => @referer) do |f|
result = f.read
if /<([A-Za-z]+):totalResults>(\d+)<\/\1:totalResults>/ =~ result
total = $2.to_i
return "#{total.to_s.gsub(/\d(?=\d{3}+\z)/,'\&,')} result#{total > 1 ? 's' : ''} in #{link}"
else
return "#{key} - not found in #{link}"
end
end
end
end
if __FILE__ == $0
h = {
'bing' => {
:referer => 'https://github.com/nadoka/nadoka',
:html => 'http://www.bing.com/search?q={searchTerms}',
:rss => 'http://api.search.live.com/rss.aspx?source=web&query={searchTerms}',
},
'googlecode' => {
:referer => 'https://github.com/nadoka/nadoka',
# Google Code Search Data API (Deprecated)
# http://code.google.com/intl/ja/apis/codesearch/docs/2.0/developers_guide.html
:html => 'http://www.google.com/codesearch?q={searchTerms}',
:rss => 'http://www.google.com/codesearch/feeds/search?q={searchTerms}',
},
'koders' => {
:referer => 'https://github.com/nadoka/nadoka',
# http://www.koders.com/search/KodersDescriptionOS1_1.xml
:html => 'http://www.koders.com/?s={searchTerms}',
:rss => 'http://www.koders.com/?s={searchTerms}&results=code&output=rss&OSversion=1.1',
},
'youtube' => {
:referer => 'https://github.com/nadoka/nadoka',
:html => 'http://www.youtube.com/results?search_query={searchTerms}',
:rss => 'http://gdata.youtube.com/feeds/api/videos?q={searchTerms}',
},
}
engine = ARGV.shift
if h.key?(engine)
open_search = OpenSearch.new(h[engine])
ARGV.each do |key|
result = open_search.result(key)
puts result
end
else
STDERR.puts "usage: #{$0} {#{h.keys.sort.join('|')}} key ..."
end
exit
end
class OpenSearchBot < Nadoka::NDK_Bot
def bot_initialize
if @bot_config.key?(:channels)
channels = '\A(?:' + @bot_config[:channels].collect{|ch|
Regexp.quote(ch)
}.join('|') + ')\z'
@available_channel = Regexp.compile(channels)
else
@available_channel = @bot_config[:ch] || //
end
@bot_name = @bot_config[:bot_name] || 'OpenSearchBot'
@open_search = OpenSearch.new(@bot_config)
@pattern = @bot_config[:pattern] || /\A#{Regexp.quote(@bot_name)}\s*[<:>]\s*(.+)/
@ch_kcode = @bot_config[:ch_kcode]
end
def on_privmsg prefix, ch, msg
if @pattern =~ msg
key = $1
if @ch_kcode == :jis
ret = @open_search.result(key.toutf8).tojis
else
ret = @open_search.result(key)
end
send_notice ch, "#{@bot_name} bot: #{ret}"
end
end
end