1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use DateTime qw( );
use Path::Tiny;
use File::Fetch;
use JSON::MaybeXS qw( decode_json );
use Text::Table::Tiny qw( generate_table );
use OpenBSD::Unveil;
# Unveil @INC.
foreach my $path (@INC) {
unveil( $path, 'rx' ) or
die "Unable to unveil: $!";
}
# %unveil contains list of paths to unveil with their permissions.
my %unveil = (
"/" => "rx", # Unveil "/", remove this later after profiling with
# ktrace.
"/home" => "", # Veil "/home", we don't want to read it.
"/tmp" => "rwc",
"/dev/null" => "rw",
);
# Unveil each path from %unveil.
keys %unveil;
while( my( $path, $permission ) = each %unveil ) {
unveil( $path, $permission ) or
die "Unable to unveil: $!";
}
# Fetch latest data from api.
my $url = 'https://api.covid19india.org/data.json';
my $ff = File::Fetch->new(uri => $url);
# Save the api response under /tmp.
my $file = $ff->fetch( to => '/tmp' ) or
die $ff->error;
# Slurp api response to $file_data.
my $file_data = path($file)->slurp;
# Block further unveil calls.
unveil() or
die "Unable to lock unveil: $!";
# Decode $file_data to $json_data.
my $json_data = decode_json($file_data);
# Get statewise information.
my $statewise = $json_data->{statewise};
# Map month number to Months.
my @months = qw( lol Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my $rows = [
['State', 'Confirmed', 'Active', 'Recovered', 'Deaths', 'Last Updated'],
];
my $today = DateTime->now( time_zone => 'Asia/Kolkata' );
# Add first 37 entries to $rows.
foreach my $i (0...37) {
my $update_info;
my $lastupdatedtime = $statewise->[$i]{'lastupdatedtime'};
my $last_update_dmy = substr( $lastupdatedtime, 0, 10 );
# Add $update_info.
if ( $last_update_dmy eq $today->dmy('/') ) {
$update_info = "Today";
} elsif ( $last_update_dmy eq
$today->clone->subtract( days => 1 )->dmy('/') ) {
$update_info = "Yesterday";
} elsif ( $last_update_dmy eq
$today->clone->add( days => 1 )->dmy('/') ) {
$update_info = "Tomorrow"; # Hopefully we don't see this.
} else {
$update_info =
$months[substr( $lastupdatedtime, 3, 2 )] .
" " .
substr( $lastupdatedtime, 0, 2 );
}
my $state = $statewise->[$i]{'state'};
$state = "India" if
$state eq "Total";
$state = $statewise->[$i]{'statecode'} if
length($state) > 16;
push @$rows, [
$state,
"$statewise->[$i]{'confirmed'} (+$statewise->[$i]{'deltaconfirmed'})" ,
$statewise->[$i]{'active'},
"$statewise->[$i]{'recovered'} (+$statewise->[$i]{'deltadeaths'})",
"$statewise->[$i]{'deaths'} (+$statewise->[$i]{'deltarecovered'})",
$update_info,
];
}
# Generate table.
say generate_table(rows => $rows, header_row => 1);
|