#!/usr/bin/perl # this script copyright Adam Bernard 2009 # http://twitter.com/pseudomonas # http://pseudomonas.livejournal.com # released under creative-commons license (attribution, non-commercial, share-alike) # http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ use warnings; use strict; use PerlSpeak; use LJ::Simple; use Data::Dumper; use XML::RSS::Feed; use WWW::Mechanize; use Net::Twitter; my $ps = PerlSpeak->new(tts_engine=>"festival_pipe", voice=>"voice_nitech_us_awb_arctic_hts"); # Much much much better voice than the defaults. Comes in a pack of voices many of which aren't bad. # Googling the voice name should find you the package. $ps->say("Starting"); # "Linux: can't open /dev/dsp" errors? I used the solution at http://ubuntuforums.org/showpost.php?p=4058268&postcount=16 #### NB: I *know* that rot13 is not encryption. This is just very slight obfuscation against shoulder-surfing. my $ljuser= "pseudomonas"; my $ljpass = "ROT-13-ed-password"; # This will only work with paid/permanent LJ accounts: http://community.livejournal.com/howto/40882.html my $twitteruser = "pseudomonas"; my $twitterpass = "ROT-13-ed-password"; my %entries; my %dict = qw/ languagelog language-log feanelwa fee-a-nell-wa livredor lee-fruh-door phdcomic P-H-D-comic palmer1984 palmer--nineteen-eighty-four doseybat dozy-bat gerald_duck gerald-duck beingjdc being-j-d-c sphyg sfig beckyc becky-c rysmiel rise-me-ell wychwood which-wood andrewducker andrew-ducker uitlander oit-lander nja n-j-a 1ngi ing-ghee ingaborg in-ga-borg fivemack five-mack taimatsu tie-matsu /; # login to twitter $twitterpass =~ y/A-Za-z/N-ZA-Mn-za-m/; my $twit = Net::Twitter->new({username=>$twitteruser, password=>$twitterpass}); my $ft = $twit->friends_timeline(); my $latest_time = $ft->[0]->{id}; $ljpass =~ y/A-Za-z/N-ZA-Mn-za-m/; # login to LJ (one) my $agent = WWW::Mechanize->new(); $agent->get('http://www.livejournal.com/login.bml'); $agent->form_with_fields('user', 'password'); $agent->field('user',$ljuser); $agent->field('password',$ljpass); $agent->field('remember_me',1); $agent->submit(); # login to LJ (two) my $lj = new LJ::Simple ( { user => $ljuser, pass => $ljpass, } ); # setup the feed handler my $feed = XML::RSS::Feed->new( url => "http://pseudomonas.livejournal.com/data/customview?styleid=670763&checkcookies=1", name => "pmonas", delay => 10, debug => 0, tmpdir => "/tmp", # optional caching ); # initialize so that old entries are marked as seen $agent->get('http://pseudomonas.livejournal.com/data/customview?styleid=670763&checkcookies=1'); $feed->parse($agent->content()); while(1) { my ($new_friends,$next_update)=$lj->CheckFriends("Default View"); (defined $new_friends) || die "$0: Failed to check friends - $LJ::Simple::error\n"; if ($new_friends) { $agent->get('http://pseudomonas.livejournal.com/data/customview?styleid=670763&checkcookies=1'); #print "New friends!\n"; $feed->parse($agent->content()); for (reverse $feed->late_breaking_news){ my $headline = $_->headline; $headline =~ m#^(.*?) - (.*)$#; my $writer = $dict{$1} || $1; my $content = $2; #$content =~ s/\s+/ ... /g; $ps->say("New ell jay entry by user $writer. ..."); $ps->say("... $content"); sleep 1; } } my $ft = $twit->friends_timeline({since_id=>$latest_time}); if (scalar @$ft){ for (reverse @$ft){ my $content = $_->{text}; my $writer = $_->{user}->{name} || $_->{user}->{screen_name}; $ps->say("New twitter tweet by user $writer. ..."); $ps->say("... $content"); sleep 1; } $latest_time = $ft->[0]->{id}; } print "Sleeping for $next_update seconds...\n"; sleep($next_update+2); }