diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Taurus/CLI.rakumod | 141 |
1 files changed, 117 insertions, 24 deletions
diff --git a/lib/Taurus/CLI.rakumod b/lib/Taurus/CLI.rakumod index db6be9e..4647c1c 100644 --- a/lib/Taurus/CLI.rakumod +++ b/lib/Taurus/CLI.rakumod @@ -1,29 +1,122 @@ use CSV::Parser; -use Terminal::UI; -use Terminal::Spinners; -use Text::Table::Simple; +use Terminal::UI 'ui'; +use Terminal::ANSI::OO 't'; + +# If no arguments are passed then run USAGE & exit. +proto MAIN(|) is export {unless so @*ARGS {put $*USAGE; exit}; {*}} #| parses Call Logs -unit sub MAIN ( +multi sub MAIN ( Str $log where *.IO.f, #= input log file to parse UInt :$digits = 10, #= number of significant digits -); - -my @logs; -my Str %contacts{Str}; -Spinner.new(:type<bounce2>).await: Promise.start: { - my $p = CSV::Parser.new(); - # 0: Name, 1: Phone number, 2: Call Type, 3: Timestamp, - # 4: Duration, 5: Sim used. - - # Turn the Hash to an Array. - @logs = @($log.IO.lines.skip.hyper.map({$p.parse($_)})>>.{0..4} - # Discard invalid phone numbers. - .grep(*.[1].chars >= $digits)); - - # Discard non-significant digits from phone numbers. - .[1] = .[1].substr(*-10) for @logs; - - # Build contact list. - %contacts{.[1]} = .[0] for @logs.grep(*.[0].chars > 0); -}; +) is export { + my @logs; + my Str %contacts{Str}; + + my Instant $timed = now; + my Promise $initial = start { + my $p = CSV::Parser.new(); + # 0: Name, 1: Phone number, 2: Call Type, + # 3: Timestamp, 4: Duration, 5: Sim used. + + # Turn the Hash to an Array. + @logs = @($log.IO.lines.skip[^200].hyper.map({$p.parse($_)})>>.{0..4} + # Discard invalid phone numbers. + .grep(*.[1].chars >= $digits)); + + for @logs { + # Discard non-significant digits from phone numbers. + .[1] .= substr(*-10); + + # Removing leading/trailing whitespaces from names. + .[0] .= trim; + + # Build contact list. + %contacts{.[1]} = .[0] if .[0].chars > 0; + + # Store Duration in seconds. + .[4] = (.[4].split(":")[0] * 60) + .[4].split(":")[1]; + } + }; + + ui.setup: :2panes; + my $p0 = ui.panes[0]; + my $p1 = ui.panes[1]; + + $p0.put: t.bold ~ t.bg-cyan ~ t.black ~t.underline~ "Taurus v" ~ $?DISTRIBUTION.meta<version>; + $p0.put: ""; + + with ui.screen.add-frame(:4height, :40width, :center) -> $f { + with $f.add-pane -> $p { + $f.draw; + until $initial.status { + $p.splash: "Parsing logs" ~ (". ", ".. ", "...")[$++ % 3]; + sleep 0.8; + } + $p.splash: "Parsed {@logs.elems} entries in {now - $timed}s."; + $p.put: " " x 18 ~ "Ok"; + $p.select-last; + ui.focus($f); + } + ui.get-key; + ui.screen.remove-frame($f); + ui.focus($f); + } + ui.refresh; + + $p0.put: "- Show Records", :meta(:all); + $p0.put: ""; + # First list Contacts, then sorted phone numbers. + for @logs.race.map(*.[1]).unique.sort({%contacts{$_} // "Z", $_}) { + $p0.put: "- " ~ $_ ~ " {%contacts{$_} // ''}", :meta(:number($_)); + } + + $p1.clear; + $p0.select-first; + $p0.select(2); + $p0.on: select => -> :%meta { + if %meta<all> { + $p1.clear; + with @logs { + my Int $fmt = 16; + + my $outgoing = .grep(*.[2] eqv "Outgoing Call").map(*.[4]).sum; + my $incoming = .grep(*.[2] eqv "Incoming Call").map(*.[4]).sum; + + $p1.put: sprintf("%-*s", $fmt, "Outgoing:") ~ $outgoing / 3600 ~ " hours" ; + $p1.put: sprintf("%-*s", $fmt, "Incoming:") ~ $incoming / 3600 ~ " hours"; + $p1.put: sprintf("%-*s", $fmt, "Total:") ~ ($incoming + $outgoing) / 3600 ~ " hours"; + $p1.put: ""; + } + } elsif %meta<number> -> $num { + my Int $fmt = 18; + + $p1.clear; + $p1.put: "Name: " ~ $_ with %contacts{$num}; + $p1.put: "Number: " ~ $num; + $p1.put: ""; + with @logs.grep(*.[1] eqv $num).cache { + my $outgoing = .grep(*.[2] eqv "Outgoing Call").map(*.[4]).sum; + my $incoming = .grep(*.[2] eqv "Incoming Call").map(*.[4]).sum; + + $p1.put: sprintf("%-*s", $fmt, "Outgoing:") ~ $outgoing / 3600 ~ " hours"; + $p1.put: sprintf("%-*s", $fmt, "Incoming:") ~ $incoming / 3600 ~ " hours"; + $p1.put: sprintf("%-*s", $fmt, "Total:") ~ ($incoming + $outgoing) / 3600 ~ " hours"; + $p1.put: ""; + + $p1.put: sprintf("%-*s", $fmt, "Declined:") ~ .grep( + {$_.[2] eqv "Incoming Call" and $_.[4] == 0}).elems; + $p1.put: sprintf("%-*s", $fmt, "Declined (they):") ~ .grep( + {$_.[2] eqv "Outgoing Call" and $_.[4] == 0}).elems; + $p1.put: sprintf("%-*s", $fmt, "Missed Calls:") ~ .grep(*.[2] eqv "Missed Call").elems; + } + } + } + + ui.interact; + ui.shutdown; +} + +multi sub MAIN( + Bool :$version #= print version +) is export { put "Lacerta v" ~ $?DISTRIBUTION.meta<version>; } |