doctolib-api-corona-date-ch.../search_for_corona_date.pl

143 lines
5.4 KiB
Perl

#!/usr/bin/perl
use strict;
use warnings;
use HTTP::Tiny;
use DateTime;
use JSON;
use LWP::UserAgent;
my %data = (
'Arena Berlin (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457622-457619-457629-457626-457627-457610-457631-457621-457625-457611-457612-457620-457617-457623-457628-457616-457614-457618-457613-457615&insurance_sector=public&practice_ids=158431&destroy_temporary=true&limit=4',
'Messe Berlin (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457415-457408-457411-457407-457504-457414-457511-457404-457412-457409-457405-457418&insurance_sector=public&practice_ids=158434&destroy_temporary=true&limit=4',
'Flughafen Berlin-Tegel (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457363-457254-457331-457358-457349-457256-457263-457343&insurance_sector=public&practice_ids=158436&destroy_temporary=true&limit=4',
'Flughafen Berlin-Tegel (Moderna)' => '&visit_motive_ids=2537716&agenda_ids=465619-465615-465609-465580-465601-466144-465582-466145-466151-465592-465594-465598-466143-466150-466152-466148-466146-466147-465584-466149&insurance_sector=public&practice_ids=158436&destroy_temporary=true&limit=4',
'Messe Berlin (Astra)' => '&visit_motive_ids=2597576&agenda_ids=493350-493326-493328-493324-493331-493329-493334-493348-493352-493320-493322-493335-493338-493340-493333-493353-493343-493345-493339-493347&insurance_sector=public&practice_ids=195952&destroy_temporary=true&limit=4',
'Flughafen Tempelhof (Moderna)' => '&visit_motive_ids=2537716&agenda_ids=499603-499605-499608-499615-499618-499620-499621-499623-499627-499629-499631-499633-499637-499639-499641-499647-499649-499651-499654-499657&insurance_sector=public&practice_ids=158433&destroy_temporary=true&limit=4',
'Velodrom Berlin (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457299-457310-457304-457291-457319-457306-457315-457321-457217-457296-457288-457991-457312-457195-457205-457193-457211-457283-457201&insurance_sector=public&practice_ids=158435&destroy_temporary=true&limit=4',
'Erika-Heß-Eisstadion' => '&visit_motive_ids=2537716&agenda_ids=457979-457966-457971-457975-457970-457955-457968-457953-457976-457963-457977-457946-457954-457956-457960-457973-457959-457944-457964-457961-457967&insurance_sector=public&practice_ids=158437&destroy_temporary=true&limit=4',
);
my $url = 'https://www.doctolib.de/availabilities.json?start_date=';
my $dt = DateTime->now;
my $date = $dt->ymd;
my $epoch = $dt->epoch;
foreach my $station (keys %data)
{
my $json = decode_json do_request($date,$url,$data{$station});
if($json->{'total'} > 20)
{
if(read_last_hit($station,$json->{'total'},$epoch) == 0)
{
print $station.": total => ".$json->{'total'}." @ ".$date."\n";
send_notification($station.": total => ".$json->{'total'}." @ ".$date);
}
write_last_hit($station,$json->{'total'},$epoch);
}
elsif(defined $json->{'next_slot'})
{
#print $station.": found next_slot\n";
#send_notification($station.": found next_slot");
my ($ns_year,$ns_month,$ns_day) = split("-",$json->{'next_slot'});
my $next_slot_dt = DateTime->new( year => $ns_year, month => $ns_month, day => $ns_day );
my $date_diff = $dt->delta_days($next_slot_dt);
my $json2 = decode_json do_request($json->{'next_slot'},$url,$data{$station});
if($json2->{'total'} > 20 and $date_diff->in_units('days') > 1 and $date_diff->in_units('days') < 40)
{
if(read_last_hit($station,$json2->{'total'},$epoch) == 0)
{
print $station.": total => ".$json2->{'total'}." @ ".$json->{'next_slot'}."\n";
send_notification($station.": total => ".$json2->{'total'}." @ ".$json->{'next_slot'});
}
write_last_hit($station,$json2->{'total'},$epoch);
}
elsif(defined $json2->{'next_slot'})
{
print "\t".$station.": LOOP?\n";
send_notification($station.": LOOP?");
}
else
{
#print "\t".$station.": total => ".$json2->{'total'}." @ ".$json->{'next_slot'}."\n";
}
}
else
{
#print $station.": total => ".$json->{'total'}." @ ".$date."\n";
}
sleep 1;
}
sub write_last_hit
{
my ($station,$hits,$epoch) = @_;
open(FILE_W,">>","/tmp/search_for_date-last_hit.txt") or die "Can't open file: $!";
print FILE_W $station."::".$hits."::".$epoch."\n";
close(FILE_W);
}
sub read_last_hit
{
my ($station,$hits,$epoch) = @_;
my $too_early = 0;
if(! -e "/tmp/search_for_date-last_hit.txt")
{
open(NEW_FILE,">","/tmp/search_for_date-last_hit.txt") or die "Can't create file: $!";
close(NEW_FILE);
}
open(FILE_R,"<","/tmp/search_for_date-last_hit.txt") or die "Can't open file: $!";
my @array = <FILE_R>;
close(FILE_R);
foreach my $line (@array)
{
chomp($line);
if($line =~/^(.+)\:\:$hits\:\:(\d+)$/)
{
my $station_old = $1;
my $epoch_old = $2;
$epoch -= 120;
if($station eq $station_old and $epoch < $epoch_old)
{
#print $epoch." < ".$epoch_old."\n";
$too_early = 1;
}
elsif($station eq $station_old and $epoch >= $epoch_old)
{
#print $epoch." > ".$epoch_old."\n";
}
else
{
#print $station." ne ".$station_old." | ".$epoch." != ".$epoch_old."\n";
}
}
}
return $too_early;
}
sub send_notification
{
my ($msg) = @_;
LWP::UserAgent->new()->post(
"https://api.pushover.net/1/messages.json", [
"token" => "<API_TOKEn>",
"user" => "<API_USER>",
"message" => "Impfstation gefunden: ".$msg,
]);
}
sub do_request
{
my ($date,$url1,$url2) = @_;
my $url = $url1.$date.$url2;
my $httptiny = HTTP::Tiny->new("timeout" => 20);
my $response = $httptiny->request("GET",$url);
return $response->{'content'};
}