1111
1212use vars qw( $VERSION %IRSSI) ;
1313
14- $VERSION = " 1.7.8 " ;
15- my ($REV ) = ' $Rev: 435 $' =~ / (\d +)/ ;
14+ $VERSION = " 2.0 " ;
15+ my ($REV ) = ' $Rev: 443 $' =~ / (\d +)/ ;
1616%IRSSI = (
1717 authors => ' Dan Boger' ,
1818 contact => ' zigdon@gmail.com' ,
1919 name => ' twirssi' ,
2020 description => ' Send twitter updates using /tweet. '
2121 . ' Can optionally set your bitlbee /away message to same' ,
2222 license => ' GNU GPL v2' ,
23- url => ' http://tinyurl .com/twirssi ' ,
24- changed => ' $Date: 2009-01-27 16:40:26 -0800 (Tue, 27 Jan 2009) $' ,
23+ url => ' http://twirssi .com' ,
24+ changed => ' $Date: 2009-01-29 18:25:38 -0800 (Thu, 29 Jan 2009) $' ,
2525);
2626
2727my $window ;
2828my $twit ;
2929my %twits ;
3030my $user ;
3131my $poll ;
32+ my $last_poll ;
3233my %nicks ;
3334my %friends ;
34- my $last_poll = time - 300;
3535my %tweet_cache ;
3636my %id_map ;
3737my %irssi_to_mirc_colors = (
@@ -377,14 +377,16 @@ sub cmd_login {
377377 if ($twit ) {
378378 my $rate_limit = $twit -> rate_limit_status();
379379 if ( $rate_limit and $rate_limit -> {remaining_hits } < 1 ) {
380- ¬ice(" Rate limit exceeded, try again later" );
380+ ¬ice(
381+ " Rate limit exceeded, try again after $rate_limit ->{reset_time}"
382+ );
381383 $twit = undef ;
382384 return ;
383385 }
384386
385387 $twits {$user } = $twit ;
386388 Irssi::timeout_remove($poll ) if $poll ;
387- $poll = Irssi::timeout_add( 300 * 1000, \&get_updates, " " );
389+ $poll = Irssi::timeout_add( &get_poll_time * 1000, \&get_updates, " " );
388390 ¬ice(" Logged in as $user , loading friends list..." );
389391 &load_friends();
390392 ¬ice( " loaded friends: " , scalar keys %friends );
@@ -405,6 +407,65 @@ sub cmd_login {
405407 }
406408}
407409
410+ sub cmd_add_search {
411+ my ( $data , $server , $win ) = @_ ;
412+
413+ unless ( $twit and $twit -> can(' search' ) ) {
414+ ¬ice(" ERROR: Your version of Net::Twitter ($Net::Twitter::VERSION ) "
415+ . " doesn't support searches." );
416+ return ;
417+ }
418+
419+ $data =~ s / ^\s +|\s +$// ;
420+ $data = lc $data ;
421+ if ( exists $id_map {__searches }{$user }{$data } ) {
422+ ¬ice(" Already had a subscription for '$data '" );
423+ return ;
424+ }
425+
426+ $id_map {__searches }{$user }{$data } = 1;
427+ ¬ice(" Added subscription for '$data '" );
428+ }
429+
430+ sub cmd_del_search {
431+ my ( $data , $server , $win ) = @_ ;
432+
433+ unless ( $twit and $twit -> can(' search' ) ) {
434+ ¬ice(" ERROR: Your version of Net::Twitter ($Net::Twitter::VERSION ) "
435+ . " doesn't support searches." );
436+ return ;
437+ }
438+ $data =~ s / ^\s +|\s +$// ;
439+ $data = lc $data ;
440+ unless ( exists $id_map {__searches }{$user }{$data } ) {
441+ ¬ice(" No subscription found for '$data '" );
442+ return ;
443+ }
444+
445+ delete $id_map {__searches }{$user }{$data };
446+ ¬ice(" Removed subscription for '$data '" );
447+ }
448+
449+ sub cmd_list_search {
450+ my ( $data , $server , $win ) = @_ ;
451+
452+ my $found = 0;
453+ foreach my $suser ( sort keys %{ $id_map {__searches } } ) {
454+ my $topics ;
455+ foreach my $topic ( sort keys %{ $id_map {__searches }{$suser } } ) {
456+ $topics = $topics ? " $topics , $topic " : $topic ;
457+ }
458+ if ($topics ) {
459+ $found = 1;
460+ ¬ice(" Search subscriptions for \@ $suser : $topics " );
461+ }
462+ }
463+
464+ unless ($found ) {
465+ ¬ice(" No search subscriptions set up" );
466+ }
467+ }
468+
408469sub cmd_upgrade {
409470 my ( $data , $server , $win ) = @_ ;
410471
@@ -601,6 +662,12 @@ sub get_updates {
601662sub do_updates {
602663 my ( $fh , $username , $obj ) = @_ ;
603664
665+ my $rate_limit = $obj -> rate_limit_status();
666+ if ( $rate_limit and $rate_limit -> {remaining_hits } < 1 ) {
667+ ¬ice(" Rate limit exceeded for $username " );
668+ return 1;
669+ }
670+
604671 print scalar localtime , " - Polling for updates for $username " if &debug;
605672 my $tweets ;
606673 eval {
@@ -707,6 +774,47 @@ sub do_updates {
707774 printf $fh " id:%d account:%s nick:%s type:dm %s \n " ,
708775 $t -> {id }, $username , $t -> {sender_screen_name }, $text ;
709776 }
777+
778+ print scalar localtime , " - Polling for subscriptions" if &debug;
779+ if ( $obj -> can(' search' ) and $id_map {__searches }{$username } ) {
780+ my $search ;
781+ foreach my $topic ( sort keys %{ $id_map {__searches }{$username } } ) {
782+ eval {
783+ $search = $obj -> search(
784+ {
785+ q => $topic ,
786+ since_id => $id_map {__searches }{$username }{$topic }
787+ }
788+ );
789+ };
790+
791+ if ($@ ) {
792+ print $fh
793+ " type:debug Error during search($topic ) call. Aborted.\n " ;
794+ return 1;
795+ }
796+
797+ unless ( $search -> {max_id } ) {
798+ print $fh
799+ " type:debug Invalid search results when searching for $topic . Aborted.\n " ;
800+ return 1;
801+ }
802+
803+ $id_map {__searches }{$username }{$topic } = $search -> {max_id };
804+ printf $fh " id:%d account:%s type:searchid topic:%s \n " ,
805+ $search -> {max_id }, $username , $topic ;
806+
807+ foreach my $t ( reverse @{ $search -> {results } } ) {
808+ my $text = decode_entities( $t -> {text } );
809+ $text =~ s / (^|\W )\@ ([-\w ]+)/ $1 \cC 12\@ $2 \cO / g ;
810+ $text =~ s / (^|\W )\# ([-\w ]+)/ $1 \cC 5\# $2 \cO / g ;
811+ $text =~ s / [\n\r ]/ / g ;
812+ printf $fh " id:%d account:%s nick:%s type:search topic:%s %s \n " ,
813+ $t -> {id }, $username , $t -> {from_user }, $topic , $text ;
814+ }
815+ }
816+ }
817+
710818 print scalar localtime , " - Done" if &debug;
711819
712820 return 0;
@@ -727,7 +835,7 @@ sub monitor_child {
727835 last if / ^__friends__/ ;
728836 my $hilight = 0;
729837 my %meta ;
730- foreach my $key (qw/ id account nick type/ ) {
838+ foreach my $key (qw/ id account nick type topic / ) {
731839 if (s / ^$key:(\S +)\s *// ) {
732840 $meta {$key } = $1 ;
733841 }
@@ -759,24 +867,29 @@ sub monitor_child {
759867 $hilight = MSGLEVEL_HILIGHT;
760868 }
761869
762- if ( $meta {type } eq ' tweet' ) {
870+ if ( $meta {type } =~ / tweet|reply / ) {
763871 push @lines ,
764872 [
765873 ( MSGLEVEL_PUBLIC | $hilight ),
766874 $meta {type }, $account , $meta {nick }, $marker , $_
767875 ];
768- } elsif ( $meta {type } eq ' reply ' ) {
876+ } elsif ( $meta {type } eq ' search ' ) {
769877 push @lines ,
770878 [
771879 ( MSGLEVEL_PUBLIC | $hilight ),
772- $meta {type }, $account , $meta {nick }, $marker , $_
880+ $meta {type }, $account , $meta {topic },
881+ $meta {nick }, $marker , $_
773882 ];
774883 } elsif ( $meta {type } eq ' dm' ) {
775884 push @lines ,
776885 [
777886 ( MSGLEVEL_MSGS | $hilight ),
778887 $meta {type }, $account , $meta {nick }, $_
779888 ];
889+ } elsif ( $meta {type } eq ' searchid' ) {
890+ $id_map {__searches }{ $meta {account } }{ $meta {topic } } =
891+ $meta {id };
892+ print " Search '$meta {topic}' id set to $meta {id}" if &debug;
780893 } elsif ( $meta {type } eq ' error' ) {
781894 push @lines , [ MSGLEVEL_MSGS, $_ ];
782895 } elsif ( $meta {type } eq ' debug' ) {
@@ -800,9 +913,9 @@ sub monitor_child {
800913 print " new last_poll = $new_last_poll " if &debug;
801914 for my $line (@lines ) {
802915 $window -> printformat(
803- @ $line [0],
804- " twirssi_" . @ $line [1],
805- @$line [ 2, 3, 4, 5 ]
916+ $line -> [0],
917+ " twirssi_" . $line -> [1],
918+ @$line [ 2 .. $# $line ]
806919 );
807920 }
808921
@@ -947,17 +1060,25 @@ sub event_send_text {
9471060 }
9481061}
9491062
1063+ sub get_poll_time {
1064+ my $poll = Irssi::settings_get_int(" twitter_poll_interval" );
1065+ return $poll if $poll >= 60;
1066+ return 60;
1067+ }
1068+
9501069Irssi::signal_add( " send text" , " event_send_text" );
9511070
9521071Irssi::theme_register(
9531072 [
954- ' twirssi_tweet' , ' [$0%B@$1%n$2] $3' ,
955- ' twirssi_reply' , ' [$0\--> %B@$1%n$2] $3' ,
956- ' twirssi_dm' , ' [$0%B@$1%n (%WDM%n)] $2' ,
957- ' twirssi_error' , ' ERROR: $0' ,
1073+ ' twirssi_tweet' , ' [$0%B@$1%n$2] $3' ,
1074+ ' twirssi_search' , ' [$0%r$1%n:%B@$2%n$3] $4' ,
1075+ ' twirssi_reply' , ' [$0\--> %B@$1%n$2] $3' ,
1076+ ' twirssi_dm' , ' [$0%r@$1%n (%WDM%n)] $2' ,
1077+ ' twirssi_error' , ' ERROR: $0' ,
9581078 ]
9591079);
9601080
1081+ Irssi::settings_add_int( " twirssi" , " twitter_poll_interval" , 300 );
9611082Irssi::settings_add_str( " twirssi" , " twitter_window" , " twitter" );
9621083Irssi::settings_add_str( " twirssi" , " bitlbee_server" , " bitlbee" );
9631084Irssi::settings_add_str( " twirssi" , " short_url_provider" , " TinyURL" );
@@ -976,6 +1097,7 @@ sub event_send_text {
9761097Irssi::settings_add_bool( " twirssi" , " twirssi_use_reply_aliases" , 0 );
9771098Irssi::settings_add_bool( " twirssi" , " tweet_window_input" , 0 );
9781099
1100+ $last_poll = time - &get_poll_time;
9791101$window = Irssi::window_find_name( Irssi::settings_get_str(' twitter_window' ) );
9801102if ( !$window ) {
9811103 $window =
@@ -985,16 +1107,19 @@ sub event_send_text {
9851107}
9861108
9871109if ($window ) {
988- Irssi::command_bind( " dm" , " cmd_direct" );
989- Irssi::command_bind( " dm_as" , " cmd_direct_as" );
990- Irssi::command_bind( " tweet" , " cmd_tweet" );
991- Irssi::command_bind( " tweet_as" , " cmd_tweet_as" );
992- Irssi::command_bind( " twitter_reply" , " cmd_reply" );
993- Irssi::command_bind( " twitter_reply_as" , " cmd_reply_as" );
994- Irssi::command_bind( " twitter_login" , " cmd_login" );
995- Irssi::command_bind( " twitter_logout" , " cmd_logout" );
996- Irssi::command_bind( " twitter_switch" , " cmd_switch" );
997- Irssi::command_bind( " twirssi_upgrade" , " cmd_upgrade" );
1110+ Irssi::command_bind( " dm" , " cmd_direct" );
1111+ Irssi::command_bind( " dm_as" , " cmd_direct_as" );
1112+ Irssi::command_bind( " tweet" , " cmd_tweet" );
1113+ Irssi::command_bind( " tweet_as" , " cmd_tweet_as" );
1114+ Irssi::command_bind( " twitter_reply" , " cmd_reply" );
1115+ Irssi::command_bind( " twitter_reply_as" , " cmd_reply_as" );
1116+ Irssi::command_bind( " twitter_login" , " cmd_login" );
1117+ Irssi::command_bind( " twitter_logout" , " cmd_logout" );
1118+ Irssi::command_bind( " twitter_switch" , " cmd_switch" );
1119+ Irssi::command_bind( " twitter_subscribe" , " cmd_add_search" );
1120+ Irssi::command_bind( " twitter_unsubscribe" , " cmd_del_search" );
1121+ Irssi::command_bind( " twitter_list_subscriptions" , " cmd_list_search" );
1122+ Irssi::command_bind( " twirssi_upgrade" , " cmd_upgrade" );
9981123 if ( Irssi::settings_get_bool(" twirssi_use_reply_aliases" ) ) {
9991124 Irssi::command_bind( " reply" , " cmd_reply" );
10001125 Irssi::command_bind( " reply_as" , " cmd_reply_as" );
@@ -1006,7 +1131,7 @@ sub event_send_text {
10061131 map { " u: $_ ->{username}" } values %twits ;
10071132 print " friends: " , join " , " , sort keys %friends ;
10081133 print " nicks: " , join " , " , sort keys %nicks ;
1009- print " id_map : " , Dumper \%{ $id_map {__indexes } };
1134+ print " searches : " , Dumper \%{ $id_map {__searches } };
10101135 print " last poll: $last_poll " ;
10111136 }
10121137 );
0 commit comments