burguillos.info/lib/BurguillosInfo/FarmaciaGuardia.pm

142 lines
4.1 KiB
Perl

package BurguillosInfo::FarmaciaGuardia;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Data::Dumper;
use Moo;
use DateTime;
use DateTime::Format::Pg;
use Mojo::UserAgent;
use BurguillosInfo::Farmacias;
use BurguillosInfo::Farmacias::CruzDeLaErmita;
use BurguillosInfo::Farmacias::Morera;
has _app => ( is => 'lazy', );
has _db => ( is => 'lazy' );
sub _build__app {
require BurguillosInfo;
return BurguillosInfo->new;
}
sub get_current ($self) {
my $date_search = $self->_get_search_date;
my $farmacia_db = $self->_search_horario_db($date_search);
if (defined $farmacia_db) {
return $farmacia_db;
}
my $farmacia;
eval {
$farmacia = $self->_request_horario_internet($date_search);
};
if (!defined $farmacia) {
die "API possibly broken for Farmacia de Guardia. $@";
}
$self->_register_farmacia($date_search, $farmacia);
return $farmacia;
}
sub _register_farmacia($self, $date_search, $farmacia) {
my $f = DateTime::Format::Pg->new;
my $dbh = $self->_db;
$dbh->do(<<'EOF', undef, $f->format_datetime($date_search), $farmacia->id);
INSERT INTO farmacia_guardia (date, id_farmacia) VALUES (?, ?);
EOF
}
sub _search_horario_db ( $self, $date_search ) {
my $f = DateTime::Format::Pg->new;
my $db = $self->_db;
$date_search = $date_search->clone;
$date_search->set_time_zone('UTC');
my $start_farmacia_week = $self->_get_start_date_week($date_search);
my $end_farmacia_week = $self->_get_end_date_week($date_search);
my $horarios = $db->selectall_arrayref(
<<'EOF', { Slice => {} }, $f->format_datetime($start_farmacia_week), $f->format_datetime($end_farmacia_week) );
SELECT id_farmacia from farmacia_guardia where date > ? and date < ?;
EOF
if (!scalar @$horarios) {
return;
}
my $id = $horarios->[0]{id_farmacia};
return BurguillosInfo::Farmacias->new->by_id($id);
}
sub _request_horario_internet ( $self, $date_search ) {
my $ua = $self->_ua;
my $result = $ua->get(
'http://www.farmaciacruzdelaermita.com/index.php/component/dpcalendar/events',
form => {
limit => 0,
compact => 0,
my => 0,
format => 'raw',
ids => 10,
'date-start' => $date_search->epoch,
'date-end' => $date_search->epoch,
_ => $date_search->epoch * 1000,
}
)->result;
my $json;
eval { $json = $result->json; };
if ($@) {
die "Unable to recover data of Farmacia de Guardia $@.";
}
my $data;
eval { $data = $json->[0]{data}; };
if ( $@ || !defined $data ) {
die "Unable to get data of calendar.";
}
if ( scalar @$data ) {
return BurguillosInfo::Farmacias::CruzDeLaErmita->new;
}
return BurguillosInfo::Farmacias::Morera->new;
}
sub _ua {
return Mojo::UserAgent->new;
}
sub _get_search_date ($self) {
my $current_date = DateTime->now;
my $date_search = $current_date->clone;
if ( $date_search < $self->_get_start_date_week($current_date) ) {
$date_search = $date_search->add( days => -1 );
}
return $date_search;
}
sub _get_end_date_week ( $self, $date_search ) {
my $start_farmacia_week = $self->_get_start_date_week($date_search);
my $end_farmacia_week = $start_farmacia_week->clone->add( weeks => 1 );
$end_farmacia_week->set_time_zone('Europe/Madrid');
$end_farmacia_week->set_hour(9);
$end_farmacia_week->set_minute(30);
$end_farmacia_week->set_time_zone('UTC');
return $end_farmacia_week;
}
sub _get_start_date_week ( $self, $date_search ) {
my $start_farmacia_week = $date_search->clone->truncate( to => 'week' );
$start_farmacia_week->set_time_zone('Europe/Madrid');
$start_farmacia_week->set_hour(9);
$start_farmacia_week->set_minute(30);
$start_farmacia_week->set_time_zone('UTC');
return $start_farmacia_week;
}
sub _build__db ($self) {
require BurguillosInfo::DB;
return BurguillosInfo::DB->connect( $self->_app );
}
1;