X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bin%2Fsync.pl;h=4487fb45dcd6e5d8a76748d7d2534c1bdd09edac;hb=96b7fad9045165418862b9611128413167a35f7f;hp=dba9e46f91bc0aefeb25683eb7a4ea42da9b9654;hpb=fc827b42d333d4f7b4c5014d5decd2e64562fc5b;p=skvidarsync diff --git a/bin/sync.pl b/bin/sync.pl index dba9e46..4487fb4 100644 --- a/bin/sync.pl +++ b/bin/sync.pl @@ -19,6 +19,27 @@ require '../include/config.pm'; my $dbh; my @log = (); +my %rgb = ( + yellow => { + red => 1, + green => 1, + blue => 0, + alpha => 1 + }, + blue => { + red => 0, + green => 1, + blue => 1, + alpha => 1 + }, + white => { + red => 1, + green => 1, + blue => 1, + alpha => 0 + } +); + sub get_oauth_bearer_token { my $ua = shift; my $now = time(); @@ -198,7 +219,7 @@ sub best_name_for_log { sub create_reaction_log { my ($dbh, $invitation_ts, $slack_userid_to_real_name, $slack_userid_to_slack_name) = @_; - my $q = $dbh->prepare('select userid,event_type,reaction,to_char(event_ts,\'YYYY-mm-dd HH24:MI\') as event_ts from ( select distinct on (channel,ts,userid,reaction) userid,event_type,reaction,timestamptz \'1970-01-01 utc\' + event_ts::float * interval \'1 second\' as event_ts from reaction_log where channel=? and ts=? and reaction in (\'heart\',\'open_mouth\') order by channel,ts,userid,reaction,event_ts desc ) t1 where event_ts > current_timestamp - interval \'8 hours\' order by event_ts desc limit 50'); + my $q = $dbh->prepare('select userid,event_type,reaction,to_char(event_ts,\'YYYY-mm-dd HH24:MI\') as event_ts from ( select distinct on (channel,ts,userid,reaction) userid,event_type,reaction,timestamptz \'1970-01-01 utc\' + event_ts::float * interval \'1 second\' as event_ts from reaction_log where channel=? and ts=? and reaction in (\'heart\',\'open_mouth\',\'blue_heart\') order by channel,ts,userid,reaction,event_ts desc ) t1 where event_ts > current_timestamp - interval \'8 hours\' order by event_ts desc limit 50'); $q->execute($config::invitation_channel, $invitation_ts); my @recent_changes = (); while (my $ref = $q->fetchrow_hashref) { @@ -210,6 +231,8 @@ sub create_reaction_log { } if ($ref->{'reaction'} eq 'open_mouth') { $msg .= '😮'; + } elsif ($ref->{'reaction'} eq 'blue_heart') { + $msg .= '💙'; } else { $msg .= '❤️'; } @@ -225,43 +248,40 @@ sub create_reaction_log { # Also applies the diff to the database (a bit ugly). sub find_diff { - my ($dbh, $invitation_ts, $want_names, $have_names, $seen_names) = @_; + my ($dbh, $invitation_ts, $want_colors, $have_colors, $seen_names) = @_; my @diffs = (); - for my $real_name (keys %$want_names) { - next if (exists($have_names->{$real_name})); - skv_log("Markerer at $real_name skal på trening."); - push @diffs, [ - $real_name, - { - backgroundColor => { - red => 1, - green => 1, - blue => 0, - alpha => 1 - } + for my $real_name (keys %$want_colors) { + my $wc = $want_colors->{$real_name}; + if (exists($have_colors->{$real_name})) { + if ($have_colors->{$real_name} eq $wc) { + # Already good. + next; } - ]; - $dbh->do('INSERT INTO applied (channel, ts, name) VALUES (?, ?, ?)', undef, - $config::invitation_channel, $invitation_ts, $real_name); + skv_log("Markerer at $real_name har byttet treningssted."); + push @diffs, [ + $real_name, { backgroundColor => $rgb{$wc} } + ]; + $dbh->do('UPDATE applied SET color=? WHERE channel=? AND ts=? AND name=?', undef, + $wc, $config::invitation_channel, $invitation_ts, $real_name); + } else { + skv_log("Markerer at $real_name skal på trening."); + push @diffs, [ + $real_name, { backgroundColor => $rgb{$wc} } + ]; + $dbh->do('INSERT INTO applied (channel, ts, name, color) VALUES (?, ?, ?, ?)', undef, + $config::invitation_channel, $invitation_ts, $real_name, $wc); + } } - for my $real_name (keys %$have_names) { - next if (exists($want_names->{$real_name})); + for my $real_name (keys %$have_colors) { + next if (exists($want_colors->{$real_name})); if (!exists($seen_names->{lc $real_name})) { # TODO: This can somehow come if we try to add someone who's not in the sheet, too? skv_log("Ønsket å fjerne at $real_name skulle på trening, men de var ikke i regnearket lenger."); } else { skv_log("Fjerner at $real_name skal på trening."); push @diffs, [ - $real_name, - { - backgroundColor => { - red => 1, - green => 1, - blue => 1, - alpha => 0 - } - } + $real_name, { backgroundColor => $rgb{white} } ]; $dbh->do('DELETE FROM applied WHERE channel=? AND ts=? AND name=?', undef, $config::invitation_channel, $invitation_ts, $real_name); @@ -335,11 +355,31 @@ sub run { } # Find everyone who are marked as attending on Slack (via reactions). - $q = $dbh->prepare('SELECT DISTINCT userid FROM current_reactions WHERE channel=? AND ts=? AND reaction IN (\'heart\', \'open_mouth\')'); + $q = $dbh->prepare('SELECT DISTINCT userid,reaction FROM current_reactions WHERE channel=? AND ts=? AND reaction IN (\'heart\', \'open_mouth\', \'blue_heart\')'); $q->execute($config::invitation_channel, $invitation_ts); my @attending_userids = (); + my %colors = (); + my %double = (); while (my $ref = $q->fetchrow_hashref) { - push @attending_userids, $ref->{'userid'}; + my $userid = $ref->{'userid'}; + push @attending_userids, $userid; + if ($ref->{'reaction'} eq 'blue_heart') { + if (exists($colors{$userid}) && $colors{$userid} eq 'yellow') { + $double{$userid} = 1; + } + $colors{$userid} = 'blue'; + } else { + if (exists($colors{$userid}) && $colors{$userid} eq 'blue') { + $double{$userid} = 1; + } + $colors{$userid} = 'yellow'; + } + } + + # Remove double-attenders (we will log them as warnings further down). + @attending_userids = grep { !exists($double{$_}) } @attending_userids; + for my $userid (keys %double) { + delete $colors{$userid}; } # Get the list of all people in the sheet (we're going to need them soon anyway). @@ -459,8 +499,14 @@ sub run { ); die $response->decoded_content if (!$response->is_success); + # Now that we have Slack names, we can log double-reacters. + for my $userid (keys %double) { + my $name = best_name_for_log($userid, \%slack_userid_to_real_name, \%slack_userid_to_slack_name); + skv_log("$name er påmeldt flere steder på Slack; vet ikke hvilken som skal brukes."); + } + # Find the list of names to mark yellow. - my %want_names = (); + my %want_colors = (); my $main_sheet_rows = $main_sheet_json->{'sheets'}[0]{'data'}[0]{'rowData'}; for my $userid (@attending_userids) { next if (!exists($slack_userid_to_real_name{$userid})); @@ -476,22 +522,22 @@ sub run { if (scalar @$seen >= 2) { skv_log("$slack_name ($userid) er påmeldt på Slack, men står flere steder (se over); vet ikke hvilken celle som skal brukes."); } else { - $want_names{$seen->[0][0]} = 1; + $want_colors{$seen->[0][0]} = $colors{$userid}; } } } # Find the list of names we already marked yellow. - my %have_names = (); + my %have_colors = (); $dbh->{AutoCommit} = 0; $dbh->do('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE'); - $q = $dbh->prepare('SELECT name FROM applied WHERE channel=? AND ts=?'); + $q = $dbh->prepare('SELECT name,color FROM applied WHERE channel=? AND ts=?'); $q->execute($config::invitation_channel, $invitation_ts); while (my $ref = $q->fetchrow_hashref) { - $have_names{$ref->{'name'}} = 1; + $have_colors{$ref->{'name'}} = $ref->{'color'}; } - my @diffs = find_diff($dbh, $invitation_ts, \%want_names, \%have_names, \%seen_names); + my @diffs = find_diff($dbh, $invitation_ts, \%want_colors, \%have_colors, \%seen_names); my @yellow_updates = (); if (scalar @diffs > 0) {