-
Notifications
You must be signed in to change notification settings - Fork 4
/
generic_search.rb
66 lines (60 loc) · 2.04 KB
/
generic_search.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
require 'cgi'
require 'net/http'
#
# Search sites like Google and Wikipedia
#
# You configure the command name and URL pattern. Given a search
# term, it attempts to respond with the URL of the first search
# result. It does so by simply inserting the term into the URL at the
# '%s'. If the url redirects, it responds with the redirect target
# instead, so you get a hint about what you'll see. Otherwise, you
# get just the expanded url pattern.
#
# This is useful for a wide range of sites. Sample config:
#
# generic_search_commands:
# wikipedia: "http://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go"
# google: "http://www.google.com/search?hl=en&q=%s&btnI=I'm+Feeling+Lucky&aq=f&oq="
# php: "http://us3.php.net/manual-lookup.php?pattern=%s&lang=en"
# letmegooglethatforyou: "http://letmegooglethatforyou.com/?q=%s"
#
# Note that the last site never redirects, which is fine.
#
class GenericSearch < CampfireBot::Plugin
attr_reader :commands
def initialize
@commands = bot.config["generic_search_commands"] || {}
commands.each { |c, s|
method = "do_#{c}_command".to_sym
self.class.send(:define_method, method) {|msg|
msg.speak(http_peek(sprintf(s, CGI.escape(msg[:message]))))
}
self.class.on_command(c, method)
}
end
protected
# Follow the url just enough to see if it redirects. If so,
# return the redirect. Otherwise, return the original.
def http_peek(url)
uri = URI.parse url
http = Net::HTTP.new(uri.host, uri.port)
# Unfortunately the net/http(s) API can't seem to do this for us,
# even if we require net/https from the beginning (ruby 1.8)
if uri.scheme == "https"
require 'net/https'
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
res = http.start { |http|
req = Net::HTTP::Get.new uri.request_uri
#req.basic_auth u, p
response = http.request req
}
case res
when Net::HTTPRedirection
uri.merge res.header['Location']
else # Net::HTTPSuccess or error
url
end
end
end