use vars qw($VERSION %IRSSI);
-$VERSION = "1.7.8";
-my ($REV) = '$Rev: 435 $' =~ /(\d+)/;
+$VERSION = "2.0";
+my ($REV) = '$Rev: 443 $' =~ /(\d+)/;
%IRSSI = (
authors => 'Dan Boger',
contact => 'zigdon@gmail.com',
description => 'Send twitter updates using /tweet. '
. 'Can optionally set your bitlbee /away message to same',
license => 'GNU GPL v2',
- url => 'http://tinyurl.com/twirssi',
- changed => '$Date: 2009-01-27 16:40:26 -0800 (Tue, 27 Jan 2009) $',
+ url => 'http://twirssi.com',
+ changed => '$Date: 2009-01-29 18:25:38 -0800 (Thu, 29 Jan 2009) $',
);
my $window;
my %twits;
my $user;
my $poll;
+my $last_poll;
my %nicks;
my %friends;
-my $last_poll = time - 300;
my %tweet_cache;
my %id_map;
my %irssi_to_mirc_colors = (
if ($twit) {
my $rate_limit = $twit->rate_limit_status();
if ( $rate_limit and $rate_limit->{remaining_hits} < 1 ) {
- ¬ice("Rate limit exceeded, try again later");
+ ¬ice(
+ "Rate limit exceeded, try again after $rate_limit->{reset_time}"
+ );
$twit = undef;
return;
}
$twits{$user} = $twit;
Irssi::timeout_remove($poll) if $poll;
- $poll = Irssi::timeout_add( 300 * 1000, \&get_updates, "" );
+ $poll = Irssi::timeout_add( &get_poll_time * 1000, \&get_updates, "" );
¬ice("Logged in as $user, loading friends list...");
&load_friends();
¬ice( "loaded friends: ", scalar keys %friends );
}
}
+sub cmd_add_search {
+ my ( $data, $server, $win ) = @_;
+
+ unless ( $twit and $twit->can('search') ) {
+ ¬ice("ERROR: Your version of Net::Twitter ($Net::Twitter::VERSION) "
+ . "doesn't support searches." );
+ return;
+ }
+
+ $data =~ s/^\s+|\s+$//;
+ $data = lc $data;
+ if ( exists $id_map{__searches}{$user}{$data} ) {
+ ¬ice("Already had a subscription for '$data'");
+ return;
+ }
+
+ $id_map{__searches}{$user}{$data} = 1;
+ ¬ice("Added subscription for '$data'");
+}
+
+sub cmd_del_search {
+ my ( $data, $server, $win ) = @_;
+
+ unless ( $twit and $twit->can('search') ) {
+ ¬ice("ERROR: Your version of Net::Twitter ($Net::Twitter::VERSION) "
+ . "doesn't support searches." );
+ return;
+ }
+ $data =~ s/^\s+|\s+$//;
+ $data = lc $data;
+ unless ( exists $id_map{__searches}{$user}{$data} ) {
+ ¬ice("No subscription found for '$data'");
+ return;
+ }
+
+ delete $id_map{__searches}{$user}{$data};
+ ¬ice("Removed subscription for '$data'");
+}
+
+sub cmd_list_search {
+ my ( $data, $server, $win ) = @_;
+
+ my $found = 0;
+ foreach my $suser ( sort keys %{ $id_map{__searches} } ) {
+ my $topics;
+ foreach my $topic ( sort keys %{ $id_map{__searches}{$suser} } ) {
+ $topics = $topics ? "$topics, $topic" : $topic;
+ }
+ if ($topics) {
+ $found = 1;
+ ¬ice("Search subscriptions for \@$suser: $topics");
+ }
+ }
+
+ unless ($found) {
+ ¬ice("No search subscriptions set up");
+ }
+}
+
sub cmd_upgrade {
my ( $data, $server, $win ) = @_;
sub do_updates {
my ( $fh, $username, $obj ) = @_;
+ my $rate_limit = $obj->rate_limit_status();
+ if ( $rate_limit and $rate_limit->{remaining_hits} < 1 ) {
+ ¬ice("Rate limit exceeded for $username");
+ return 1;
+ }
+
print scalar localtime, " - Polling for updates for $username" if &debug;
my $tweets;
eval {
printf $fh "id:%d account:%s nick:%s type:dm %s\n",
$t->{id}, $username, $t->{sender_screen_name}, $text;
}
+
+ print scalar localtime, " - Polling for subscriptions" if &debug;
+ if ( $obj->can('search') and $id_map{__searches}{$username} ) {
+ my $search;
+ foreach my $topic ( sort keys %{ $id_map{__searches}{$username} } ) {
+ eval {
+ $search = $obj->search(
+ {
+ q => $topic,
+ since_id => $id_map{__searches}{$username}{$topic}
+ }
+ );
+ };
+
+ if ($@) {
+ print $fh
+ "type:debug Error during search($topic) call. Aborted.\n";
+ return 1;
+ }
+
+ unless ( $search->{max_id} ) {
+ print $fh
+"type:debug Invalid search results when searching for $topic. Aborted.\n";
+ return 1;
+ }
+
+ $id_map{__searches}{$username}{$topic} = $search->{max_id};
+ printf $fh "id:%d account:%s type:searchid topic:%s\n",
+ $search->{max_id}, $username, $topic;
+
+ foreach my $t ( reverse @{ $search->{results} } ) {
+ my $text = decode_entities( $t->{text} );
+ $text =~ s/(^|\W)\@([-\w]+)/$1\cC12\@$2\cO/g;
+ $text =~ s/(^|\W)\#([-\w]+)/$1\cC5\#$2\cO/g;
+ $text =~ s/[\n\r]/ /g;
+ printf $fh "id:%d account:%s nick:%s type:search topic:%s %s\n",
+ $t->{id}, $username, $t->{from_user}, $topic, $text;
+ }
+ }
+ }
+
print scalar localtime, " - Done" if &debug;
return 0;
last if /^__friends__/;
my $hilight = 0;
my %meta;
- foreach my $key (qw/id account nick type/) {
+ foreach my $key (qw/id account nick type topic/) {
if (s/^$key:(\S+)\s*//) {
$meta{$key} = $1;
}
$hilight = MSGLEVEL_HILIGHT;
}
- if ( $meta{type} eq 'tweet' ) {
+ if ( $meta{type} =~ /tweet|reply/ ) {
push @lines,
[
( MSGLEVEL_PUBLIC | $hilight ),
$meta{type}, $account, $meta{nick}, $marker, $_
];
- } elsif ( $meta{type} eq 'reply' ) {
+ } elsif ( $meta{type} eq 'search' ) {
push @lines,
[
( MSGLEVEL_PUBLIC | $hilight ),
- $meta{type}, $account, $meta{nick}, $marker, $_
+ $meta{type}, $account, $meta{topic},
+ $meta{nick}, $marker, $_
];
} elsif ( $meta{type} eq 'dm' ) {
push @lines,
( MSGLEVEL_MSGS | $hilight ),
$meta{type}, $account, $meta{nick}, $_
];
+ } elsif ( $meta{type} eq 'searchid' ) {
+ $id_map{__searches}{ $meta{account} }{ $meta{topic} } =
+ $meta{id};
+ print "Search '$meta{topic}' id set to $meta{id}" if &debug;
} elsif ( $meta{type} eq 'error' ) {
push @lines, [ MSGLEVEL_MSGS, $_ ];
} elsif ( $meta{type} eq 'debug' ) {
print "new last_poll = $new_last_poll" if &debug;
for my $line (@lines) {
$window->printformat(
- @$line[0],
- "twirssi_" . @$line[1],
- @$line[ 2, 3, 4, 5 ]
+ $line->[0],
+ "twirssi_" . $line->[1],
+ @$line[ 2 .. $#$line ]
);
}
}
}
+sub get_poll_time {
+ my $poll = Irssi::settings_get_int("twitter_poll_interval");
+ return $poll if $poll >= 60;
+ return 60;
+}
+
Irssi::signal_add( "send text", "event_send_text" );
Irssi::theme_register(
[
- 'twirssi_tweet', '[$0%B@$1%n$2] $3',
- 'twirssi_reply', '[$0\--> %B@$1%n$2] $3',
- 'twirssi_dm', '[$0%B@$1%n (%WDM%n)] $2',
- 'twirssi_error', 'ERROR: $0',
+ 'twirssi_tweet', '[$0%B@$1%n$2] $3',
+ 'twirssi_search', '[$0%r$1%n:%B@$2%n$3] $4',
+ 'twirssi_reply', '[$0\--> %B@$1%n$2] $3',
+ 'twirssi_dm', '[$0%r@$1%n (%WDM%n)] $2',
+ 'twirssi_error', 'ERROR: $0',
]
);
+Irssi::settings_add_int( "twirssi", "twitter_poll_interval", 300 );
Irssi::settings_add_str( "twirssi", "twitter_window", "twitter" );
Irssi::settings_add_str( "twirssi", "bitlbee_server", "bitlbee" );
Irssi::settings_add_str( "twirssi", "short_url_provider", "TinyURL" );
Irssi::settings_add_bool( "twirssi", "twirssi_use_reply_aliases", 0 );
Irssi::settings_add_bool( "twirssi", "tweet_window_input", 0 );
+$last_poll = time - &get_poll_time;
$window = Irssi::window_find_name( Irssi::settings_get_str('twitter_window') );
if ( !$window ) {
$window =
}
if ($window) {
- Irssi::command_bind( "dm", "cmd_direct" );
- Irssi::command_bind( "dm_as", "cmd_direct_as" );
- Irssi::command_bind( "tweet", "cmd_tweet" );
- Irssi::command_bind( "tweet_as", "cmd_tweet_as" );
- Irssi::command_bind( "twitter_reply", "cmd_reply" );
- Irssi::command_bind( "twitter_reply_as", "cmd_reply_as" );
- Irssi::command_bind( "twitter_login", "cmd_login" );
- Irssi::command_bind( "twitter_logout", "cmd_logout" );
- Irssi::command_bind( "twitter_switch", "cmd_switch" );
- Irssi::command_bind( "twirssi_upgrade", "cmd_upgrade" );
+ Irssi::command_bind( "dm", "cmd_direct" );
+ Irssi::command_bind( "dm_as", "cmd_direct_as" );
+ Irssi::command_bind( "tweet", "cmd_tweet" );
+ Irssi::command_bind( "tweet_as", "cmd_tweet_as" );
+ Irssi::command_bind( "twitter_reply", "cmd_reply" );
+ Irssi::command_bind( "twitter_reply_as", "cmd_reply_as" );
+ Irssi::command_bind( "twitter_login", "cmd_login" );
+ Irssi::command_bind( "twitter_logout", "cmd_logout" );
+ Irssi::command_bind( "twitter_switch", "cmd_switch" );
+ Irssi::command_bind( "twitter_subscribe", "cmd_add_search" );
+ Irssi::command_bind( "twitter_unsubscribe", "cmd_del_search" );
+ Irssi::command_bind( "twitter_list_subscriptions", "cmd_list_search" );
+ Irssi::command_bind( "twirssi_upgrade", "cmd_upgrade" );
if ( Irssi::settings_get_bool("twirssi_use_reply_aliases") ) {
Irssi::command_bind( "reply", "cmd_reply" );
Irssi::command_bind( "reply_as", "cmd_reply_as" );
map { "u: $_->{username}" } values %twits;
print "friends: ", join ", ", sort keys %friends;
print "nicks: ", join ", ", sort keys %nicks;
- print "id_map: ", Dumper \%{ $id_map{__indexes} };
+ print "searches: ", Dumper \%{ $id_map{__searches} };
print "last poll: $last_poll";
}
);