From 3eae415f60bd3fa890207771ce781a2db84025a8 Mon Sep 17 00:00:00 2001 From: pdbogen Date: Tue, 21 Apr 2009 15:04:58 +0000 Subject: [PATCH] Destult can now act as a twitter client. git-svn-id: https://www.cernu.us/~pdbogen/svn/destult2@92 088b83a4-0077-4247-935c-42ec02c2848b --- commands.yaml | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 175 insertions(+), 19 deletions(-) diff --git a/commands.yaml b/commands.yaml index 97e3aa0..d158ef4 100644 --- a/commands.yaml +++ b/commands.yaml @@ -52,21 +52,29 @@ CLASSIFY: |- sub { my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; my( $cmd, $level ) = split( / /, $what, 2 ); - unless( $level =~ /^[0-9]$/ ) { + unless( !($level) || $level =~ /^[0-9]$/ ) { $kernel->post( $src, $replypath, "Access level should be a non-negative integer.", $dest ); return; } - if( exists( $heap->{ 'commands' }->{ uc( $cmd ) } ) ) { - $heap->{ 'cmdaccess' }->{ uc( $cmd ) } = $level; + if( defined $level ) { + if( exists( $heap->{ 'commands' }->{ uc( $cmd ) } ) ) { + $heap->{ 'cmdaccess' }->{ uc( $cmd ) } = $level; DumpFile( "cmdaccess.yaml", $heap->{ 'cmdaccess' } ); $kernel->post( $src, $replypath, "Set.", $dest ); - } elsif( exists( $heap->{ 'db' }->{ uc( $cmd ) } ) ) { - $heap->{ 'factoidAccess' } = {} unless exists $heap->{ 'factoidAccess' }; - $heap->{ 'factoidAccess' }->{ uc( $cmd ) } = $level; - DumpFile( 'factoidAccess.yaml', $heap->{ 'factoidAccess' } ); - $kernel->post( $src, $replypath, "Set.", $dest ); + } elsif( exists( $heap->{ 'db' }->{ uc( $cmd ) } ) ) { + $heap->{ 'factoidAccess' } = {} unless exists $heap->{ 'factoidAccess' }; + $heap->{ 'factoidAccess' }->{ uc( $cmd ) } = $level; + DumpFile( 'factoidAccess.yaml', $heap->{ 'factoidAccess' } ); + $kernel->post( $src, $replypath, "Set.", $dest ); + } else { + $kernel->post( $src, $replypath, "'$cmd' not found.", $dest ); + } } else { - $kernel->post( $src, $replypath, "'$cmd' not found.", $dest ); + if( exists( $heap->{ 'cmdaccess' }->{ uc( $cmd ) } ) ) { + $kernel->post( $src, $replypath, uc( $cmd )." is level ".$heap->{ 'cmdaccess' }->{ uc( $cmd ) }, $dest ); + } else { + $kernel->post( $src, $replypath, uc( $cmd )." is not classified.", $dest ); + } } } @@ -81,6 +89,7 @@ DECLASSIFY: |- for my $list (keys %lists) { if( exists( $heap->{ $list } ) && exists( $heap->{ $list }->{ uc( $what ) } ) ) { delete( $heap->{ $list }->{ uc( $what ) } ); + DumpFile( $list.'.yaml', $heap->{ $list } ); $kernel->post( $src, $replypath, "'$what' removed from ".$lists{ $list }." access list.", $dest ); $found = 1; } @@ -309,15 +318,21 @@ SETPASSWORD: |- CONFIG: |- sub { my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; - my( $subj, $predicate ) = split( / /, $what, 2 ); - if( $predicate ) { - $Destult::config{ uc( $subj ) } = $predicate; - DumpFile( "config.yaml", \%Destult::config ); - $kernel->post( $src, $replypath, "Okay, $who.", $dest ); - } elsif( exists( $Destult::config{ uc( $subj ) } ) ) { - $kernel->post( $src, $replypath, "$subj is '".$Destult::config{ uc( $subj ) }."'.", $dest ); + if( $what ) { + my( $subj, $predicate ) = split( / /, $what, 2 ); + if( $predicate ) { + $Destult::config{ uc( $subj ) } = $predicate; + DumpFile( "config.yaml", \%Destult::config ); + $kernel->post( $src, $replypath, "Okay, $who.", $dest ); + } elsif( exists( $Destult::config{ uc( $subj ) } ) ) { + $kernel->post( $src, $replypath, "$subj is '".$Destult::config{ uc( $subj ) }."'.", $dest ); + } else { + $kernel->post( $src, $replypath, "$subj is not found.", $dest ); + } } else { - $kernel->post( $src, $replypath, "$subj is not found.", $dest ); + for my $key ( keys %Destult::config ) { + $kernel->post( $src, $replypath, "$key: ".$Destult::config{ $key }, $dest ); + } } } @@ -439,8 +454,8 @@ DICTCLEAN: |- DICT: |- sub { - require WWW::Search; - require WWW::Search::UrbanDictionary; + use WWW::Search; + use WWW::Search::UrbanDictionary; my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; if( $what =~ /^$/ ) { @@ -1879,3 +1894,144 @@ TITLE: |- } } } + +TWITTERCLEAR: |- + sub { + my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; + unlink( 'twitterUsers.yaml' ); + delete( $heap->{ 'twitterUsers' } ); + $kernel->post( $src, $replypath, "Twitter user database cleared.", $dest ); + } + +TWITTER: |- + sub { + my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; + + use Net::OAuth; + use Digest::MD5 qw( md5_hex ); + use HTTP::Request::Common; + use LWP::UserAgent; + + my $userAgent = LWP::UserAgent->new(); + my $nonce = md5_hex( time.rand ); + + if( !exists( $heap->{ 'twitterUsers' } ) ) { + if( -e 'twitterUsers.yaml' ) { + $heap->{ 'twitterUsers' } = LoadFile( 'twitterUsers.yaml' ); + } else { + $heap->{ 'twitterUsers' } = {}; + } + } + + my $len = length $what; + if( $len > 140 ) { + $kernel->post( $src, $replypath, "Your tweet exceed the 140-character limit by ".($len - 140)." character".($len>141?"s":""), $dest ); + return; + } + + if( exists( $heap->{ 'twitterUsers' }->{ uc( $who ) } ) ) { + if( $heap->{ 'twitterUsers' }->{ uc( $who ) }->{ "state" } == 0 ) { + my $oaRequest = Net::OAuth->request( "access token" )->new( + consumer_key => $Destult::config{ "TWITTER_C_K" }, + consumer_secret => $Destult::config{ "TWITTER_C_S" }, + request_url => 'http://twitter.com/oauth/access_token', + request_method => 'POST', + signature_method => 'HMAC-SHA1', + timestamp => time, + nonce => $nonce, + token => $heap->{ 'twitterUsers' }->{ uc( $who ) }->{ "request_token" }, + token_secret => $heap->{ 'twitterUsers' }->{ uc( $who ) }->{ "request_secret" }, + ); + $oaRequest->sign(); + my $response = $userAgent->request( POST $oaRequest->to_url() ); + if( !$response->is_success() ) { + print( "TWITTER: Error: ".$response->status_line(), "\n" ); + $kernel->post( $src, $replypath, "Either you denied Destult access, or some other error occured. Please try again.", $dest ); + delete $heap->{ 'twitterUsers' }->{ uc( $who ) }; + DumpFile( "twitterUsers.yaml", $heap->{ 'twitterUsers' } ); + return; + } + my $oaResponse = Net::OAuth->response( 'access token' )->from_post_body( $response->content ); + $heap->{ 'twitterUsers' }->{ uc( $who ) } = { + state => 1, + token => $oaResponse->token, + secret => $oaResponse->token_secret, + }; + $kernel->post( $src, $replypath, "Congratulations! Destult now has a token to access your Twitter account. You shouldn't need to do this again.", $dest ); + DumpFile( "twitterUsers.yaml", $heap->{ 'twitterUsers' } ); + } + my $oaRequest = Net::OAuth->request( "protected resource" )->new( + consumer_key => $Destult::config{ "TWITTER_C_K" }, + consumer_secret => $Destult::config{ "TWITTER_C_S" }, + request_url => 'http://twitter.com/statuses/update.json', + request_method => 'POST', + signature_method => 'HMAC-SHA1', + timestamp => time, + nonce => $nonce, + token => $heap->{ 'twitterUsers' }->{ uc( $who ) }->{ "token" }, + token_secret => $heap->{ 'twitterUsers' }->{ uc( $who ) }->{ "secret" }, + extra_params => { + status => $what + } + ); + $oaRequest->sign(); + my $response = $userAgent->request( POST $oaRequest->to_url() ); + if( !$response->is_success() ) { + print( "TWITTER: Error: ".$response->status_line(), "\n" ); + if( $response->code == "401" ) { + $kernel->post( $src, $replypath, "401 from Twitter: This generally means Destult ". + "has been de-authorized to update your Twitter ". + "status. You might consider using ~DETWITTER and ". + "then re-authorizing through ~TWITTER.", $dest ); + } else { + $kernel->post( $src, $replypath, "I ran into an error updating your Twitter status: ".$response->status_line, $dest ); + } + return; + } + $kernel->post( $src, $replypath, "Tweet.", $dest ); + } else { + my $oaRequest = Net::OAuth->request( "request token" )->new( + consumer_key => $Destult::config{ "TWITTER_C_K" }, + consumer_secret => $Destult::config{ "TWITTER_C_S" }, + request_url => 'http://twitter.com/oauth/request_token', + request_method => 'POST', + signature_method => 'HMAC-SHA1', + timestamp => time, + nonce => $nonce + ); + + $oaRequest->sign(); + + $kernel->post( $src, $replypath, "One moment, I am retrieving a request token..", $dest ); + my $response = $userAgent->request( POST $oaRequest->to_url() ); + + if( !($response->is_success()) ) { + $kernel->post( $src, $replypath, "An error occured while retrieving the request token from Twitter: ".$response->status_line() ); + return; + } + + my $oaResponse = Net::OAuth->response( 'request token' )->from_post_body( $response->content ); + $kernel->post( $src, $replypath, "You must grant Destult write access to your Twitter account. ". + "To do so, please visit: ". + "http://twitter.com/oauth/authorize?oauth_token=".($oaResponse->token)." ". + "and then re-run this command.", $dest ); + $heap->{ 'twitterUsers' }->{ uc( $who ) } = { + request_token => $oaResponse->token, + request_secret => $oaResponse->token_secret, + state => 0 + }; + DumpFile( "twitterUsers.yaml", $heap->{ 'twitterUsers' } ); + } + } + +DETWITTER: |- + sub { + my( $kernel, $heap, $who, $what, $src, $dest, $replypath ) = @_; + if( exists( $heap->{ 'twitterUsers' }->{ uc( $who ) } ) ) { + delete $heap->{ 'twitterUsers' }->{ uc( $who ) }; + DumpFile( "twitterUsers.yaml", $heap->{ 'twitterUsers' } ); + $kernel->post( $src, $replypath, "I've discarded my access token for your account.", $dest ); + } else { + $kernel->post( $src, $replypath, "I have no access token for your account.", $dest ); + } + } -- 2.11.0