Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
package controllers
import play.api._
import play.api.mvc._
import play.api.libs.oauth._
import play.api.libs.ws._
import play.api.libs.iteratee._
object Twitter extends Controller {
// Twitter OAuth keys - retrieve them from dev.twitter.com or via authorization
val consumerKey = ConsumerKey(
"???", "???"
)
val accessToken = RequestToken(
"???", "???"
)
// -- Server Sent Events --
val bytesToString: Enumeratee[Array[Byte], String] = Enumeratee.map[Array[Byte]] { bytes: Array[Byte] =>
new String(bytes)
}
val filterRTs = Enumeratee.filter[String] (!_.startsWith("RT"))
val toServerEvent = Enumeratee.map[String] { tweet =>
"data: " + tweet + "\n"
}
def streamForKeyword(track: String) = Action { request =>
// Stream to output using an Iteratee
Ok stream { socket: Socket.Out[String] => //Socket.Out = Iteratee[Array[Byte], ?]
WS.url("https://stream.twitter.com/1/statuses/filter.json?track=" + track) // withQueryString seems to have a bug
.sign(OAuthCalculator(consumerKey, accessToken))
// Compose the Enumeratees (><> or compose) and apply the result to the Iteratee
.get(_ => bytesToString ><> filterRTs ><> toServerEvent &> socket)
} as "text/event-stream"
}
def showStream = Action { implicit request =>
Ok(views.html.twitterStream())
}
}
@()(implicit request: RequestHeader)
@main("Stream") {
<h1>What's happening right now?</h1>
<form id="form">
<input type="text" name="track" id="track" />
<input type="submit" value="Stream!" />
</form>
<ul id="tweets"></ul>
@helper.javascriptRouter("jsRoutes")(
routes.javascript.Twitter.streamForKeyword
)
<script type="text/javascript">
$(function() {
var source = undefined;
$("#track").focus();
$("#form").submit(function() {
if (source !== undefined)
source.close();
var track = $("#track").val();
source = new EventSource(jsRoutes.controllers.Twitter.streamForKeyword(track).url);
source.onmessage = function(e) {
var tweet = jQuery.parseJSON(e.data);
var fullName = tweet.user.name || "unknown";
var user = tweet.user.screen_name;
var text = tweet.text;
var display = fullName + "(@@" + user + ") - " + text;
$('<li />').text(display).appendTo('#tweets');
};
return false;
});
})
</script>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment