GEmeTool/lib/GEmeTool/Log.pm

113 lines
2.8 KiB
Perl

package GEmeTool::Log;
use v5.16.3;
use strict;
use warnings;
use Moo;
use parent 'Exporter';
use Digest::SHA qw/sha256_hex/;
use Path::Tiny;
use UUID::URandom qw/create_uuid_string/;
use GEmeTool::DB;
use GEmeTool::Config;
our @EXPORT_OK = qw/logger/;
my %triggers_on_message;
sub logger {
return GEmeTool::Log->new;
}
sub msg {
my $self = shift;
my $msg = shift;
my $input_file = shift;
my $output_file = shift;
my $backup_pk3_file = shift;
my ( $input_file_backup, $output_file_backup ) =
$self->backup_files( $input_file, $output_file );
my $db = GEmeTool::DB->connect;
my $uuid = create_uuid_string();
my $insert = <<'EOF';
INSERT INTO logs
(uuid, date, message, input_file,
output_file, backup_input_file,
backup_output_file)
VALUES (?, datetime('now'), ?, ?, ?, ?, ?);');
EOF
$db->do( $insert, {}, $uuid, $msg, $input_file, $output_file,
$input_file_backup, $output_file_backup );
for my $key (keys %triggers_on_message) {
$triggers_on_message{$key}->();
}
}
sub backup_files {
my $self = shift;
my @files = @_;
my $data_dir = GEmeTool::Config->new->data_dir;
my $backup_dir = $data_dir->child('backups');
$backup_dir->mkpath;
@files = map { sub {return undef if !defined $_; return path($_)->absolute}->() } @files;
my @result_files;
for my $file (@files) {
if (!defined $file || !-f $file) {
push @result_files, undef;
next;
}
my $contents = $file->slurp_raw;
my $digest = sha256_hex($contents);
my ($possible_output) =
grep { $_->basename =~ /^$digest-/ } $backup_dir->children;
if ( defined $possible_output ) {
# We should probably check that the backup
# is unmodified, but I cannot
# figure a user friendly way to recover from
# that error.
push @result_files, $possible_output;
next;
}
my $basename = $file->basename;
$basename =~ s/\.\.//g;
$basename =~ s/\///g;
my $output_file = $backup_dir->child("$digest-$basename");
$output_file->spew_raw($contents);
push @result_files, $output_file;
}
return @result_files;
}
sub get_logs {
my $self = shift;
my $db = GEmeTool::DB->connect;
my $query = <<'EOF';
SELECT message, date, input_file,
output_file, backup_input_file,
backup_output_file
FROM logs
ORDER BY date DESC;
EOF
my $results = $db->selectall_arrayref($query, {Slice => {}});
return $results;
}
sub del_on_message {
my $self = shift;
my $func = shift;
delete $triggers_on_message{$func};
}
sub add_on_message {
my $self = shift;
my $func = shift;
$triggers_on_message{$func} = $func;
}
1;