From 46759339710e7a89b5b2b337ed10e3c02bba8960 Mon Sep 17 00:00:00 2001 From: Christian Garbs Date: Fri, 17 Sep 2010 21:46:21 +0200 Subject: [PATCH 1/3] add basic twitter_search it's neither finished nor polished, but it works --- twirssi.pl | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/twirssi.pl b/twirssi.pl index 5095cfd..c9a5a22 100644 --- a/twirssi.pl +++ b/twirssi.pl @@ -431,6 +431,17 @@ sub gen_cmd { } } +sub cmd_search { + my ( $data, $server, $win ) = @_; + + $data =~ s/^\s+|\s+$//g; + if ( length $data > 0 ) { + &get_search ( $data, Irssi::settings_get_int('twitter_timeout') ); + } else { + ¬ice("Search query is empty"); + } +} + sub cmd_switch { my ( $data, $server, $win ) = @_; @@ -1004,6 +1015,98 @@ sub load_friends { return ( $added, $removed ); } +sub get_search { + my ( $topic, $max_results ) = @_; + + print scalar localtime, " - get_search starting" if &debug; + + $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" ); + } + + return unless &logged_in($twit); + + my ( $fh, $filename ) = File::Temp::tempfile(); + binmode( $fh, ":" . &get_charset ); + $child_pid = fork(); + + if ($child_pid) { # parent + Irssi::timeout_add_once( 5000, 'monitor_child', + [ "$filename.done", 0 ] ); + Irssi::pidwait_add($child_pid); + } elsif ( defined $child_pid ) { # child + close STDIN; + close STDOUT; + close STDERR; + + my $error = 0; + my %context_cache; + + + if ( $twit->can('search') ) { + my $username = $user; + my $search; + print $fh "type:debug searching for $topic (max $max_results)\n"; + eval { + $search = $twit->search( + { + 'q' => $topic + } + ); + }; + + if ($@) { + print $fh + "type:debug Error during search($topic) call. Aborted.\n"; + return undef; + } + + unless ( $search->{max_id} ) { + print $fh "type:debug Invalid search results when searching", + " for $topic. Aborted.\n"; + return undef; + } + + $id_map{__searches}{$username}{$topic} = $search->{max_id}; + $topic =~ s/ /%20/g; + printf $fh "id:%s account:%s type:searchid topic:%s\n", + $search->{max_id}, $username, $topic; + + my $count = 0; + foreach my $t ( reverse @{ $search->{results} } ) { + last if $max_results > 0 && ++$count > $max_results; + + my $text = &get_text( $t, $twit ); + printf $fh "id:%s account:%s nick:%s type:search topic:%s %s\n", + $t->{id}, $username, $t->{from_user}, $topic, $text; + } + } + + print $fh "__friends__\n"; + foreach ( sort keys %friends ) { + print $fh "$_ $friends{$_}\n"; + } + + if ($error) { + print $fh "type:debug Search encountered errors. Aborted\n"; + print $fh "-- $last_poll"; + } else { + print $fh "-- $last_poll"; # don't update last poll :) + } + close $fh; + rename $filename, "$filename.done"; + exit; + } else { + &ccrap("Failed to fork for searching: $!"); + } + print scalar localtime, " - get_search ends" if &debug; +} + sub get_updates { print scalar localtime, " - get_updates starting" if &debug; @@ -1918,8 +2021,9 @@ sub get_text { Irssi::settings_add_str( "twirssi", "twirssi_oauth_store", Irssi::get_irssi_dir . "/scripts/twirssi.oauth" ); -Irssi::settings_add_int( "twirssi", "twitter_friends_poll", 600 ); -Irssi::settings_add_int( "twirssi", "twitter_timeout", 30 ); +Irssi::settings_add_int( "twirssi", "twitter_friends_poll", 600 ); +Irssi::settings_add_int( "twirssi", "twitter_timeout", 30 ); +Irssi::settings_add_int( "twirssi", "twitter_search_results", 5 ); Irssi::settings_add_bool( "twirssi", "twirssi_upgrade_beta", 0 ); Irssi::settings_add_bool( "twirssi", "tweet_to_away", 0 ); @@ -1961,6 +2065,7 @@ sub get_text { 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_search", "cmd_search" ); Irssi::command_bind( "twitter_switch", "cmd_switch" ); Irssi::command_bind( "twitter_subscribe", "cmd_add_search" ); Irssi::command_bind( "twitter_unsubscribe", "cmd_del_search" ); From 121af89cd146571e2ae8def600607d9a4dd23946 Mon Sep 17 00:00:00 2001 From: Christian Garbs Date: Fri, 17 Sep 2010 23:16:23 +0200 Subject: [PATCH 2/3] integrate twitter_search into existing background poll also add a theme variable --- twirssi.pl | 162 +++++++++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 98 deletions(-) diff --git a/twirssi.pl b/twirssi.pl index c9a5a22..31a1770 100644 --- a/twirssi.pl +++ b/twirssi.pl @@ -42,6 +42,7 @@ my $first_call = 1; my $child_pid; my %fix_replies_index; +my %search_once; my %irssi_to_mirc_colors = ( '%k' => '01', @@ -436,7 +437,12 @@ sub cmd_search { $data =~ s/^\s+|\s+$//g; if ( length $data > 0 ) { - &get_search ( $data, Irssi::settings_get_int('twitter_timeout') ); + my $username = &normalize_username( $user ); + if (exists $search_once{$username}->{$data}) { + ¬ice("Search is already queued"); + } + $search_once{$username}->{$data} = Irssi::settings_get_int( "twitter_search_results" ); + &get_updates; } else { ¬ice("Search query is empty"); } @@ -1015,98 +1021,6 @@ sub load_friends { return ( $added, $removed ); } -sub get_search { - my ( $topic, $max_results ) = @_; - - print scalar localtime, " - get_search starting" if &debug; - - $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" ); - } - - return unless &logged_in($twit); - - my ( $fh, $filename ) = File::Temp::tempfile(); - binmode( $fh, ":" . &get_charset ); - $child_pid = fork(); - - if ($child_pid) { # parent - Irssi::timeout_add_once( 5000, 'monitor_child', - [ "$filename.done", 0 ] ); - Irssi::pidwait_add($child_pid); - } elsif ( defined $child_pid ) { # child - close STDIN; - close STDOUT; - close STDERR; - - my $error = 0; - my %context_cache; - - - if ( $twit->can('search') ) { - my $username = $user; - my $search; - print $fh "type:debug searching for $topic (max $max_results)\n"; - eval { - $search = $twit->search( - { - 'q' => $topic - } - ); - }; - - if ($@) { - print $fh - "type:debug Error during search($topic) call. Aborted.\n"; - return undef; - } - - unless ( $search->{max_id} ) { - print $fh "type:debug Invalid search results when searching", - " for $topic. Aborted.\n"; - return undef; - } - - $id_map{__searches}{$username}{$topic} = $search->{max_id}; - $topic =~ s/ /%20/g; - printf $fh "id:%s account:%s type:searchid topic:%s\n", - $search->{max_id}, $username, $topic; - - my $count = 0; - foreach my $t ( reverse @{ $search->{results} } ) { - last if $max_results > 0 && ++$count > $max_results; - - my $text = &get_text( $t, $twit ); - printf $fh "id:%s account:%s nick:%s type:search topic:%s %s\n", - $t->{id}, $username, $t->{from_user}, $topic, $text; - } - } - - print $fh "__friends__\n"; - foreach ( sort keys %friends ) { - print $fh "$_ $friends{$_}\n"; - } - - if ($error) { - print $fh "type:debug Search encountered errors. Aborted\n"; - print $fh "-- $last_poll"; - } else { - print $fh "-- $last_poll"; # don't update last poll :) - } - close $fh; - rename $filename, "$filename.done"; - exit; - } else { - &ccrap("Failed to fork for searching: $!"); - } - print scalar localtime, " - get_search ends" if &debug; -} - sub get_updates { print scalar localtime, " - get_updates starting" if &debug; @@ -1405,6 +1319,48 @@ sub do_updates { } } + print scalar localtime, " - Polling for one-time searches" if &debug; + if ( $obj->can('search') and exists $search_once{$username} ) { + my $search; + foreach my $topic ( sort keys %{ $search_once{$username} } ) { + my $max_results = $search_once{$username}->{$topic}; + + print $fh "type:debug searching once for $topic (max $max_results)\n"; + eval { + $search = $obj->search( + { + 'q' => $topic + } + ); + }; + + if ($@) { + print $fh + "type:debug Error during search_once($topic) call. Aborted.\n"; + return undef; + } + + unless ( $search->{max_id} ) { + print $fh "type:debug Invalid search results when searching once", + " for $topic. Aborted.\n"; + return undef; + } + $topic =~ s/ /%20/g; + + # TODO: consider applying ignore-settings to search results + my @results = @{ $search->{results} }; + if ($max_results > 0) { + splice @results, $max_results; + } + foreach my $t ( reverse @results ) { + + my $text = &get_text( $t, $obj ); + printf $fh "id:%s account:%s nick:%s type:search_once topic:%s %s\n", + $t->{id}, $username, $t->{from_user}, $topic, $text; + } + } + } + print scalar localtime, " - Done" if &debug; return 1; @@ -1586,6 +1542,15 @@ sub monitor_child { $id_map{__searches}{ $meta{account} }{ $meta{topic} } = $meta{id}; } + } elsif ( $meta{type} eq 'search_once' ) { + push @lines, + [ + ( MSGLEVEL_PUBLIC | $hilight ), + $meta{type}, $account, $meta{topic}, + $meta{nick}, $marker, $_ + ]; + my $username = &normalize_username ( $meta{account} ); + delete $search_once{$username}->{$meta{topic}}; } elsif ( $meta{type} eq 'dm' ) { push @lines, [ @@ -1989,11 +1954,12 @@ sub get_text { Irssi::theme_register( [ - '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', + 'twirssi_tweet', '[$0%B@$1%n$2] $3', + 'twirssi_search', '[$0%r$1%n:%B@$2%n$3] $4', + 'twirssi_search_once', '[$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', ] ); From 90b255c049d8a4a699cfa6bc03b82d3437d9e794 Mon Sep 17 00:00:00 2001 From: Christian Garbs Date: Fri, 17 Sep 2010 23:22:06 +0200 Subject: [PATCH 3/3] prevent parallel get_update runs --- twirssi.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/twirssi.pl b/twirssi.pl index 31a1770..cb048af 100644 --- a/twirssi.pl +++ b/twirssi.pl @@ -43,6 +43,7 @@ my $child_pid; my %fix_replies_index; my %search_once; +my $update_is_running = 0; my %irssi_to_mirc_colors = ( '%k' => '01', @@ -1035,6 +1036,13 @@ sub get_updates { return unless &logged_in($twit); + if ($update_is_running) { + print scalar localtime, " - get_updates aborted: already running" if &debug; + return; + } else { + $update_is_running = 1; + } + my ( $fh, $filename ) = File::Temp::tempfile(); binmode( $fh, ":" . &get_charset ); $child_pid = fork(); @@ -1665,6 +1673,7 @@ sub monitor_child { } $failwhale = 0; $first_call = 0; + $update_is_running = 0; return; } } @@ -1680,6 +1689,8 @@ sub monitor_child { waitpid( -1, WNOHANG ); unlink $filename unless &debug; + $update_is_running = 0; + return unless Irssi::settings_get_bool("twirssi_notify_timeouts"); my $since;