]> git.sesse.net Git - skvidarsync/commitdiff
Support reacting to attend multiple different events, not just yellow.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 29 Oct 2023 22:49:13 +0000 (23:49 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 29 Oct 2023 23:00:46 +0000 (00:00 +0100)
bin/sync.pl
skvidarlang.sql

index dba9e46f91bc0aefeb25683eb7a4ea42da9b9654..4487fb45dcd6e5d8a76748d7d2534c1bdd09edac 100644 (file)
@@ -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) {
index d52ed9d8b13c3d133a31f78c4c01b543588eeba0..63f537c75784db5676796f26696f07f96fc029da 100644 (file)
@@ -2,6 +2,7 @@ CREATE TABLE applied (
     channel VARCHAR NOT NULL,
     ts VARCHAR NOT NULL,
     name VARCHAR NOT NULL,
+    color VARCHAR NOT NULL DEFAULT 'yellow',
     PRIMARY KEY (channel, ts, name)
 );
 
@@ -35,7 +36,7 @@ CREATE VIEW current_reactions AS
            FROM reaction_log ORDER BY channel, ts, userid, reaction, event_ts DESC ) t1
   WHERE event_type = 'reaction_added';
 
-GRANT SELECT,INSERT,DELETE ON TABLE applied TO skvidarlang;
+GRANT SELECT,UPDATE,INSERT,DELETE ON TABLE applied TO skvidarlang;
 GRANT SELECT,INSERT ON TABLE reaction_log TO skvidarlang;
 GRANT SELECT ON TABLE current_reactions TO skvidarlang;
 GRANT SELECT,UPDATE,INSERT ON TABLE message_sheet_link TO skvidarlang;