Created
February 22, 2010 09:15
-
-
Save erikh/310954 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# a commentary on twitter. problem? | |
# | |
# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLPLDQDDDDDDDDDDDDDDDDDDDDDDDDQQDLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMEH^xxxxxxx#///////////////////////////\xxxxx&@@@@@@39999LMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMMMQ&:/:^p9999999MMMMMMMMMzJ7JJJJJJJJJJJ9JJWW999E@@@@@@& xxxx///: dppJzPMMMMMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMJ&##&NPLMMMMMMMMMMDQJ7939EPDLPPLLLLLPPPPPPPz9999W7999997NNNNd3ppp^ \x\\ HELMMMMMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMML3#[&zMMMMMMMMMMLDN3NQJQPDLQ999NN99999997W97QPLPPPPLLLLLLPLPPDLLLLL999WJE3^\[x&NPLMMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMzx/\NMMMMMMMMMM93W7DMJ93WJ7JJLMMMMMMMMMMMMMMLJJJJJJJJJJJJJJJJE7JJJJJQMM97QMMLN&:/:^QMMMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMp[[^MMMMMMMMMzJ9QMQJE3ED9EEW99399999999p_HJMMMMMMMMMMMMMMMQJJJJ7JJJJ9ELMMMMMMMMMMJd#[^EMMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMM7[[HMMMMMMLEN9DLPN37QEN37DPLMMMMMMMMMMMMLJdEMMMMMMMMMMMMM399LLPLPLLLPPQNW7JLMMMMMMMMD&[#EMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMz\/^LMMMMMMD9LMP7HJD7HJDMMMMMMMMMMMMMMMMMMMP@MMMMMMMMMMMMMMQHDMMMMMMMMMMMMQ9dLMMMMMMMML\/pMMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMMMQ\/ LMMMMMMMMMMD3JMWHEMMMMMMML99EE999LMMMMMMM@MMMMMMMMMMMMMM@DMMMMMMMMMMMMMMMN7MMMMMMMMM:/&MMMMMMMMMMMM | |
# MMMMMMMMMMMMMMMM7#/ MMMMMMMMMMMMMMMMQMMDz3 \//[/////#[//\ H9MMMMMMMMMMMMMMMMM@MMMMMMMMMMMMMMMMLDMMMMMMMMM3/[EMMMMMMMMMMM | |
# MMMMMMMMMMMMMQH [:3LMMMMMMMMMMMMMMMMMQd\\:\/////////dDQ9p^:[\dzLMMMMMMMMMMMMMWMQ9d@ \::\\\\\pELMMMMMMMMMML@##dELMMMMMMMM | |
# MMMMMMMMMMMD@\###@NNNNNNPLLMMMEWNd9Dz:/:_@x[////////HpWQPMD9^##xPMMMMMMMLPLMLJ^://[[/# x//[&MzNQPDLLLLPDJ^\[x&DMMMMMM | |
# MMMMMMMMMPd#/^_HJ7JzzzJJzJLMMMQNJ9NDz^#//x @ppppppp& x//x&N9Dx/[WMMMMMMM^x @^[////////[ 3EMJJJJ7JJJJEHpMLW\[ QMMMMM | |
# MMMMMMMMp[[^E&7MMMzp [//[////^WzJDPMMMMMMMMMMLW\[pMMMML9@xx//#_WMMMMMMMMDN&x//:^39PMMMMMMMMMMMMMMMMMMMMMN99E3W9M /#zMMMM | |
# MMMMMMD&[#373DMMD&## 3JQDzEQd \##\^W9QQQQQE3 \[x9LMMMMMMMPP99DMMMMMMMMMMMMML//7LMMMMMMMMMMMMMMMP9d@@@@@@9zD37Lz3P\/pMMMM | |
# MMMMML^/xJM@MMMP:/xJMMMMM^:9MLQ99dx:#xxxxx## HELMMMMMMMMMMMMMMMMMMMMMMMMMMMM//7MMMMMMMMMd_JQPJ_x[\^@@@&##xzM@MLWW:/pMMMM | |
# MMMMM9//JMM@MMPx[:DMMMMME#[x3JMMMMMMJJJJJJJPMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM:/xp9LMMMMMM@[//x[/[^LL9MMMD7NLL^PMM@\/pMMMM | |
# MMMMM9[/MMM@MMQ//QMMMLEp:/x \/x pELMMMMMMMMMMMMMMMMMMME9PW_ zMMMMMMMMMMMMM7 x/#3JMMMMMML9999EMM /@MMMMMMMdQM@z:/pMMMM | |
# MMMMME[[7MM@MMQ//9L^:\#://WLDJ3 \#\ 3EQLMMMMMD7999999NWz\[x@ppWLMMMMMMMMMMMMMMLPW[[#:HLMMMMMMMMMMM / ELMMDEHELP^7#[NMMMM | |
# MMMMML /_LM7pML^/:zJ99EQ [:JMMMMQEH ##:x&3JQPPLMMMMMMMMM//7LM3 dpQMMMMMMMMML@[##/xHNPPPMMMMMME#[/[9MMDJQPQHH#[&LMMMM | |
# MMMMMMW/[dPM^PMD:/ MMMMMJ#/\9LMMMMMMP\/: [//x @@9zMMMMMM:/:^M [@pp_ 7MMMMMMMME /#7DpzMDJ933zMMMWx/:// MDNW77E9x/xLMMMMM | |
# MMMMMMMQ /#zDH77DEPMMMMMDd\/[/xd7QMMM\/@MML9W@&x\/// _ppJ9HWMMMMMMMMMMMM9[xp@x/\3LMMMMMMMMMMP93\/\[: /#zDLMMM7#/@LMMMMMM | |
# MMMMMMMML^[#3EJD7N7MMMMMMMzx//\x[#x@9 /[3DMMMMMLPDzpdx/[#\: @H99JQQDMMMML3 _WPMMMMMMPDQEH \#[[ z:/:[[pMMMLE#[_LMMMMMMM | |
# MMMMMMMMML9 [[xW3LMMMMMMMMMP [\37N&:#[[//:3QQDPMMMLMM /#99H@ ::#\xx: _pppppppp3 xx:[# 3EH/#D9[/[[pMMMM^/:PMMMMMMMM | |
# MMMMMMMMMMMM7x/\3LMMMMMMMMMMMp#/@LMMJ\///////[x@3zMMD#/pMMMMMMMDzJJ /:pp@ [/: ppp9[/3MMMQ//QL^///pMMMM//WMMMMMMMMM | |
# MMMMMMMMMMMMMME [#7MMMMMMMMMMME /#7MM9//DN&x////[//:x/#7DMMMMMMMMMM@/ MMMMMMM&[/MMMMMMMM&/[7MMd[/& ////pMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMML_[#EMMMMMMMMMMMLd\# 9_[#MMMPQJ3 ::\/[/[##\\ @799999 /x9999999H//99999N@@_[[_\:[////////pMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMLx/:PMMMMMMMMMMMMQd#/[ EMMMMMMMMQQQ /\x:#[/////////////////////////////////////////////pMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMD:/xPMMMMMMMMMMMMMD@[[x3LMMMMMMMMM@/ MMJ93 [///////////////////////////////////[/[:[#zMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMP /#3DMMMMMMMMMMMMMP7 [/ pDMMMML&[#pMMMMMMMMMz9#/x^x://[/////////////[//////:^//#N//&MMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMLE:/ 3DMMMMMMMMMMMMMLD3 ##xNzPp[/EMMMMMMMMMMMM:/pLPPQQQQQ&/[dpppp@[[^pN7\/xz@/#3x[xDMMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMQH [:3PMP9DLLMQ7DDLMMLJWx#\x[/^DLLMMMMMMMMMM\/pMMMMMMML#/&MMMML^/\DMQ /xzL :x /xzMMMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMM9 [\@EQ77W7MPz7Ep9PMMMQ7@ #/#x_@39PMMMMME#[pMMMMMMLQ//9MMML@/#7MM@//Wd@ \/xdDMMMMMMM//9MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMMP&///xdJLz3W7EPMP3W9ELMMMMM9d@ x[//[/x [[ pppppppx/#dppdx//# \///[#x_@pzMMMMMMMMMM\/ MMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMMP&[#7W_:#\_WzDD737QzzQ73NJzDMMMLPDQDQJpppp3 ^ppppp9QQQDPLMMLzMMMMMMMMM3/#DMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMMDx[\7MMLQ9dx#\ HEPzQQN39LzJz9939zDPLMMMMMMMMLPLLLLLLLLLLLLLLPPLMMMMMMMMMLJH9MMMMWMMMMD#/pMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMMp#/:DMMMMMMMLJp^#/x @WQMQJNW7W9LLJN9N39JMMMMLJJJJJJJJJJJJJJJJzJQMMMMMMME3WNLMMMMM@MMMMM\/pMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMM@///x@7QMMMMMMMML9p@ #//x@7QMMD99p9EJJ9HHWW79999999999WJJJJJJJJJJJJW9p9zMMMMMMJpWpMMMMM\/pMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMML //H_x\#^WQLMMMMMMMMLDQW_x\#x@9QLMMLPLPPD799399QQDDQQDJJJJQLLLLLLLLLMMMMMMQJNpJPMMMMMML\/pMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMMMMJ[[/JQJ7^#/: 3QQDDDDQDDQLMPzN&\#\ @9DLMMMMMMMMMMDQQQDDDDDQQN9999999999999997JDMMMMMMMML&[#EMMMMMMMM | |
# MMMMMMMMMMMMMMMMMMz9@ [//\////////////////_x/xNDMMMMJW_\/#x@9LMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMP /#7MMMMMMMMM | |
# MMMMMMMMMMMMMLE&://\x ///HEMMMMMMME [#^9MMMMWx//7LMMMMMMDN&x//#\/# @pEJPMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM9H#[^PMMMMMMMMMM | |
# MMMMMMMMMMLJ \#:&NQDL9/// PMMMMMMMMLEH:[:dzPMPW#[HLMMMMMMMMLQJpppp_ \x\\::^@99EDDMMMMMMMMMMMMMMMMMMDz9d\[:^ELMMMMMMMMMMM | |
# MMMMMMMMD3 #\dEDMMMMM9//#/ PMMMMMMMMMMD9 \\x7DLW/[7LMMMMMMMMMMMMMMMMQQEE9d&\:\#x\ pppppppppppp@ \:\x@9DMMMMMMMMMMMMMM | |
# MMMMMML3\/ 9DMMMMMMMM9//z#/xzMMMMMMMMMMMMLW\/#&D@[[HMMMMMMMMMMMMMMMMMMMMMMMMMLzJpp3 _ppJLMMMMMMMMMMMMMMMMMM | |
# | |
# This might have been written by me, but I assure you, there are plenty of | |
# people who would if they weren't as bored as I am. Either way, do whatever | |
# the hell you want with it. | |
# | |
use strict; | |
use warnings; | |
use Net::Twitter; | |
use List::MoreUtils qw(uniq); | |
use Data::Dumper; | |
use constant AUTH_CONFIG => 'twit_config'; | |
use constant LAST_SPAM_CONFIG => 'last_spam'; | |
use constant SENTINEL_CONFIG => 'sentinel'; | |
use constant SPAM_FREQUENCY => 21600; # 6 hours or greater for next spam | |
our @COOL_STORY = ( | |
'cool story bro', | |
'Wow. Cool story, bro.', | |
'Damn! Cool story bro!', | |
); | |
sub write_config { | |
my ($filename, $config) = @_; | |
my $fh; | |
open($fh, '>', $filename) || die; | |
print { $fh } join("\n", map { "$_ $config->{$_}" } keys %$config); | |
close($fh); | |
} | |
sub read_config { | |
my $filename = shift; | |
return () unless -f $filename; | |
my $fh; | |
my %config = (open($fh, $filename) && do { local $/ = undef; map { split(/\s/) } split(/\n/, <$fh>) }); | |
close($fh); | |
return %config; | |
} | |
my $sentinel = int(open(SENTINEL, SENTINEL_CONFIG) && do { <SENTINEL> }); | |
close(SENTINEL); | |
my %config = read_config(AUTH_CONFIG); | |
my %last_spam = read_config(LAST_SPAM_CONFIG); | |
my $twit = new Net::Twitter(traits => [qw/API::REST/], %config); | |
my %suckers; | |
my @followers = map { $_->{id} } @{$twit->followers}; | |
my @following = map { $_->{id} } @{$twit->following}; | |
my %followers = map { $_ => 1 } @followers; | |
my %following = map { $_ => 1 } @following; | |
my @suckers = grep { exists($followers{$_}) xor exists($following{$_}) } (@following, @followers); | |
# be a good neighbor and allow people to opt-in and opt-out by following or de-following this user. | |
for my $sucker (@suckers) { | |
if (exists($followers{$sucker})) { | |
$twit->create_friend($sucker); | |
$last_spam{$sucker} = 0; | |
} elsif (exists($following{$sucker})) { | |
$twit->destroy_friend($sucker); | |
delete($last_spam{$sucker}); | |
} else { | |
# ??? mmm... dangling else. | |
} | |
} | |
my %victims; | |
eval { | |
my $feed = $twit->friends_timeline($sentinel ? { since_id => $sentinel, count => 1000 } : { }); | |
foreach my $item (@$feed) { | |
# let's not spam ourselves! | |
next if ($item->{user}{screen_name} eq $config{username}); | |
print Dumper $item; | |
$victims{$item->{id}} = $item->{user}{screen_name}; | |
$sentinel = $item->{id} if ($item->{id} > $sentinel); | |
} | |
}; | |
if ($@) { die $@ } | |
open(SENTINEL, '>', SENTINEL_CONFIG) && do { print SENTINEL $sentinel; close(SENTINEL) }; | |
print Dumper \%last_spam; | |
# let's at least make an effort to not become the spam-spewing vile that we're | |
# mocking. | |
my @victim_names = grep { exists($last_spam{$_}) ? time - int($last_spam{$_}) - SPAM_FREQUENCY > 0 : 1 } uniq(values %victims); | |
my @victim_posts; | |
foreach my $id (keys %victims) { | |
push @victim_posts, $id if(scalar grep $victims{$id} eq $_, @victim_names); | |
} | |
my $winnar = $victim_posts[int(rand(@victim_posts))]; | |
exit 0 unless $winnar; | |
print "$winnar - $victims{$winnar}\n"; | |
$last_spam{$victims{$winnar}} = time; | |
write_config(LAST_SPAM_CONFIG, \%last_spam); | |
$twit->update({ status => "\@$victims{$winnar} ".$COOL_STORY[int(rand(scalar @COOL_STORY))], in_reply_to_status_id => $winnar }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment