Adding Farmacia de Guardia.
This commit is contained in:
parent
455afc62f5
commit
af83dabf8c
1
Build.PL
1
Build.PL
@ -17,6 +17,7 @@ my $build = Module::Build->new(
|
||||
'DBD::Pg' => 0,
|
||||
'DateTime::Format::ISO8601.pm' => 0,
|
||||
'DateTime::Format::Mail.pm' => 0,
|
||||
'DateTime::Format::Pg' => 0,
|
||||
'SVG' => 0,
|
||||
'XML::Twig' => 0,
|
||||
'JSON' => 0,
|
||||
|
15
content/posts/0000036-farmacia-de-guardia.xml
Normal file
15
content/posts/0000036-farmacia-de-guardia.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<post>
|
||||
<author>Burguillos.info</author>
|
||||
<date>2023-09-07T16:11:00+00:00</date>
|
||||
<title>Farmacia de Guardia en Burguillos.</title>
|
||||
<ogdesc>Farmacia de Guardia en Burguillos.</ogdesc>
|
||||
<img src="/img/farmacia.webp"/>
|
||||
<category>index</category>
|
||||
<slug>farmacia-guardia</slug>
|
||||
<content>
|
||||
<img alt="Imagen de cruz de Farmacia" src="/img/farmacia.webp"/>
|
||||
<p>Este artículo se rellena automáticamente con los datos de la Farmacia de Guardia, tu navegador o móvil debe soportar Javascript para que funcione.</p>
|
||||
|
||||
<p>La farmacia de guardia esta semana y hasta la siguiente vez que sean las 9:30 un lunes es <b id="farmacia-name"></b> se encuentra ubicada en <b id="farmacia-address"></b>.</p>
|
||||
</content>
|
||||
</post>
|
@ -10,6 +10,7 @@ window.onload = () => {
|
||||
const mobile_foldable = document.querySelector('nav.mobile-foldable');
|
||||
const tables = document.querySelectorAll('table')
|
||||
|
||||
fillFarmaciaGuardia();
|
||||
loadAd()
|
||||
addEasterEggAnimation()
|
||||
|
||||
@ -39,6 +40,26 @@ window.onload = () => {
|
||||
addListenersSearch()
|
||||
};
|
||||
|
||||
function fillFarmaciaGuardia() {
|
||||
const farmaciaName = document.querySelector('#farmacia-name');
|
||||
const farmaciaAddress = document.querySelector('#farmacia-address');
|
||||
if (farmaciaName !== null || farmaciaAddress !== null) {
|
||||
const port = _port()
|
||||
const url = new URL(window.location.protocol
|
||||
+ "//"
|
||||
+ window.location.hostname
|
||||
+ port
|
||||
+ '/farmacia-guardia.json');
|
||||
fetch(url).then(async (res) => {
|
||||
const farmacia = await res.json()
|
||||
if (farmaciaName !== null) {
|
||||
farmaciaName.innerText = farmacia.name;
|
||||
farmaciaAddress.innerText = farmacia.address;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function addListenersSearch() {
|
||||
if (searchMobile !== null) {
|
||||
const searchIcon = searchMobile.querySelector('div.search-icon')
|
||||
@ -62,6 +83,14 @@ function addListenersSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
function _port() {
|
||||
let port = window.location.port;
|
||||
if (port !== '') {
|
||||
port = ':' + port
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
function onSearchChange() {
|
||||
const search = document.querySelector('div.search-overlay div.search input');
|
||||
const searchResults = document.querySelector('div.search-overlay div.search-results');
|
||||
@ -70,10 +99,7 @@ function onSearchChange() {
|
||||
}
|
||||
const query = search.value;
|
||||
fakeSearchInput.value = search.value
|
||||
let port = window.location.port;
|
||||
if (port !== '') {
|
||||
port = ':' + port
|
||||
}
|
||||
const port = _port()
|
||||
const url = new URL(window.location.protocol
|
||||
+ "//"
|
||||
+ window.location.hostname
|
||||
|
@ -52,6 +52,7 @@ sub startup ($self) {
|
||||
# $r->get('/:post')->to('Page#post');
|
||||
$r->get('/stats')->to('Metrics#stats');
|
||||
$r->get('/search.json')->to('Search#search');
|
||||
$r->get('/farmacia-guardia.json')->to('FarmaciaGuardia#current');
|
||||
$r->get('/<:category>.rss')->to('Page#category_rss');
|
||||
$r->get('/:category_slug/atributo/<:attribute_slug>-preview.png')->to('Attribute#get_attribute_preview');
|
||||
$r->get('/:category_slug/atributo/:attribute_slug')->to('Attribute#get');
|
||||
|
@ -60,7 +60,7 @@ sub get_rand_ad($self, $array) {
|
||||
my $max_weight = $self->sum_weights($array);
|
||||
my $rand = int(rand() * $max_weight);
|
||||
my $sum_weight = 0;
|
||||
for my $ad (@$array) {
|
||||
for my $ad (@$valid_ads) {
|
||||
$sum_weight += $ad->weight;
|
||||
if ($rand < $sum_weight) {
|
||||
return $ad;
|
||||
|
@ -43,6 +43,12 @@ sub MIGRATIONS {
|
||||
\&_populate_locations,
|
||||
\&_populate_locations,
|
||||
\&_populate_locations,
|
||||
'CREATE TABLE farmacia_guardia (
|
||||
uuid UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
date timestamp NOT NULL,
|
||||
id_farmacia TEXT NOT NULL
|
||||
);',
|
||||
'CREATE INDEX farmacia_guardia_index on farmacia_guardia (date, id_farmacia, uuid);',
|
||||
);
|
||||
}
|
||||
|
||||
|
20
lib/BurguillosInfo/Farmacia.pm
Normal file
20
lib/BurguillosInfo/Farmacia.pm
Normal file
@ -0,0 +1,20 @@
|
||||
package BurguillosInfo::Farmacia;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Moo::Role;
|
||||
|
||||
requires qw(id name address);
|
||||
|
||||
sub serialize ($self) {
|
||||
return {
|
||||
id => $self->id,
|
||||
name => $self->name,
|
||||
address => $self->address,
|
||||
};
|
||||
}
|
||||
1;
|
141
lib/BurguillosInfo/FarmaciaGuardia.pm
Normal file
141
lib/BurguillosInfo/FarmaciaGuardia.pm
Normal file
@ -0,0 +1,141 @@
|
||||
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;
|
66
lib/BurguillosInfo/Farmacias.pm
Normal file
66
lib/BurguillosInfo/Farmacias.pm
Normal file
@ -0,0 +1,66 @@
|
||||
package BurguillosInfo::Farmacias;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Moo;
|
||||
|
||||
use Module::Pluggable
|
||||
search_path => ['BurguillosInfo::Farmacias'],
|
||||
instantiate => 'new',
|
||||
on_require_error => sub ( $plugin, $error ) {
|
||||
die $error;
|
||||
};
|
||||
|
||||
{
|
||||
my $array;
|
||||
sub array($self) {
|
||||
if (!defined $array) {
|
||||
$self->_populate_farmacias;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
sub _populate_farmacias($self) {
|
||||
$array = [];
|
||||
@$array = $self->plugins();
|
||||
for my $farmacia (@$array) {
|
||||
$self->_check_farmacia_valid($farmacia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $farmacias_by_id;
|
||||
sub by_id($self, $target_id) {
|
||||
if (!defined $farmacias_by_id) {
|
||||
$self->_populate_farmacias_by_id;
|
||||
}
|
||||
if (!defined $target_id) {
|
||||
die 'You must pass $target_id.';
|
||||
}
|
||||
my $farmacia = $farmacias_by_id->{$target_id};
|
||||
if (!defined $farmacia) {
|
||||
die "Farmacia $target_id not found.";
|
||||
}
|
||||
return $farmacia;
|
||||
}
|
||||
|
||||
sub _populate_farmacias_by_id($self) {
|
||||
$farmacias_by_id = {};
|
||||
my $farmacias = $self->array;
|
||||
for my $farmacia (@$farmacias) {
|
||||
$farmacias_by_id->{$farmacia->id} = $farmacia;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub _check_farmacia_valid($self, $farmacia) {
|
||||
if ( !$farmacia->does('BurguillosInfo::Farmacia') ) {
|
||||
die "$farmacia does not implement BurguillosInfo::Farmacia.";
|
||||
}
|
||||
}
|
||||
1;
|
27
lib/BurguillosInfo/Farmacias/CruzDeLaErmita.pm
Normal file
27
lib/BurguillosInfo/Farmacias/CruzDeLaErmita.pm
Normal file
@ -0,0 +1,27 @@
|
||||
package BurguillosInfo::Farmacias::CruzDeLaErmita;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use feature 'signatures';
|
||||
|
||||
use Moo;
|
||||
use parent 'BurguillosInfo::Farmacia';
|
||||
|
||||
sub id {
|
||||
return 'cruz_de_la_ermita';
|
||||
}
|
||||
|
||||
sub name {
|
||||
return 'Farmacia Cruz de La Ermita';
|
||||
}
|
||||
|
||||
sub address {
|
||||
return 'Avenida. Alcalde José Cuesta Godoy, Nº 21. (La calle aun es como Avenida Cruz de la Ermita si lo buscas en Google Maps.)';
|
||||
}
|
||||
|
||||
1;
|
24
lib/BurguillosInfo/Farmacias/Morera.pm
Normal file
24
lib/BurguillosInfo/Farmacias/Morera.pm
Normal file
@ -0,0 +1,24 @@
|
||||
package BurguillosInfo::Farmacias::Morera;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Moo;
|
||||
|
||||
sub id {
|
||||
return 'morera';
|
||||
}
|
||||
|
||||
sub name {
|
||||
return 'Farmacia Óptica Morera';
|
||||
}
|
||||
|
||||
sub address {
|
||||
return 'Calle Virgen del Rosario número 13';
|
||||
};
|
||||
|
||||
use parent 'BurguillosInfo::Farmacia';
|
||||
1;
|
BIN
public/img/farmacia.webp
Normal file
BIN
public/img/farmacia.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 137 KiB |
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user