Está en la página 1de 4

# Se situa en directorio del script.

chdir(dirname($0));

# Carga la configuración.

my $config = YAML::Tiny->read( 'config.yml' )->[0];


my $log_config = $config->{'log'};
my $db_config = $config->{'database'};
my $central_config = $config->{'central'};
my $storage_config = $config->{'storage'};

# Revisa la configuración.

if ($log_config->{'enable'} eq 'true') {
my $logfile = $log_config->{'dirpath'} . '/tvsend.log';
open(FH, '>>', $logfile ) || &error("No se puede escribir en el archivo de log.");
close(FH);
&error("Los niveles del log pueden ser: debug, info, warn o error.") if ($log_config-
>{'level'} !~ /^debug|info|warn|error$/);
$log = Mojo::Log->new('path' => $logfile, 'level' => $log_config->{'level'});
}
$log->debug("Revisando el archivo de configuración.") if (defined $log);
$storage_config->{'path'} .= '/' if ($storage_config->{'path'} !~ /\/$/);
&error("No existe el 'path' de la sección 'storage'.") if (! -e $storage_config->{'path'});
&error("No se puede leer el 'path' de la sección 'storage'.") if (! -r $storage_config-
>{'path'});
&error("El valor del parámetro 'secure' de la sección 'central' solo pueden ser 'true' o
'false'.") if ($central_config->{'secure'} !~ /^(true|false)$/);
#&error("El valor del parámetro 'ip' de la sección 'central' no puede estar vacío.") if
($central_config->{'ip'} =~ /^ *$/);

# Se conecta a la base de datos.

$log->debug("Conectándose a la base de datos.") if (defined $log);


$dbh = DBI->connect("dbi:MariaDB:host=" . $db_config->{'host'} . ";port=" . $db_config-
>{'port'} . ";database=" . $db_config->{'name'}, $db_config->{'user'}, $db_config->{'pass'}, {
'PrintError' => 0,
'AutoCommit' => 0
}) || &error("No se pudo conectar a la base de datos: " . DBI->errstr);

# Obtiene los reportes almacenados localmente.


$log->debug("Obteniendo los reportes almacenados en la DB.") if (defined $log);
my $sth = $dbh->prepare("
SELECT
*
FROM
`report`
");
$sth->execute() || &error("No se pudo conectar a la base de datos: " . DBI->errstr);
my $db_reports = $sth->fetchall_hashref('md5sum');
$dbh->disconnect;

# Obtiene los md5sum de los reportes almacenados remotamente.

$log->debug("Obteniendo los reportes almacenados remotamente.") if (defined $log);


my $ua = LWP::UserAgent->new;
$ua->agent("Transferview/0.1 ");
my $req = HTTP::Request->new(GET => 'http' . ($central_config->{'secure'} eq 'true' ? 's' :
'') . '://' . $central_config->{'ip'} . '/hash_reports');
my $res = $ua->request($req);
if (! $res->is_success) {
&error("No se pudo obtener el listado de los reportes remotos: " . $res->status_line);
}
my $response = decode_json($res->content);
if ($response->{'status'} ne 'ok') {
&error("No se pudo obtener el listado de los reportes remotos: " . $response->{'msg'});
}
my $remote_reports = $response->{'values'};

# Recorre los reportes locales para determinar si no existen remotamente.

foreach my $db_hash (keys %{$db_reports}) {

# Determina si existe el reporte.

my $found = 0;
foreach my $remote_hash (@{$remote_reports}) {
$found++ if ($db_hash eq $remote_hash);
}

if (! $found) {

my $report_key = $db_reports->{$db_hash}->{'key'};

$log->info("No se encontró el reporte '$report_key' en el servidor central.");


# Lee el archivo del reporte.

$log->debug("Cargando el archivo local del reporte.");


my $filename = $report_key . '_' . $db_hash;
$filename =~ s/[^a-z0-9\-]/_/ig;
$filename =~ s/_+/_/g;
my $report_file = $storage_config->{'path'} . $filename . '.pdf';
my $file_blob = `base64 '$report_file'`;

# Envía el reporte al servidor central.

$log->debug("Enviando el reporte al servidor central.");


my $req = HTTP::Request->new(
'POST',
'http' . ($central_config->{'secure'} eq 'true' ? 's' : '') . '://' . $central_config->{'ip'} .
'/report',
['Content-Type' => 'application/json; charset=UTF-8'],
encode_json({
'db' => $db_reports->{$db_hash},
'file' => {
'filename' => $filename . '.pdf',
'blob' => $file_blob
}
})
);
my $res = $ua->request($req);
if (! $res->is_success) {
&error("No se pudo envíar el reporte '$report_key': " . $res->status_line);
}
my $response = decode_json($res->content);
if ($response->{'status'} ne 'ok') {
&error("No se pudo envíar el reporte '$report_key': " . $response->{'msg'});
}
}
}

# Finaliza el script.

$log->info("Ejecución finalizada") if (defined $log);


exit 0;

# .-----------.
# | FUNCTIONS |
# '-----------'

sub error {

my $msg = shift;
chomp($msg);

$log->error($msg) if (defined $log);


print STDERR "$msg\n";
$dbh->disconnect if (defined $dbh);

$log->error("Finalización anticipada") if (defined $log);


exit 2;
}

sub warn {

my $msg = shift;
chomp($msg);

$log->warn($msg) if (defined $log);


print STDERR "$msg\n";

return 1;
}

También podría gustarte