From bedde37162475a8a76e561a17a4af0a5638d9f56 Mon Sep 17 00:00:00 2001 From: Andinus Date: Mon, 15 Jun 2020 03:07:58 +0530 Subject: Update README with documentation Some basic documentation, for more details look at logs. --- README.org | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/README.org b/README.org index 63b0bd7..c45c615 100644 --- a/README.org +++ b/README.org @@ -1,6 +1,5 @@ #+HTML_HEAD: #+HTML_HEAD: -#+OPTIONS: toc:nil #+EXPORT_FILE_NAME: index #+TITLE: Ara @@ -22,3 +21,193 @@ path to =OpenBSD::= in @INC. |----------------| | [[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. +*** 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. +** 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=. -- cgit 1.4.1-2-gfad0