Skip to content

Instantly share code, notes, and snippets.

@mostlyfine
Created February 17, 2012 10:58
Show Gist options
  • Select an option

  • Save mostlyfine/1852672 to your computer and use it in GitHub Desktop.

Select an option

Save mostlyfine/1852672 to your computer and use it in GitHub Desktop.
Mojolicious::Lite and AnyEvent::Twitter::Stream and WebSocket
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Mojolicious::Lite;
use Encode;
use EV;
use AnyEvent::Twitter::Stream;
use POSIX;
use Mojo::JSON;
use Log::Minimal;
my $clients = {};
my $config = app->plugin('Config', {file => app->home->rel_file('twitter.conf')});
if (exists $config->{logfile}) {
open my $fh, '>>:utf8', $config->{logfile};
select( ( select($fh), $| = 1 )[0] );
$Log::Minimal::PRINT = sub { print $fh "$_[2]\n"; };
} else {
$Log::Minimal::COLOR = 1;
}
my $listener = AnyEvent::Twitter::Stream->new(
token => $config->{token},
token_secret => $config->{token_secret},
consumer_key => $config->{consumer_key},
consumer_secret => $config->{consumer_secret},
method => "filter",
track => $config->{keyword},
timeout => 120,
on_tweet => sub {
my $tweet = shift;
my $user = $tweet->{user}{screen_name};
my $text = $tweet->{text}||'';
my $profile_image_url = $tweet->{user}{profile_image_url};
my $lang = $tweet->{user}{lang}||'';
return if $lang ne 'ja';
return unless $user and $text;
my $json = Mojo::JSON->new;
my $time = POSIX::strftime '%Y-%m-%d %H:%M:%S', localtime;
my $msg = $json->encode({
time => $time,
user => $user,
text => $text,
icon => $profile_image_url,
});
infof("$time, $user, $text");
utf8::decode($msg);
foreach (keys %$clients) {
$clients->{$_}->send_message($msg);
}
},
on_error => sub {
my $error = shift;
warnf($error);
app->log->info("ERRROR: $error");
},
);
get '/' => sub {
my $self = shift;
$self->render('index');
};
websocket '/echo' => sub {
my $self = shift;
$self->app->log->debug("Client connected");
my $id = "$self";
$clients->{$id} = $self;
$self->on(message => sub {});
$self->on(finish => sub {
my ($self) = @_;
$self->app->log->debug("Client disconnected");
delete $clients->{$id};
}
);
};
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<title>Mojolicious::Lite + WebSocket + AnyEvent::Twitter::Stream</title>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript">
$(function() {
var log = function(text) {
$('<blockquote>'+text+'</blockquote>').hide().fadeIn().prependTo('#container');
};
log("Connection start...");
var ws;
if ("WebSocket" in window) {
ws = new WebSocket("<%= url_for('echo')->to_abs %>");
} else if ("MozWebSocket" in window) {
ws = new MozWebSocket("<%= url_for('echo')->to_abs %>");
}
ws.onopen = function(msg) {
log('Connection opened');
};
ws.onmessage = function(msg) {
var res = JSON.parse(msg.data);
log("<p><img width='48' height='48' src='" + res.icon + "'> " + res.text + "</p><small>" + res.user + " at " + res.time + "</small>");
};
ws.onerror = function(msg) {
log('Connection error');
};
ws.onclose = function(msg) {
log('Connection closed');
};
});
</script>
</head>
<body>
<header>
<h1><%= config->{keyword} %></h1>
</header>
<div id="container" class="container">
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment