From 625b2322dd681b8f11ec25f9ed5c0fc7b0824d0a Mon Sep 17 00:00:00 2001 From: xiconfjs Date: Tue, 25 May 2021 12:43:59 +0200 Subject: [PATCH] v3 --- search_for_corona_date.pl | 137 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 search_for_corona_date.pl diff --git a/search_for_corona_date.pl b/search_for_corona_date.pl new file mode 100644 index 0000000..c8d7bf9 --- /dev/null +++ b/search_for_corona_date.pl @@ -0,0 +1,137 @@ +#!/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=397800-397776-402408-397766&insurance_sector=public&practice_ids=158431&destroy_temporary=true&limit=4', + 'Messe Berlin/ Halle 21 (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457591-457443-457477-457487-457405-457414-457511-457594-457432-397846-457408-457421-457435-457489-457563-457567-457569-457439-457493-457453-457406-457416-457418-457426-457400-457404-457409-457419-457420-457427-457448-457483-457425-457428-457415-457504-457597-457566-457412-457457-457436-457463-397845-397844-457411-457497-457424-457429-457430-457442-457470-404659-457596-457407-457410-457593&insurance_sector=public&practice_ids=158434&destroy_temporary=true&limit=4', + 'Flughafen Berlin-Tegel (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=457379-457323-457329-457374-457334-457346-457253-457255-457256-457294-457317-457335-457399-457514-457350-457326-457330-457254-457267-457303-457275-457276-457281-457289-457300-457301-457302-457307-457309-457314-457331-457355-457388-457515-457338-457263-457266-457277-457286-457287-457308-457320-457343-457268-457500-397841-457512-457382-457385-457324-457460-457513-457285-457392-457395-457251-397843-457252-457264-457271-457279-457290-457292-457318-457358-457327-457341-457293-457250-457305-457377-457396-457333-457349-457265-457313-457316-457352-457295-457390-457363-457282-457297-397842-457336-457337-457413-404656-457510&insurance_sector=public&practice_ids=158436&destroy_temporary=true&limit=4', + 'Flughafen Berlin-Tegel (Moderna)' => '&visit_motive_ids=2537716&agenda_ids=465527-465550-465592-465598-465601-465651-465543-465615-465553-465594-465630-465678-465575-465653-466144-466139-466141-466153-466157-465701-465532-465609-466127-466128-466129-466130-466131-466132-466133-466134-466135-466136-466137-466138-466140-466143-466145-466147-466148-466149-466150-466151-466152-466154-466155-466156-466158-466159-466160-466161-465555-465558-465580-465582-465584-465619-465534-466146-465526&insurance_sector=public&practice_ids=158436&destroy_temporary=true&limit=4', + 'Flughafen Tempelhof (Astra)' => '&visit_motive_ids=2597576&agenda_ids=404658-397960-397955-397956&insurance_sector=public&practice_ids=158433&destroy_temporary=true&limit=4', + 'Flughafen Tempelhof (Moderna)' => '&visit_motive_ids=2537716&agenda_ids=467896-467894-467900-467908-467934-467937-467912-467901-467933-467893-467938-467939-467940-467903-467905-467906-467907-467910-467911-467935-467936-467897-467898-467899-467895&insurance_sector=public&practice_ids=158433&destroy_temporary=true&limit=4', + 'Velodrom Berlin (Biontech)' => '&visit_motive_ids=2495719&agenda_ids=404654-457215-457244-397972-457210-457239-457213-457278-457283-457304-457306-457229-457234-457299-457212-457216-457288-457291-457315-457227-457204-457237-457296-397974-457312-457280-457206-457310-457319-397973-457243-457208-457218-457245-457274-457321&insurance_sector=public&practice_ids=158435&destroy_temporary=true&limit=4', + 'Erika-Heß-Eisstadion' => '&visit_motive_ids=2537716&agenda_ids=397976-397975-457975-457951-457902-457907-457917-457924-457933-457947-457946-457971-457961-457964-457945-457955-457940-457953-457968-457920-457960-457963-457906-404655-457973-457977-457931-457956-457952-457903-457912-457916-457928-457976-457943-457954-457901-457915-457913-457918-457922-457938-457939-457927-457935-457936-457979-457966-457970-457930-457967-457944-457910-397977-457959-457926-457941-457923-457937&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; + open(FILE_R,"<","/tmp/search_for_date-last_hit.txt") or die "Can't open file: $!"; + my @array = ; + 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" => "", + "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'}; +}