Skip to content

Instantly share code, notes, and snippets.

@mloughran
Created September 30, 2010 11:01
Show Gist options
  • Select an option

  • Save mloughran/604404 to your computer and use it in GitHub Desktop.

Select an option

Save mloughran/604404 to your computer and use it in GitHub Desktop.

Revisions

  1. mloughran revised this gist Sep 30, 2010. 2 changed files with 6 additions and 7 deletions.
    4 changes: 4 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    Getting started
    ---------------

    First add your twitter username and password. Then server.rb and once it's started open websocket.html in your browser. You should see some tweets appear. If not take a look at the javascript console.
    9 changes: 2 additions & 7 deletions websocket.html
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,6 @@
    if ($('#'+id).length == 0) {
    container.append('<div id="'+id+'"><h1>'+language+'</h1></div>')
    }

    $('#'+id).append('<div class="tweet">'+tweet+'</div>');
    };

    @@ -23,8 +22,6 @@
    socket.onmessage = function(message) {
    var info = JSON.parse(message.data);
    console.log(info.lang, info.tweet);

    // Update a cool graphic thing? Piety chart? I don't know.
    addTweetToPage(info.lang, info.tweet);
    };

    @@ -36,7 +33,5 @@
    </head>

    <body>
    <div class="container">

    </div>
    </body>
    <div class="container"></div>
    </body>
  2. mloughran created this gist Sep 30, 2010.
    38 changes: 38 additions & 0 deletions language_detector.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    require 'em-http'
    require 'json'

    class LanguageDetector
    URL = "http://www.google.com/uds/GlangDetect"

    include EM::Deferrable

    def initialize(text)
    request = EM::HttpRequest.new(URL).get({
    :query => {:v => "1.0", :q => text}
    })

    # This is called if the request completes successfully (whatever the code)
    request.callback {
    begin
    if request.response_header.status == 200
    info = JSON.parse(request.response)["responseData"]
    if info['isReliable']
    self.succeed(info['language'])
    else
    self.fail("Language could not be reliably determined")
    end
    else
    self.fail("Call to fetch language failed")
    end
    rescue
    puts request.response
    self.fail
    end
    }

    # This is called if the request totally failed
    request.errback {
    self.fail("Error making API call")
    }
    end
    end
    38 changes: 38 additions & 0 deletions server.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    require 'rubygems'
    require 'eventmachine'
    require 'em-websocket'
    require 'twitter_stream'
    require 'language_detector'

    TWITTER_USERNAME = ''
    TWITTER_PASSWORD = ''
    TWITTER_TERM = 'twitter'

    EM.run {
    websocket_connections = []

    EM::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
    ws.onopen {
    puts "Websocket connection opened"
    websocket_connections << ws
    }
    ws.onclose {
    puts "Websocket connection closed"
    websocket_connections.delete(ws)
    }
    end

    stream = TwitterStream.new(TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_TERM)
    stream.ontweet { |tweet|
    LanguageDetector.new(tweet).callback { |lang|
    puts "New tweet in #{lang}: #{tweet}"

    websocket_connections.each do |socket|
    socket.send(JSON.generate({
    :lang => lang,
    :tweet => tweet
    }))
    end
    }
    }
    }
    40 changes: 40 additions & 0 deletions twitter_stream.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    require 'em-http'
    require 'json'

    class TwitterStream
    URL = 'http://stream.twitter.com/1/statuses/filter.json'

    def initialize(username, password, term)
    @username, @password = username, password
    @term = term
    @callbacks = []
    @buffer = ""
    listen
    end

    def ontweet(&block)
    @callbacks << block
    end

    private

    def listen
    http = EventMachine::HttpRequest.new(URL).post({
    :head => { 'Authorization' => [@username, @password] },
    :query => { "track" => @term }
    })

    http.stream do |chunk|
    @buffer += chunk
    process_buffer
    end
    end

    def process_buffer
    while line = @buffer.slice!(/.+\r\n/)
    tweet = JSON.parse(line)

    @callbacks.each { |c| c.call(tweet['text']) }
    end
    end
    end
    42 changes: 42 additions & 0 deletions websocket.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    <!DOCTYPE html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(document).ready(function() {
    var container = $('.container');

    var addTweetToPage = function(language, tweet) {
    var id = 'tweet' + language;
    if ($('#'+id).length == 0) {
    container.append('<div id="'+id+'"><h1>'+language+'</h1></div>')
    }

    $('#'+id).append('<div class="tweet">'+tweet+'</div>');
    };

    var socket = new WebSocket('ws://0.0.0.0:8080/');

    socket.onopen = function() {
    console.log("Socket opened");
    };

    socket.onmessage = function(message) {
    var info = JSON.parse(message.data);
    console.log(info.lang, info.tweet);

    // Update a cool graphic thing? Piety chart? I don't know.
    addTweetToPage(info.lang, info.tweet);
    };

    socket.onclose = function() {
    console.log("Socket closed");
    };
    })
    </script>
    </head>

    <body>
    <div class="container">

    </div>
    </body>