diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | README | 296 | ||||
-rw-r--r-- | README.org | 219 |
3 files changed, 297 insertions, 219 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..143d814 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.org diff --git a/README b/README new file mode 100644 index 0000000..bfe34bc --- /dev/null +++ b/README @@ -0,0 +1,296 @@ + ━━━━━━━━━ + ARA + + Andinus + ━━━━━━━━━ + + +Table of Contents +───────────────── + +1 Documentation +.. 1.1 Options +.. 1.2 Cross-platform compatibility +2 Demo Videos + + +Ara is a simple cli program that prints Covid-19 stats. Currently it +only prints India's Covid stats. + + +1 Documentation +═══════════════ + + `ara' by default will first look for the file in `$XDG_CACHE_HOME', if + that is not set then `HOME/.cache' is used, the file name is assumed + to be `ara.json', there is currently no option to override this or the + full path. + + If you run `ara' on OpenBSD then it should use `OpenBSD::Unveil'. + + Default logic is to check if the file is available locally & if it's + not older than 8 minutes, in any other case it fetches the latest + data. This can be controlled with `local' & `latest' option. + + The file is downloaded over a secure connection & the server's + identity is verified. + + +1.1 Options +─────────── + +1.1.1 local +╌╌╌╌╌╌╌╌╌╌╌ + + This option forces `ara' to use the data available locally, it will + only override this option when the file doesn't exist on disk. + + +1.1.2 latest +╌╌╌╌╌╌╌╌╌╌╌╌ + + This will force `ara' to fetch the latest data. + + *Note*: `local' & `latest' option cannot be used together, `ara' will + print a warning & latest option will be ignored. + + +1.1.3 notes +╌╌╌╌╌╌╌╌╌╌╌ + + Only state notes will be printed if this option is passed. + + +1.1.4 rows +╌╌╌╌╌╌╌╌╌╌ + + `rows' option takes an integer as argument which can be passed as + `--rows n', where `n' is an integer. + + `ara' will only print maximum these many number of rows, if you pass 0 + or a negative number then `ara' will ignore it & print all the rows. + + +1.1.5 showdelta +╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ + + This will show delta values for every row, default is to show delta + only on rows that were updated "Today". + + +1.1.6 nodelta +╌╌╌╌╌╌╌╌╌╌╌╌╌ + + This will remove delta values from every column. + + +1.1.7 nototal +╌╌╌╌╌╌╌╌╌╌╌╌╌ + + This will remove the "Total" or "India" row from the table. + + `hide' option should be used for this purpose, this option is only + kept for backwards compatibility. + + +1.1.8 nowords +╌╌╌╌╌╌╌╌╌╌╌╌╌ + + "Confirmed", "Recovered" & "Deaths" column format numbers in words. + For example, "1.6 lakhs" instead of "1,60,000" which makes it easier + to read. This option will disable this behaviour. + + "Active" column doesn't format numbers in words because it's alignment + is set as "right" & formatting it this way doesn't look good. There is + currently no option to change this behaviour. + + +1.1.9 hide +╌╌╌╌╌╌╌╌╌╌ + + `hide' is able to hide states & columns from the table, the values + should be space seperated like `--hide active "last updated" + recovered'. These are case sensitive & should be lowercase. + + Arguments can be passed as they're printed, for example `--hide "jammu + and kashmir"' is equivalent to `--hide jk' because "JK" is what's + printed on the table. + + Only "States" & "Notes" column cannot be hidden, `ara' will print a + warning if you try to do so. + + *Note*: "updated" is aliased to "last updated", so you can pass + `--hide updated' & it would hide the "last updated" column. + + *Note*: The feature to get space seperated values is marked as + experimental in `Getopt::Long' so the behaviour can change in future, + worse even get removed. To guarantee backwards compatibility pass each + value by itself like `--hide jk --hide active', this is equivalent to + `--hide jk active'. + + +◊ 1.1.9.1 Implementation + + `%hide' hash is created from `@to_hide' which was created from user + arguments by `Getopt::Long'. + + ┌──── + │ undef @hide{ @to_hide } + │ if scalar @to_hide; + └──── + + `%hide' contains values of `@to_hide' as keys & the value to those + keys is not defined, hence `undef'. This one line says Perl to "undef + these keys from the hash `%hide'" where these refers to the values of + `@to_hide'. This will fail if `@to_hide' is empty so we have to check + for that. + + Alternatively we can do `@hide { @to_hide } = ()' which works even if + `@to_hide' is empty & does the same thing otherwise, this looks more + cryptic so I use the first way. + + To check if a specific column is to be hidden or not we use `exists' + like `exists $hide{something}'. + + There are other ways of doing this & maybe those would be better, I + didn't test which one was the best. + + + ◊ 1.1.9.1.1 Columns + + To make `hide' work we put create `@columns' & push columns to it + unless the user has asked to hide it. + ┌──── + │ my @columns; + │ + │ push @columns, 'Confirmed' unless exists $hide{confirmed}; + │ push @columns, 'Active' unless exists $hide{active}; + └──── + + + ◊ 1.1.9.1.2 States + + The whole block is skipped if the user has asked to hide the state. + As said above, statecode is also check if that's what is printed in + the table which is true only if `length $state > 16'. There is no + good reason for not checking statecode for everything. + ┌──── + │ next + │ if exists $hide{lc $state} + │ # User sees the statecode if length $state > 16 so we also match + │ # against that. + │ or ( length $state > 16 + │ and exists $hide{lc $statewise->[$i]{statecode}}); + └──── + + +1.1.10 show +╌╌╌╌╌╌╌╌╌╌╌ + + `show' also accepts space seperated values & just like in `hide''s + case it's experimental & can change in future. + + `show' will only show states that are passed. For example, `--show jk' + will only print data for Jammu & Kashmir. If both `show' & `hide' is + used for states then `hide' is ignored. `show' for states can be used + with `hide' for columns. + + +◊ 1.1.10.1 Implementation + + `show''s implementation is similar to `hide''s. `%show' hash is + created from `@to_show'. + + ┌──── + │ undef @show{ @to_show } + │ if scalar @to_show; + └──── + + If user has used `show' then `hide' is ignored, this is achieved by an + if-else block. This also means that invalid values in state would + cause `hide' to be ignored, for example passing `--show invalid' + wouldn't match anything but `hide' will still be ignored. This is + intentional. + + ┌──── + │ if ( scalar @to_show ) { + │ next + │ unless exists $show{lc $state} + │ or ( length $state > 16 + │ and exists $show{lc $statewise->[$i]{statecode}}); + │ } else { ... } + └──── + + +1.1.11 help +╌╌╌╌╌╌╌╌╌╌╌ + + `help' will print help for `ara' which will have little information + about all these options listed above. + + • `nototal' was removed from `help' because `hide' option does the + same thing & is recommended. + + +1.2 Cross-platform compatibility +──────────────────────────────── + + Previously `ara' had OpenBSD specific code & would simply fail to run + on other OSes, now it runs on all platforms. There is still OpenBSD + specific code but it's used only when `ara' detects to be running on + OpenBSD. + + ┌──── + │ use constant is_OpenBSD => $^O eq "openbsd"; + │ require OpenBSD::Unveil + │ if is_OpenBSD; + │ sub unveil { + │ if (is_OpenBSD) { + │ return OpenBSD::Unveil::unveil(@_); + │ } else { + │ return 1; + │ } + │ } + └──── + + `is_OpenBSD' is a constant so the if-else block is optimized at + compile time. Another way would be to define the sub inside the + if-else block which is what I did initially but that is not the same + thing as this. + + You cannot define sub like that in Perl because this step happens at + compile time & so the if-else block is ignored, which means the code + will be equivalent to else block being true all the time because + that's what comes later. + + ┌──── + │ if (is_OpenBSD) { + │ require OpenBSD::Unveil; + │ OpenBSD::Unveil->import; + │ } else { + │ sub unveil { return 1; } + │ } + └──── + + Above code block will override the unveil sub to be `return 1;' + everytime, this was fixed in commit + `245aebe3da915afc0feafc7257f025e2e66a987f'. + + This will still fail on OpenBSD if users don't have `OpenBSD::Unveil' + in `@INC', this shouldn't be an issue with Perl in base but if user + runs custom Perl then it might not be in `@INC', in that case user is + expected to fix this by adding the path to `OpenBSD::' in `@INC'. + + +2 Demo Videos +═════════════ + + • [Ara 2020-06-14] (new options) + • [Ara 2020-06-06] + + +[Ara 2020-06-14] +https://diode.zone/videos/watch/95868534-8aae-497b-806e-5766236bb058 + +[Ara 2020-06-06] +https://diode.zone/videos/watch/03be044d-6ab7-4f01-8769-0084674dec93 diff --git a/README.org b/README.org deleted file mode 100644 index 0e83ccf..0000000 --- a/README.org +++ /dev/null @@ -1,219 +0,0 @@ -#+HTML_HEAD: <link rel="stylesheet" href="../static/style.css"> -#+HTML_HEAD: <link rel="icon" href="../static/favicon.png" type="image/png"> -#+EXPORT_FILE_NAME: index -#+TITLE: Ara - -Ara is a simple cli program that prints Covid-19 stats. Currently it -only prints India's Covid stats. - -| Project Home | [[https://andinus.nand.sh/ara/][Ara]] | -| Source Code | [[https://git.tilde.institute/andinus/ara/][Andinus / Ara]] | -| GitHub (Mirror) | [[https://github.com/andinus/ara/][Ara - GitHub]] | - -*Tested on*: -- OpenBSD 6.7 - - Perl v5.30 - -*Note* (OpenBSD users): If you're using a custom Perl install then add the -path to =OpenBSD::= in @INC. - -| Demo Videos | -|----------------| -| [[https://diode.zone/videos/watch/95868534-8aae-497b-806e-5766236bb058][Ara 2020-06-14]] | -| [[https://diode.zone/videos/watch/03be044d-6ab7-4f01-8769-0084674dec93][Ara 2020-06-06]] | - -* Documentation -=ara= by default will first look for the file in =$XDG_CACHE_HOME=, if that -is not set then =HOME/.cache= is used, the file name is assumed to be -=ara.json=, there is currently no option to override this or the full -path. - -If you run =ara= on OpenBSD then it should use =OpenBSD::Unveil=. - -Default logic is to check if the file is available locally & if it's not -older than 8 minutes, in any other case it fetches the latest data. This -can be controlled with =local= & =latest= option. - -The file is downloaded over a secure connection & the server's identity -is verified. -** Options -*** local -This option forces =ara= to use the data available locally, it will only -override this option when the file doesn't exist on disk. -*** latest -This will force =ara= to fetch the latest data. - -*Note*: =local= & =latest= option cannot be used together, =ara= will print a -warning & latest option will be ignored. -*** notes -Only state notes will be printed if this option is passed. -*** rows -=rows= option takes an integer as argument which can be passed as =--rows -n=, where =n= is an integer. - -=ara= will only print maximum these many number of rows, if you pass 0 or -a negative number then =ara= will ignore it & print all the rows. -*** showdelta -This will show delta values for every row, default is to show delta only -on rows that were updated "Today". -*** nodelta -This will remove delta values from every column. -*** nototal -This will remove the "Total" or "India" row from the table. - -=hide= option should be used for this purpose, this option is only kept -for backwards compatibility. -*** nowords -"Confirmed", "Recovered" & "Deaths" column format numbers in words. For -example, "1.6 lakhs" instead of "1,60,000" which makes it easier to -read. This option will disable this behaviour. - -"Active" column doesn't format numbers in words because it's alignment -is set as "right" & formatting it this way doesn't look good. There is -currently no option to change this behaviour. -*** hide -=hide= is able to hide states & columns from the table, the values should -be space seperated like =--hide active "last updated" recovered=. These -are case sensitive & should be lowercase. - -Arguments can be passed as they're printed, for example =--hide "jammu -and kashmir"= is equivalent to =--hide jk= because "JK" is what's printed -on the table. - -Only "States" & "Notes" column cannot be hidden, =ara= will print a -warning if you try to do so. - -*Note*: "updated" is aliased to "last updated", so you can pass =--hide -updated= & it would hide the "last updated" column. - -*Note*: The feature to get space seperated values is marked as -experimental in =Getopt::Long= so the behaviour can change in future, -worse even get removed. To guarantee backwards compatibility pass each -value by itself like =--hide jk --hide active=, this is equivalent to -=--hide jk active=. - -**** Implementation -=%hide= hash is created from =@to_hide= which was created from user -arguments by =Getopt::Long=. - -#+BEGIN_SRC perl -undef @hide{ @to_hide } - if scalar @to_hide; -#+END_SRC - -=%hide= contains values of =@to_hide= as keys & the value to those keys is -not defined, hence =undef=. This one line says Perl to "undef these keys -from the hash =%hide=" where these refers to the values of =@to_hide=. This -will fail if =@to_hide= is empty so we have to check for that. - -Alternatively we can do =@hide { @to_hide } = ()= which works even if -=@to_hide= is empty & does the same thing otherwise, this looks more -cryptic so I use the first way. - -To check if a specific column is to be hidden or not we use =exists= like -=exists $hide{something}=. - -There are other ways of doing this & maybe those would be better, I -didn't test which one was the best. -***** Columns -To make =hide= work we put create =@columns= & push columns to it unless the -user has asked to hide it. -#+BEGIN_SRC perl -my @columns; - -push @columns, 'Confirmed' unless exists $hide{confirmed}; -push @columns, 'Active' unless exists $hide{active}; -#+END_SRC -***** States -The whole block is skipped if the user has asked to hide the state. As -said above, statecode is also check if that's what is printed in the -table which is true only if =length $state > 16=. There is no good reason -for not checking statecode for everything. -#+BEGIN_SRC perl -next - if exists $hide{lc $state} - # User sees the statecode if length $state > 16 so we also match - # against that. - or ( length $state > 16 - and exists $hide{lc $statewise->[$i]{statecode}}); -#+END_SRC -*** show -=show= also accepts space seperated values & just like in =hide='s case it's -experimental & can change in future. - -=show= will only show states that are passed. For example, =--show jk= will -only print data for Jammu & Kashmir. If both =show= & =hide= is used for -states then =hide= is ignored. =show= for states can be used with =hide= for -columns. -**** Implementation -=show='s implementation is similar to =hide='s. =%show= hash is created from -=@to_show=. - -#+BEGIN_SRC perl -undef @show{ @to_show } - if scalar @to_show; -#+END_SRC - -If user has used =show= then =hide= is ignored, this is achieved by an -if-else block. This also means that invalid values in state would cause -=hide= to be ignored, for example passing =--show invalid= wouldn't match -anything but =hide= will still be ignored. This is intentional. - -#+BEGIN_SRC perl -if ( scalar @to_show ) { - next - unless exists $show{lc $state} - or ( length $state > 16 - and exists $show{lc $statewise->[$i]{statecode}}); -} else { ... } -#+END_SRC -*** help -=help= will print help for =ara= which will have little information about -all these options listed above. - -- =nototal= was removed from =help= because =hide= option does the same thing - & is recommended. -** Cross-platform compatibility -Previously =ara= had OpenBSD specific code & would simply fail to run on -other OSes, now it runs on all platforms. There is still OpenBSD -specific code but it's used only when =ara= detects to be running on -OpenBSD. - -#+BEGIN_SRC perl -use constant is_OpenBSD => $^O eq "openbsd"; -require OpenBSD::Unveil - if is_OpenBSD; -sub unveil { - if (is_OpenBSD) { - return OpenBSD::Unveil::unveil(@_); - } else { - return 1; - } -} -#+END_SRC - -=is_OpenBSD= is a constant so the if-else block is optimized at compile -time. Another way would be to define the sub inside the if-else block -which is what I did initially but that is not the same thing as this. - -You cannot define sub like that in Perl because this step happens at -compile time & so the if-else block is ignored, which means the code -will be equivalent to else block being true all the time because that's -what comes later. - -#+BEGIN_SRC perl -if (is_OpenBSD) { - require OpenBSD::Unveil; - OpenBSD::Unveil->import; -} else { - sub unveil { return 1; } -} -#+END_SRC - -Above code block will override the unveil sub to be =return 1;= everytime, -this was fixed in commit =245aebe3da915afc0feafc7257f025e2e66a987f=. - -This will still fail on OpenBSD if users don't have =OpenBSD::Unveil= in -=@INC=, this shouldn't be an issue with Perl in base but if user runs -custom Perl then it might not be in =@INC=, in that case user is expected -to fix this by adding the path to =OpenBSD::= in =@INC=. |