perltidy
use strict;
use Irssi;
use Irssi::Irc;
use Net::Twitter;
use HTTP::Date;
use HTML::Entities;
use File::Temp;
use vars qw($VERSION %IRSSI);
use constant { DEBUG => 0 };;
$VERSION = "0.4";
%IRSSI = (
authors => 'Dan Boger',
contact => 'zigdon@gmail.com',
name => 'twirssi',
description => 'Send twitter updates using /tweet. '
. 'Can optionally set your bitlbee /away message to same',
license => 'GNU GPL v2',
url => 'http://irc.peeron.com/~zigdon/twirssi/',
changed => 'Mon Dec 1 15:36:01 PST 2008',
);
my $window;
my $twit;
my $user;
my $poll;
my $last_poll = time;
sub cmd_tweet {
my ( $data, $server, $win ) = @_;
unless ($twit) {
$window->print(
"%R***%n Not logged in! Use /twitter_login username pass!");
return;
}
$data =~ s/^\s+|\s+$//;
unless ($data) {
$window->print("%R***%n Usage: /tweet <update>");
return;
}
unless ($twit->update($data)) {
$window->print( "%R***%n Update failed", MSGLEVEL_PUBLIC );
return;
}
my $away = 0;
if ( Irssi::settings_get_bool("tweet_to_away")
and $data !~ /\@\w/
and $data !~ /^[dD] / )
{
my $server =
Irssi::server_find_tag( Irssi::settings_get_str("bitlbee_server") );
if ($server) {
$server->send_raw("away :$data");
$away = 1;
}
else {
$window->print( "%R***%n Can't find bitlbee server."
. "Update bitlbee_server or disalbe tweet_to_away" );
}
}
if ( $data =~ s/^[dD] // ) {
$window->print( "%R***%n DM sent", MSGLEVEL_PUBLIC );
}
else {
$window->print(
"%R***%n Update sent" . ( $away ? " (and away msg set)" : "" ),
MSGLEVEL_PUBLIC );
}
}
sub cmd_login {
my ( $data, $server, $win ) = @_;
my $pass;
( $user, $pass ) = split ' ', $data, 2;
$twit = Net::Twitter->new(
username => $user,
password => $pass,
source => "twirssi"
);
unless ($twit->verify_credentials()) {
$window->print( "%R***%n Login failed", MSGLEVEL_PUBLIC );
$twit = undef;
return;
}
if ($twit) {
&get_updates;
Irssi::timeout_remove($poll) if $poll;
$poll = Irssi::timeout_add( 300 * 1000, \&get_updates, "" );
$window->print( "%R***%n Logged in as $user", MSGLEVEL_PUBLIC );
}
else {
$window->print( "%R***%n Login failed", MSGLEVEL_PUBLIC );
}
}
sub get_updates {
$window =
Irssi::window_find_name( Irssi::settings_get_str('twitter_window') );
unless ($window) {
Irssi::active_win()
->print( "Can't find a window named '"
. Irssi::settings_get_str('twitter_window')
. "'. Create it or change the value of twitter_window" );
}
unless ($twit) {
$window->print(
"%R***%n Not logged in! Use /twitter_login username pass!");
return;
}
my ($fh, $filename) = File::Temp::tempfile();
my $pid = fork();
if ($pid) { # parent
Irssi::timeout_add_once( 5000, 'monitor_child', [ $filename ]);
} elsif (defined $pid) { # child
close STDIN;
close STDOUT;
close STDERR;
my $new_poll = time;
print scalar localtime, " - Polling for updates" if DEBUG;
my $tweets =
$twit->friends_timeline( { since => HTTP::Date::time2str($last_poll) } ) || [];
foreach my $t ( reverse @$tweets ) {
my $text = decode_entities( $t->{text} );
$text =~ s/%/%%/g;
$text =~ s/\@([-\w]+)/%B\@$1%n/g;
printf $fh "[%%B\@%s%%n] %s\n", $t->{user}{screen_name}, $text
}
print scalar localtime, " - Polling for DMs" if DEBUG;
$tweets =
$twit->direct_messages( { since => HTTP::Date::time2str($last_poll) } ) || [];
foreach my $t ( reverse @$tweets ) {
my $text = decode_entities( $t->{text} );
$text =~ s/%/%%/g;
$text =~ s/\@([-\w]+)/%B\@$1%n/g;
printf $fh "[%%B\@%s%%n (%%WDM%%n)] %s\n", $t->{sender_screen_name}, $text;
}
print scalar localtime, " - Done" if DEBUG;
print $fh $new_poll;
close $fh;
exit;
}
}
sub monitor_child {
my $data = shift;
my $filename = $data->[0];
print scalar localtime, " - checking child log at $filename" if DEBUG;
if (open FILE, $filename) {
my @lines = <FILE>;
close FILE;
if ($lines[-1] =~ /^\d+$/) {
$last_poll = pop @lines;
print "new last_poll = $last_poll" if DEBUG;
foreach my $line (@lines) {
chomp $line;
$window->print($line, MSGLEVEL_PUBLIC);
}
unlink $filename or warn "Failed to remove $filename: $!";
return;
}
}
Irssi::timeout_add_once(5000, 'monitor_child', [$filename]);
}
Irssi::settings_add_str( "twirssi", "twitter_window", "twitter" );
Irssi::settings_add_str( "twirssi", "bitlbee_server", "bitlbee" );
Irssi::settings_add_bool( "twirssi", "tweet_to_away", 0 );
$window = Irssi::window_find_name( Irssi::settings_get_str('twitter_window') );
if ($window) {
Irssi::command_bind( "tweet", "cmd_tweet" );
Irssi::command_bind( "twitter_login", "cmd_login" );
Irssi::command_bind( "twitter_updates", "get_updates" );
$window->print(
"%R***%n Twirssi v$VERSION loaded. Log in with /twitter_login, send updates with /tweet",
MSGLEVEL_PUBLIC
);
}
else {
Irssi::active_win()
->print( "Create a window named "
. Irssi::settings_get_str('twitter_window')
. " or change the value of twitter_window" );
}