summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <git@mx.buetow.org>2021-01-02 13:00:33 +0000
committerPaul Buetow <git@mx.buetow.org>2021-01-02 13:00:33 +0000
commitc3493b103fb35ee852c13b67c709f25f93267483 (patch)
tree8036bf1678a2dc3c72a8bd6ae0c5155eec792d99
parent5161b18fbb896a987675f68b0605114a918bc23b (diff)
more
-rw-r--r--cli-hive.pl88
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;