Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created April 18, 2010 00:23
Show Gist options
  • Save tenderlove/369920 to your computer and use it in GitHub Desktop.
Save tenderlove/369920 to your computer and use it in GitHub Desktop.
event based twitter stream client
require 'socket'
require 'psych'
###
# Event based Twitter stream client. Yields tweets as they happen from the
# "sample" stream. Requires Ruby 1.9.2.
#
# Example:
#
# sc = StreamClient.new($username, $password)
# sc.each do |tweet|
# puts tweet['text']
# end
#
# See http://tenderlovemaking.com/2010/04/17/event-based-json-and-yaml-parsing/
class StreamClient
class Listener < Psych::TreeBuilder
def initialize block
@block = block
super()
end
def end_document implicit_end
super
@block.call @last.children.pop.to_ruby
end
end
def initialize user, pass
@ba = ["#{user}:#{pass}"].pack('m').chomp
end
def each &block
socket = TCPSocket.new 'stream.twitter.com', 80
socket.write "GET /1/statuses/sample.json HTTP/1.1\r\n"
socket.write "Host: stream.twitter.com\r\n"
socket.write "Authorization: Basic #{@ba}\r\n"
socket.write "\r\n"
# Read the headers
while((line = socket.readline) != "\r\n"); puts line if $DEBUG; end
reader, writer = IO.pipe
producer = Thread.new(socket, writer) do |s, io|
loop do
io.write "---\n"
io.write s.read s.readline.strip.to_i 16
io.write "...\n"
s.read 2 # strip the blank line
end
end
parser = Psych::Parser.new Listener.new block
parser.parse reader
producer.join
end
end
sc = StreamClient.new(ARGV[0], ARGV[1])
sc.each do |tweet|
p tweet
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment