Class: Kirby
Overview
In-channel commands:
>> [string of code]
-
Evaluate some Ruby code.
reset_irb
-
Reset the
irb
session. add_svn [repository_url]
-
Watch an svn repository for changes.
Constant Summary collapse
- PATH =
Pathname.new(".").dirname.realpath.to_s
- STORE =
PATH + '/kirby.repositories'
- ATOM =
PATH + '/kirby.atoms'
- PIDFILE =
PATH + '/kirby.pid'
- NICK =
(ARGV[1] or "kirby-dev")
- CHANNEL =
("#" + (ARGV[2] or "kirby-dev"))
- SERVER =
(ARGV[3] or "irc.freenode.org")
- SILENT =
ARGV[6] == "--silent"
Instance Method Summary collapse
-
#connect ⇒ Object
Connect to the IRC server.
-
#listen ⇒ Object
The event loop.
-
#poll ⇒ Object
Look for svn changes.
-
#post(url) ⇒ Object
Post a url to the del.icio.us account.
-
#reset_irb ⇒ Object
Get a new
irb
session. -
#restart ⇒ Object
Connect and reconnect to the server.
-
#say(s) ⇒ Object
Say something in the channel.
-
#try(s) ⇒ Object
Eval a piece of code in the
irb
environment. -
#try_eval(s) ⇒ Object
Inner loop of the try method.
-
#write(s) ⇒ Object
Send a raw string to the server.
Instance Method Details
#connect ⇒ Object
Connect to the IRC server.
34 35 36 37 38 39 |
# File 'lib/kirby.rb', line 34 def connect @socket = TCPSocket.new(SERVER, 6667) write "USER #{[NICK]*3*" "} :#{NICK}" write "NICK #{NICK}" write "JOIN #{CHANNEL}" end |
#listen ⇒ Object
The event loop. Waits for socket traffic, and then responds to it. The server sends PING
every 3 minutes, which means we don’t need a separate thread to check for svn updates. All we do is wake on ping (or channel talking).
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/kirby.rb', line 42 def listen @socket.each do |line| # puts "GOT: #{line.inspect}" poll unless SILENT case line.strip when /^PING/ then write line.sub("PING", "PONG")[0..-3] when /^ERROR/, /KICK #{CHANNEL} #{NICK} / then restart unless line =~ /PRIVMSG/ else if msg = line[/ PRIVMSG #{CHANNEL} \:(.+)/, 1] case msg when /^>>\s*(.+)/ then try $1.chop when /^#{NICK}/ then say "Usage: '>> CODE'. Say 'reset_irb' for a clean session. Say 'add_svn [repository_url]' to watch an svn repository and add_atom [atom_feed_url] to watch an atom feed" when /^reset_irb/ then reset_irb when /^add_svn (.+?)(\s|\r|\n|$)/ then $store[$1] = 0 and say $store.inspect when /^add_atom (.+?)(\s|\r|\n|$)/ then $atom[$1] = '' and say $atom.inspect end unless SILENT post($1) if DELICIOUS_PASS and msg =~ /(http:\/\/.*?)(\s|\r|\n|$)/ end end end end |
#poll ⇒ Object
Look for svn changes.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/kirby.rb', line 98 def poll return unless (Time.now - $last_poll > 15 rescue true) $last_poll = Time.now $store.each do |repo, last| (Hpricot(`svn log #{repo} -rHEAD:#{last} --limit 10 --xml`)/:logentry).reverse[1..-1].each do |ci| $store[repo] = rev = ci.attributes['revision'].to_i say "Commit #{rev} to #{repo.split("/").last} by #{(ci/:author).text}: #{(ci/:msg).text}" end rescue nil end File.open(STORE, 'w') {|f| f.puts YAML.dump($store)} $atom.each do |feed, last| begin e = (Hpricot(open(feed))/:entry).first $atom[feed] = link = e.at("link")['href'] say "#{(e/:title).text} by #{((e/:author)/:name).text} : #{link}" unless link == last rescue end end File.open(ATOM, 'w') {|f| f.puts YAML.dump($atom)} end |
#post(url) ⇒ Object
Post a url to the del.icio.us account.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/kirby.rb', line 121 def post url query = {:url => url, :description => (((Hpricot(open(url))/:title).first.innerHTML or url) rescue url), :tags => (Hpricot(open("http://del.icio.us/url/check?url=#{CGI.escape(url)}"))/'.alphacloud'/:a).map{|s| s.innerHTML}.join(" "), :replace => 'yes' } begin http = Net::HTTP.new('api.del.icio.us', 443) http.use_ssl = true http.start do |http| req = Net::HTTP::Get.new('/v1/posts/add?' + query.map{|k,v| "#{k}=#{CGI.escape(v)}"}.join('&')) req.basic_auth DELICIOUS_USER, DELICIOUS_PASS http.request(req) end.body end end |
#reset_irb ⇒ Object
Get a new irb
session.
84 85 86 87 |
# File 'lib/kirby.rb', line 84 def reset_irb say "Began new irb session" $session = try_eval("!INIT!IRB!") end |
#restart ⇒ Object
Connect and reconnect to the server
25 26 27 28 29 30 31 |
# File 'lib/kirby.rb', line 25 def restart $store = (YAML.load_file STORE rescue {}) $atom = (YAML.load_file ATOM rescue {}) @socket.close if @socket connect listen end |
#say(s) ⇒ Object
Say something in the channel.
78 79 80 81 |
# File 'lib/kirby.rb', line 78 def say s write "PRIVMSG #{CHANNEL} :#{s[0..450]}" sleep 1 end |
#try(s) ⇒ Object
Eval a piece of code in the irb
environment.
72 73 74 75 |
# File 'lib/kirby.rb', line 72 def try s reset_irb unless $session try_eval(s).select{|e| e !~ /^\s+from .+\:\d+(\:|$)/}.each {|e| say e} rescue say "session error" end |
#try_eval(s) ⇒ Object
Inner loop of the try method.
90 91 92 93 94 95 |
# File 'lib/kirby.rb', line 90 def try_eval s reset_irb and return [] if s.strip == "exit" result = open("http://tryruby.hobix.com/irb?cmd=#{CGI.escape(s)}", {'Cookie' => "_session_id=#{$session}"}).read result[/^Your session has been closed/] ? (reset_irb and try_eval s) : result.split("\n") end |
#write(s) ⇒ Object
Send a raw string to the server.
65 66 67 68 69 |
# File 'lib/kirby.rb', line 65 def write s raise RuntimeError, "No socket" unless @socket @socket.puts s += "\r\n" # puts "WROTE: #{s.inspect}" end |