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;