Browse Source

add `link` route to lookup direct link to entries by channel+time+nick

Byron Jones 6 years ago
parent
commit
22bdf6409d
3 changed files with 54 additions and 2 deletions
  1. 48 1
      lib/LogBot/Web/Channel.pm
  2. 1 1
      lib/LogBot/Web/Util.pm
  3. 5 0
      logbot-web

+ 48 - 1
lib/LogBot/Web/Channel.pm

@@ -8,7 +8,7 @@ use DateTime ();
 use Encode qw( decode );
 use LogBot::Database qw( dbh execute_with_timeout );
 use LogBot::Util qw( event_to_short_string );
-use LogBot::Web::Util qw( channel_from_param date_from_param munge_emails preprocess_event );
+use LogBot::Web::Util qw( channel_from_param date_from_param munge_emails preprocess_event url_for_channel );
 
 sub _get_logs {
     my ($c, $dbh, $channel, $date) = @_;
@@ -132,4 +132,51 @@ sub render_raw {
     $c->render(text => join("\n", @lines) . "\n", format => 'txt', charset => 'utf-8');
 }
 
+sub _get_link {
+    my ($c) = @_;
+    my $config = $c->stash('config');
+    my $dbh = dbh($config, cached => 1);
+
+    my $channel = channel_from_param($c) // return (404, 'Channel not logged');
+    my $time    = $c->param('time')      // return (400, 'Bad or missing timestamp');
+    my $nick    = $c->param('nick')      // return (400, 'Bad or missing nick');
+
+    # search for entries +/- 5 seconds from the specified time
+    # returns closest match
+    ## no critic (ProhibitInterpolationOfLiterals)
+    #<<<
+    my $sql =
+        "SELECT COALESCE(old_id, id) AS id\n" .
+        "FROM logs\n" .
+        "WHERE (channel = ?) " .
+            "AND (time BETWEEN " . ($time - 5) . " AND " . ($time + 5) . ") ".
+            "AND (nick = ? COLLATE NOCASE)\n" .
+        "ORDER BY ABS(time - $time) ASC, time\n" .
+        "LIMIT 1";
+    #>>>
+    ## use critic
+
+    my $logs = execute_with_timeout($dbh, $sql, [$channel, $nick], 5);
+    return (408, 'Request took too long to process and has been cancelled.') unless defined $logs;
+    return (404, 'Entry not found') unless scalar @{$logs};
+    return (
+        302,
+        url_for_channel(
+            channel => $channel,
+            date    => DateTime->from_epoch(epoch => $time),
+            id      => $logs->[0]->{id},
+        )
+    );
+}
+
+sub redirect_to {
+    my ($c) = @_;
+    my ($status, $response) = _get_link($c);
+    if ($status == 302) {
+        $c->redirect_to($response);
+    } else {
+        $c->render(status => $status, text => $response, format => 'txt');
+    }
+}
+
 1;

+ 1 - 1
lib/LogBot/Web/Util.pm

@@ -121,7 +121,7 @@ sub url_for_channel {
     if ($params{date}) {
         push @path, ref($params{date}) ? $params{date}->ymd('') : $params{date};
     }
-    return '/' . join('/', @path);
+    return '/' . join('/', @path) . ($params{id} ? '#c' . $params{id} : '');
 }
 
 sub irc_host {

+ 5 - 0
logbot-web

@@ -243,6 +243,11 @@ get '/#channel/:date/raw' => [date => qr/\d{8}/] => sub {
     LogBot::Web::Channel::render_raw($c);
 };
 
+get '/#channel/link/:time/:nick' => [time => qr /\d+/] => sub {
+    my ($c) = @_;
+    LogBot::Web::Channel::redirect_to($c);
+};
+
 get '/#channel/stats' => sub {
     my ($c) = @_;
     LogBot::Web::Stats::render($c, require_channel => 1);