From 41973a17591ae42d683ea1f97b6d1a57786bcfe2 Mon Sep 17 00:00:00 2001 From: dakkar Date: Sat, 19 Dec 2015 13:03:20 +0000 Subject: different output format, input mostly works --- twitlist.pl | 111 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 20 deletions(-) (limited to 'twitlist.pl') diff --git a/twitlist.pl b/twitlist.pl index 57774a3..fe049a0 100644 --- a/twitlist.pl +++ b/twitlist.pl @@ -10,6 +10,8 @@ use Try::Tiny; use Safe::Isa; use open ':std',':locale'; +my $WRITING=0; + use Data::Printer; sub get_twitter { @@ -63,7 +65,7 @@ sub fetch_friends_info { }); my %friends_info = map { - $_->{id} => { name => $_->{name} } + $_->{id} => { $_->%{qw(name screen_name)} } } $friends->@*; return \%friends_info; @@ -105,24 +107,16 @@ sub print_friends_lists_matrix { my ($li,$fi) = @_; my @lists = to_list($li); - my $list_width = set_display_name(\@lists); + set_display_name(\@lists); my @friends = to_list($fi); my $friend_width = set_display_name(\@friends); - print ' ' x ($friend_width+1); - for my $l (@lists) { - print $l->{dn},' '; - } - print "\n"; - for my $f (@friends) { - printf '%-*s ',$friend_width,$f->{dn}; - for my $l (@lists) { - printf '%-*s ', - length($l->{dn}), - ( $l->{members}->{$f->{id}} - ? '*' : '_' ); - } + printf '%-*s : ',$friend_width,$f->{dn}; + print join ', ', + map { $_->{dn} } + grep { $_->{members}->{$f->{id}} } + @lists; print "\n"; } } @@ -131,14 +125,84 @@ sub parse_friends_lists_matrix { my ($fn) = @_; my @lines = path($fn)->lines_utf8; - my @list_ids = $lines[0] =~ m{\((\d+)\)}g; - shift @lines; my %lists; for my $l (@lines) { - $l =~ s{\A.*?\((\d+)\)\s+}{} or next; + $l =~ s{\A.*?\((\d+)\)\s+:}{} or next; my $friend_id = $1; - + my @lists = map { s{\A\s*(.*?)\s*\z}{$1}r } split ',',$l; + for my $list (@lists) { + my ($list_name,$list_id) = ($list =~ m{\A(.*?)(?:\s+\((\d+)\))?\z}); + next unless $list_name; + my $list_data = $lists{$list_name}||={}; + if ($list_id && $list_data->{id}) { + if ($list_data->{id} != $list_id) { + warn "List $list_name id conflict for friend $friend_id"; + } + } + else { + $list_data->{id} ||= $list_id; + } + $list_data->{members}->{$friend_id} = 1; + } + } + return \%lists; +} + +sub make_it_so { + my ($tw,$current_lists,$wanted_lists) = @_; + + my @operations; + # first, lists to create + for my $list (keys $wanted_lists->%*) { + if ($current_lists->{$list}) { + $wanted_lists->{$list}{id} ||= $current_lists->{$list}{id}; + if ($wanted_lists->{$list}{id} != $current_lists->{$list}{id}) { + warn "list $list has conflicting ids!\n"; + } + } + else { + warn "creating $list\n"; + my $list_data; + if ($WRITING) { + $list_data = $tw->create_list({name=>$list,mode=>'private'}); + } + else { + $list_data = { id => int(rand(10000)) }; + } + $current_lists->{$list} = { + $list_data->%{id}, + members => {}, + }; + } + } + # then, set members + for my $list (keys $wanted_lists->%*) { + warn "operating on $list\n"; + my %current_members = $current_lists->{$list}->{members}->%*; + my %wanted_members = $wanted_lists->{$list}{members}->%*; + my %to_add = %wanted_members; delete @to_add{keys %current_members}; + my %to_remove = %current_members; delete @to_remove{keys %wanted_members}; + my @to_remove=keys %to_remove; + while (my @these = splice @to_remove,0,100) { + warn "Removing @these from $list\n"; + if ($WRITING) { + $tw->remove_list_members({ + list_id => $current_lists->{$list}{id}, + user_id => \@these, + }); + } + } + my @to_add=keys %to_add; + while (my @these = splice @to_add,0,100) { + warn "Adding @these to $list\n"; + if ($WRITING) { + $tw->add_list_members({ + list_id => $current_lists->{$list}{id}, + user_id => \@these, + }); + } + } } } @@ -155,11 +219,18 @@ try { $friends_info = fetch_friends_info($tw); save_info($lists_info,$friends_info); } - print_friends_lists_matrix($lists_info,$friends_info); + if (@ARGV) { + my $wanted_lists = parse_friends_lists_matrix($ARGV[0]); + make_it_so($tw,$lists_info,$wanted_lists); + } + else { + print_friends_lists_matrix($lists_info,$friends_info); + } } catch { if ($_->$_isa('Net::Twitter::Error')) { my $limit = $tw->rate_limit_status; p $limit; + p $_; } else { local $@=$_;die } }; -- cgit v1.2.3