diff options
| author | Paul Buetow <git@mx.buetow.org> | 2021-01-02 13:00:33 +0000 |
|---|---|---|
| committer | Paul Buetow <git@mx.buetow.org> | 2021-01-02 13:00:33 +0000 |
| commit | c3493b103fb35ee852c13b67c709f25f93267483 (patch) | |
| tree | 8036bf1678a2dc3c72a8bd6ae0c5155eec792d99 | |
| parent | 5161b18fbb896a987675f68b0605114a918bc23b (diff) | |
more
| -rw-r--r-- | cli-hive.pl | 88 |
1 files changed, 67 insertions, 21 deletions
diff --git a/cli-hive.pl b/cli-hive.pl index f0187f2..a3694be 100644 --- a/cli-hive.pl +++ b/cli-hive.pl @@ -4,21 +4,44 @@ use strict; use warnings; use Data::Dumper; +use File::Tail; use JSON; +use Digest::SHA qw(sha256_hex); +use Net::Domain qw(hostfqdn); +use Storable; -sub tojson { +our %DEFAULT_DATA = ( + user => $ENV{'USER'}, + hostname => hostfqdn(), + shell => 'zsh', +); + +our %PROCESSED; + +sub read_processed { + return unless -f "$ENV{'HOME'}/.cli-hive.processed"; + %PROCESSED = %{retrieve "$ENV{'HOME'}/.cli-hive.processed"}; +} + +sub store_processed { + store \%PROCESSED, "$ENV{'HOME'}/.cli-hive.processed", +} + +sub record_to_json { my $timestamp = shift; my $lines = shift; - my %lines = ( - 'command' => join '\\n', @$lines, + my %json = ( + timestamp => $timestamp, + command => join '\\n', @$lines, ); - $lines{'timestamp'} = $timestamp if defined $timestamp; + @json{keys %DEFAULT_DATA} = values %DEFAULT_DATA; - print encode_json \%lines; + #print encode_json \%json; + print Dumper \%json; print "\n"; } -sub extract_timestamp { +sub zsh_extract_timestamp { my $line = shift; my ($timestamp, $command) = $line =~ /^: (\d+).*?;(.*)/; @@ -26,13 +49,21 @@ sub extract_timestamp { return (undef, $line); } -sub entry { - my @lines; - my $timestamp; +sub checksum { + my $timestamp = shift; + my @fields = @_; + + push @fields, $timestamp if defined $timestamp; + sha256_hex(join '', @fields); +} + +sub record_reader { + my ($timestamp, @lines); return sub { my $line = shift; - my ($timestamp_, $command) = extract_timestamp $line; + + my ($timestamp_, $command) = zsh_extract_timestamp $line; $timestamp = $timestamp_ if defined $timestamp_; if ($command =~ /\\$/) { @@ -40,23 +71,38 @@ sub entry { push @lines, $command; return; } - chomp $command; - push @lines, $command; - tojson $timestamp, \@lines; - @lines, $timestamp = (), undef; + if (defined $timestamp) { + chomp $command; + push @lines, $command; + + my $checksum = checksum $timestamp, @lines; + unless (exists $PROCESSED{$checksum}) { + record_to_json $timestamp, \@lines; + $PROCESSED{$checksum} = { + timestamp => time, + }; + store_processed; + } + } + + @lines = (); + $timestamp = undef; }; } sub follow_history { - open my $fd, '<', "$ENV{HOME}/.zsh_history" or die $!; - seek $fd, SEEK_END; - for (;;) { - my $entry = entry; - $entry->($_) while <$fd>; - sleep 1; + my $file = File::Tail->new( + name => "$ENV{'HOME'}/.zsh_history", + interval => 0.1, + maxinterval => 1, + ); + + my $reader = record_reader; + while (defined(my $line = $file->read)) { + $reader->($line); } - close $fd; } +read_processed; follow_history; |
