Created
February 11, 2012 04:05
-
-
Save perigrin/1796064 to your computer and use it in GitHub Desktop.
Updating data files for my Twitter interactions
This file contains 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 | |
use strict; | |
use warnings FATAL => qw( all ); | |
use Net::Twitter::Lite; | |
use Lingua::EN::Inflect qw(NO NUMWORDS); | |
use HTML::Entities qw(encode_entities_numeric); | |
use lib '../files/perl/lib'; | |
use Base::Roots qw(get_data data_directory); | |
use Base::Data qw(get_hash); | |
use Base::Convert qw(hashtagify); | |
use Twitter qw(twitter_accounts); | |
local $\ = "\n"; | |
my @accounts = twitter_accounts(); | |
die "First account is not Lady Aleena" if $accounts[0] ne 'Lady_Aleena'; | |
my @accounts_totals; | |
my %is_account; | |
$is_account{$_}++ for @accounts; | |
my $nt = Net::Twitter::Lite->new( | |
consumer_key => Twitter::consumer_key, | |
consumer_secret => Twitter::consumer_key_secret, | |
); | |
# Get Lady_Aleena's followers for greetings which will be added later. | |
my %LA_followers; | |
print "Are you tweeting this time? "; | |
my $tweeting = <>; | |
chomp($tweeting); | |
print "How many seconds between tweets? "; | |
my $sleep = <>; | |
chomp($sleep); | |
for my $account (@accounts) { | |
print $account; | |
$nt->{access_token} = Twitter::access_key($account); | |
$nt->{access_token_secret} = Twitter::access_key_secret($account); | |
my $short_account = $account; | |
$short_account =~ s/LadyAleena_//g; | |
my $directory = "Twitter/users/$account"; | |
my $full_path = data_directory($directory); | |
mkdir($full_path) or die unless (-d $full_path); | |
my %files; | |
for (qw(followers twitter_friends not_following not_followers friend_tweets lists list_memberships mentions retweets)) { | |
$files{$_} = get_data($directory,"$_.txt"); | |
} | |
# Start account totals | |
my $account_totals = $nt->account_totals; | |
push @accounts_totals, "$account|".join("|",map($account_totals->{$_},qw(followers friends updates)));; | |
# End account totals | |
# Start followers and friends | |
my %people; | |
for my $people_type (qw(followers friends)) { | |
for ( my $cursor = -1; $cursor; ) { | |
my $type = $nt->$people_type({ cursor => $cursor, }); | |
push @{$people{$_->{screen_name}}}, "$people_type" for @{$type->{users}}; | |
if ($people_type eq 'followers') { | |
if ($account eq 'Lady_Aleena') { | |
$LA_followers{$_->{screen_name}}++ for @{$type->{users}}; | |
} | |
else { | |
my %followers; | |
if (-f $files{$people_type}) { | |
%followers = get_hash( | |
file => $files{$people_type}, | |
headings => [qw(id screen_name greet)], | |
); | |
} | |
for my $follower (@{$type->{users}}) { | |
my $id = $follower->{id}; | |
if (!exists($followers{$id})) { | |
$followers{$id}{greet} = 0; | |
} | |
$followers{$id}{id} = $id; | |
$followers{$id}{screen_name} = $follower->{screen_name}; | |
} | |
print "\t$account follower greetings"; | |
my @follower_lines; | |
for my $follower (sort {lc $followers{$a}{screen_name} cmp lc $followers{$b}{screen_name}} keys %followers) { | |
my $screen_name = $followers{$follower}{screen_name}; | |
my $id = $followers{$follower}{id}; | |
if ($followers{$follower}{greet} == 0) { | |
my $line = "\@$screen_name: Thank you for following my $short_account account. "; | |
if (!exists($LA_followers{$screen_name})) { | |
$line .= "\@Lady_Aleena is my main account."; | |
} | |
else { | |
$line .= "I hope you don't get bored. :)"; | |
} | |
print "\t\t$line"; | |
$nt->update({ status => $line }) if $tweeting =~ /^y/i; | |
sleep($sleep); | |
} | |
$followers{$follower}{greet} = 1; | |
my $greet = $followers{$follower}{greet}; | |
push @follower_lines, "$id|$screen_name|$greet"; | |
} | |
open(my $to_file,'>',$files{$people_type}) or die "Can't open $files{$people_type} $!"; | |
print $to_file join("\n",@follower_lines); | |
} | |
} | |
$cursor = $type->{next_cursor}; | |
} | |
} | |
my %groups; | |
for my $person (sort {lc $a cmp lc $b} keys %people) { | |
my @statuses = @{$people{$person}}; | |
if (@statuses == 2) { | |
push @{$groups{twitter_friends}}, $person; | |
next; | |
} | |
push @{$groups{not_following}}, $person if $statuses[0] eq "followers"; | |
push @{$groups{not_followers}}, $person if $statuses[0] eq "friends"; | |
} | |
for my $group (keys %groups) { | |
local $\ = undef; | |
open(my $fh, '>', $files{$group}) or die "Can't open $files{$group} $!"; | |
print $fh join("\n",@{$groups{$group}}); | |
close($fh); | |
} | |
my $friend_count = NO('friend',scalar(@{$groups{twitter_friends}})); | |
print "\t$account has $friend_count on Twitter."; | |
my $not_following_count = NO('person',scalar(@{$groups{not_following}})); | |
print "\t$account is not following $not_following_count on Twitter."; | |
my $not_followers_count = NO('person',scalar(@{$groups{not_followers}})); | |
print "\t$account is not being followed by $not_followers_count on Twitter."; | |
my $tweet_tag = '#Friends'; | |
my $space = 140 - length($tweet_tag); | |
my $friends = ''; | |
my @friend_tweets; | |
for my $friend (sort { lc $a cmp lc $b } @{$groups{twitter_friends}}) { | |
if (length($friends) + 1 + length($friend) > $space) { | |
push @friend_tweets, $tweet_tag . $friends; | |
$friends = ''; | |
} | |
$friends .= " \@$friend"; | |
} | |
push @friend_tweets, $tweet_tag . $friends if length($friends); | |
my $friend_tweets_count = NO('tweet',scalar(@friend_tweets)); | |
print "\t$account has $friend_tweets_count for her friends."; | |
open(my $friend_tweets_fh, '>', $files{friend_tweets}) or die "Can't open $files{friend_tweets} $!"; | |
print $friend_tweets_fh join("\n",@friend_tweets); | |
close($friend_tweets_fh); | |
# End followers and friends | |
# Start list updates | |
# link to lists on tumblr http://tmblr.co/ZZVoswE7_RE1 | |
print "\t$account lists"; | |
my %lists; | |
if (-s $files{lists}) { | |
%lists = get_hash( | |
file => $files{lists}, | |
headings => [qw(list_slug list_name members_count members_change subscribers_count subscribers_change)], | |
); | |
} | |
my $lists = $nt->get_lists({ | |
user => $account, | |
}); | |
my $lists_directory = "Twitter/users/$account/lists"; | |
my $lists_full_path = data_directory($lists_directory); | |
mkdir($lists_full_path) or die "Can't make $lists_full_path $!" unless (-d $lists_full_path); | |
my @list_lines; | |
for my $list (sort {$a->{name} cmp $b->{name}} @{$lists->{lists}}) { | |
my $list_slug = $list->{slug}; | |
my $list_name = $list->{name}; | |
my $member_count = $list->{member_count}; | |
my $member_change = $lists{$list_slug}{members_count} ? $member_count - $lists{$list_slug}{members_count} : 0; | |
my $subscriber_count = $list->{subscriber_count}; | |
my $subscriber_change = $lists{$list_slug}{subscriber_count} ? $subscriber_count - $lists{$list_slug}{subscriber_count} : 0; | |
my $list_directory = "Twitter/users/$account/lists/$list_slug"; | |
my $list_full_path = data_directory($list_directory); | |
mkdir($list_full_path) or die "Can't make $list_full_path $!" unless (-d $list_full_path); | |
push @list_lines, join('|',($list_slug,$list_name,$member_count,$member_change,$subscriber_count,$subscriber_change)); | |
print "\t\t$list_name"; | |
if ($subscriber_count > 0) { | |
my @subscribers; | |
for ( my $cursor = -1; $cursor; ) { | |
my $list_subscribers = $nt->list_subscribers({ | |
user => $account, | |
list_id => $list_slug, | |
cursor => $cursor, | |
}); | |
push @subscribers, map $_->{screen_name}, @{$list_subscribers->{users}}; | |
$cursor = $list_subscribers->{next_cursor}; | |
} | |
for my $subscriber (sort {lc $a cmp lc $b} @subscribers) { | |
if (!exists($people{$subscriber}) && $account ne 'Lady_Aleena') { | |
$nt->create_friend({ | |
screen_name => $subscriber, | |
follow => 'true', | |
}); | |
$nt->update_friendship({ | |
screen_name => $subscriber, | |
retweets => 'false', | |
}); | |
print "\t\t\t$subscriber subscribed to $list_name so $short_account followed."; | |
} | |
} | |
{ # Print the file for the subscribers. | |
local $\ = undef; | |
open(my $subscriber_fh, '>', "$list_full_path/subscribers.txt") or die "Can't open $list_full_path/subscribers.txt $!"; | |
print $subscriber_fh join("\n",@subscribers); | |
close($subscriber_fh); | |
} | |
} | |
my @members; | |
for ( my $cursor = -1; $cursor; ) { | |
my $list_members = $nt->list_members({ | |
user => $account, | |
list_id => $list_slug, | |
cursor => $cursor, | |
}); | |
push @members, map $_->{screen_name}, @{$list_members->{users}}; | |
$cursor = $list_members->{next_cursor}; | |
} | |
{ # Print the file for members. | |
local $\ = undef; | |
open(my $member_fh, '>', "$list_full_path/members.txt") or die "Can't open $list_full_path/members.txt $!"; | |
print $member_fh join("\n",@members); | |
close($member_fh); | |
} | |
} | |
if (scalar(@list_lines) > 0) { | |
local $\ = undef; | |
open(my $al_fh, '>', $files{lists}) or die "Can't open $files{lists} $!"; | |
print $al_fh join("\n",@list_lines); | |
close($al_fh); | |
} | |
# End list updates | |
# Start list memberships | |
print "\t$account list memberships"; | |
my @list_memberships; | |
for ( my $cursor = -1; $cursor; ) { | |
my $list_memberships = $nt->list_memberships({ | |
user => $account, | |
cursor => $cursor, | |
}); | |
for my $list_membership (@{$list_memberships->{lists}}) { | |
my $list_full_name = $list_membership->{full_name}; | |
my $member_count = $list_membership->{member_count}; | |
my $subscriber_count = $list_membership->{subscriber_count}; | |
my $user_screen_name = $list_membership->{user}{screen_name}; | |
push @list_memberships, "$list_full_name|$member_count|$subscriber_count|$user_screen_name"; | |
print "\t\t$list_full_name"; | |
} | |
$cursor = $list_memberships->{next_cursor}; | |
} | |
if (scalar(@list_memberships) > 0) { | |
open(my $lm_fh, '>', $files{list_memberships}) or die "Can't open $files{list_memberships} $!"; | |
print $lm_fh join("\n",@list_memberships); | |
close($lm_fh); | |
} | |
# End lists memberships | |
# Start mentions | |
print "$account mentions"; | |
my $last_mention; | |
if (-s $files{mentions}) { | |
open (my $message_fh, '<', $files{mentions}) or die "Can't open $files{mentions}. $!"; | |
my @message_array = <$message_fh>; | |
chomp(@message_array); | |
my $last_line = pop @message_array; | |
my ($last_id,$last_data) = split(/\|/,$last_line,2); | |
$last_mention = $last_id; | |
} | |
my $mentions = $nt->mentions({ | |
count => 200, | |
include_entities => 1, | |
since_id => $last_mention || 1, | |
}); | |
my @new_mentions; | |
MENTION: for my $mention (@{$mentions}) { | |
my $tweet_id = $mention->{id}; | |
my $tweet_dt = $mention->{created_at}; | |
my $tweet_text = encode_entities_numeric($mention->{text},'^\n\x20-\x25\x27-\x7e'); | |
$tweet_text =~ s/[\r\n]+//g; | |
my $tweet_reply_to_screen_name = $mention->{in_reply_to_screen_name} || ''; | |
my $tweet_reply_to_id = $mention->{in_reply_to_status_id} || ''; | |
my $user_id = $mention->{user}{id}; | |
my $user_name = $mention->{user}{screen_name}; | |
if ($tweeting =~ /^y/i && ($tweet_text =~ /^#FF/i || $tweet_text =~ /^#FollowFriday/i)) { | |
try { | |
$nt->update({ | |
status => "\@$user_name Thank you for the \#FF.", | |
in_reply_to_status_id => $tweet_id, | |
}); | |
} catch { warn $_; next MENTION; }; | |
} | |
for my $url (@{$mention->{entities}{urls}}) { | |
my $short_url = quotemeta($url->{url}); | |
my $long_url = $url->{expanded_url} ? $url->{expanded_url} : "http://$short_url"; | |
$tweet_text =~ s/$short_url/$long_url/; | |
} | |
if (!exists($is_account{$user_name})) { | |
push @new_mentions, "$tweet_id|$user_name|$tweet_dt|$tweet_text|$tweet_reply_to_screen_name|$tweet_reply_to_id"; | |
} | |
} | |
if (scalar(@new_mentions) > 0) { | |
local $\ = undef; | |
open (my $message_fh, '>>', $files{mentions}) or die "Can't open $files{mentions}. $!"; | |
print join("\n",reverse @new_mentions); | |
print $message_fh "\n".join("\n",reverse @new_mentions); | |
close($message_fh); | |
print "\n"; | |
} | |
# End mentions | |
# Start retweets | |
print "$account reweets"; | |
my %stored_retweets; | |
if (-f $files{retweets}) { | |
%stored_retweets = get_hash( | |
file => $files{retweets}, | |
headings => [qw(id tweet retweeters)], | |
); | |
} | |
my $retweets = $nt->retweets_of_me({ | |
count => 100, | |
include_entities => 1, | |
}); | |
for my $retweet (@{$retweets}) { | |
my $id = $retweet->{id}; | |
my $retweet_by = $nt->retweeted_by($id); | |
if (!exists($stored_retweets{$id})) { | |
my $retweet_text = encode_entities_numeric($retweet->{text},'^\n\x20-\x25\x27-\x7e'); | |
for my $url (@{$retweet->{entities}{urls}}) { | |
my $short_url = quotemeta($url->{url}); | |
my $long_url = $url->{expanded_url} ? $url->{expanded_url} : "http://$short_url"; | |
$retweet_text =~ s/$short_url/$long_url/; | |
} | |
$stored_retweets{$id}{tweet} = $retweet_text; | |
my @retweeters_list; | |
for my $retweeter (@{$retweet_by}) { | |
my $screen_name = $retweeter->{screen_name}; | |
push @retweeters_list, $screen_name; | |
} | |
$stored_retweets{$id}{retweeters} = scalar(@retweeters_list) > 0 ? join(',',@retweeters_list) : ''; | |
} | |
else { | |
my @retweeters_list = split(/,/,$stored_retweets{$id}{retweeters}); | |
for my $retweeter (@{$retweet_by}) { | |
my $screen_name = $retweeter->{screen_name}; | |
push @retweeters_list, $screen_name if !grep($screen_name,@retweeters_list); | |
} | |
$stored_retweets{$id}{retweeters} = scalar(@retweeters_list) > 0 ? join(',',@retweeters_list) : ''; | |
} | |
$stored_retweets{$id}{id} = $id; | |
} | |
my @updated_retweets; | |
for my $tweet (sort {$stored_retweets{$a}{id} <=> $stored_retweets{$b}{id}} keys %stored_retweets) { | |
my $id = $stored_retweets{$tweet}{id}; | |
my $retweet_text = $stored_retweets{$tweet}{tweet}; | |
my $retweeters = $stored_retweets{$tweet}{retweeters}; | |
push @updated_retweets, "$id|$retweet_text|$retweeters"; | |
} | |
if (scalar(@updated_retweets) > 0) { | |
local $\ = undef; | |
open (my $message_fh, '>', $files{retweets}) or die "Can't open $files{retweets}. $!"; | |
print join("\n",@updated_retweets); | |
print $message_fh join("\n",@updated_retweets); | |
close($message_fh); | |
print "\n"; | |
} | |
# End retweets | |
} | |
open(my $gen_acct_file,'>',get_data('Twitter','account_totals.txt')) or die "Can't open account_totals.txt. $!"; | |
print $gen_acct_file join("\n",@accounts_totals); | |
close($gen_acct_file); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment