Skip to content

Instantly share code, notes, and snippets.

@xtetsuji
Created March 20, 2012 18:58
Show Gist options
  • Save xtetsuji/2139804 to your computer and use it in GitHub Desktop.
Save xtetsuji/2139804 to your computer and use it in GitHub Desktop.
Search Twitter by Twitter Stream API using AnyEvent::Twitter::Stream
#!/usr/bin/env perl
# written by @xtetsuji at 2012/02/04
use v5.10;
use strict;
use warnings;
use utf8;
use IO::Handle;
use Encode;
use Date::Format 'time2str';
use Date::Parse 'str2time';
use AnyEvent::Twitter::Stream;
### Configuration.
my $username = 'YOUR TWITTER USERANME';
my $password = 'YOUR TWITTER PASSWORD';
### Arguments Processing.
my $keyword = decode_utf8(shift // '');
my $filename = shift;
if ( !length $keyword || $keyword eq '-h' || $keyword eq '--help' || $keyword eq '--usage' ) {
print <<END_USAGE;
Usage:
$0 <keyword> [<append_filename>]
<keyword> is utf8 string
END_USAGE
exit;
}
if ( $username =~ /[^a-zA-Z0-9_]/ || $password =~ /\s/ ) { # maybe not configure $username/$password
# Environment variable support (not recommendeded)
if ( $ENV{TWITTER_USERNAME} && $ENV{TWITTER_PASSWORD} ) {
$username = $ENV{TWITTER_USERNAME};
$password = $ENV{TWITTER_PASSWORD};
}
else {
warn <<END_MSG;
Error:
Please setting \$username and \$password in $0
END_MSG
exit;
}
}
my $condvar = AnyEvent->condvar;
my $fh;
if ( $filename ) {
open $fh, '>>', $filename
or die $!;
$fh->autoflush(1);
$SIG{INT} = sub { $fh->flush(); exit; };
}
# track keywords
my $guard = AnyEvent::Twitter::Stream->new(
username => $username,
password => $password,
method => "filter",
track => encode_utf8($keyword),
on_tweet => sub {
my $tweet = shift;
my $created_at_time = str2time($tweet->{created_at});
my $screen_name = $tweet->{user}->{screen_name};
my $text = $tweet->{text};
for my $url ( @{$tweet->{entities}->{urls}} ) {
my $idxs = $url->{indices};
substr $text, $idxs->[0], $idxs->[1]-$idxs->[0], $url->{expanded_url};
}
my $stream_lines = "[@{[ date_reformat_tiny($created_at_time) ]}] \@$screen_name : $text";
say encode_utf8($stream_lines);
if ( $fh ) {
my $write_lines = "[@{[ date_reformat($created_at_time) ]}] @{[ tweet_url($tweet) ]}\n\@$screen_name : $text";
say {$fh} encode_utf8($write_lines);
}
},
);
$condvar->recv;
sub date_reformat {
# return time2str('%Y/%m/%d %H:%M:%S', str2time(shift));
return time2str('%Y/%m/%d %H:%M:%S', shift);
}
sub date_reformat_tiny {
# return time2str('%H:%M:%S', str2time(time));
return time2str('%H:%M:%S', shift);
}
sub tweet_url {
my $tweet = shift;
return sprintf 'https://twitter.com/%s/status/%d', $tweet->{user}->{screen_name}, $tweet->{id}; # id or id_str
}
__END__
=pod
=encoding utf-8
=head1 NAME
twitter-stream-search.pl - Search Twitter by Twitter Streaming API.
=head1 SYNOPSIS
twitter-stream-search.pl <keyword> [<append_filename>]
twitter-stream-search.pl '#nowplaying'
twitter-stream-search.pl '#nhk,#etv'
twitter-stream-search.pl '#topic' twitter-topic.log
=head1 DESCRIPTIONS
If argument is given only one, this argument is treated SEARCH-KEYWORD.
If argument is given two, first argument is treated SEARCH-KEYWORD and
second argument is APPEND-FILENAME as log.
On two arguments,
if the filename second argument string is not found,
it create newly.
If it is found, append this file.
CAVEATS: On given second argument, it's filename is appended text as text file.
Caution breaking file on no-intention.
=head1 DEPENDENCIES
=over
=item *
Perl 5.10 or higher version.
=item *
L<Date::Format>
=item *
L<Date::Parse>
=item *
L<AnyEvent>
=item *
L<AnyEvent::Twitter::Stream>
=item *
and Some modules required these modules.
=back
=head1 AUTHOR
OGATA Tetsuji E<lt>tetsuji.ogata {at} gmail.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2012 by OGATA Tetsuji.
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment