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
|
use Terminal::Table;
use Terminal::Spinners;
# Parses the WhatsApp logs.
grammar WhatsApp {
token TOP {
|| <Text>
|| <Notice>
}
token Notice { <date> ', ' <time> ' - ' <message> }
token Text { <date> ', ' <time> ' - ' <name> ': ' <message> }
token date { (\d+) ** 3 % '/' }
token time { (\d+) ** 2 % ':' }
token name { [[\w|\s]+ | '+' \d+ [\d+|\s]+] }
token number { '+' \d+ [\d+|\s]+ }
token message { .* }
}
#| parses WhatsApp export
sub MAIN (
Str $profile-name = "Andinus", #= WhatsApp profile name
Str $input where *.IO.f = "input", #= input log file to parse
) {
my WhatsApp @logs;
{
my $bar = Bar.new: :type<equals>;
$bar.show: 0;
my Int $count = 0;
my Int $total = $input.IO.lines.elems; # Roughly the number of messages.
my Int $interval = $total div 40; # Interval for update.
@logs = gather for $input.IO.lines -> $line {
if WhatsApp.parse($line) -> $m { take $m }
$bar.show: $count / $total * 100 if $count++ %% $interval;
}
$bar.show: 100;
put "\n" ~ "Parsed {@logs.elems} logs in " ~ (now - ENTER now) ~ "s";
}
{
my @data;
my @given-data;
push @data, <Name Messages Words Deleted Media MostActiveHour Left>;
push @given-data, <Name FucksGiven>;
for @logs.grep(*<Text>).map(*<Text>).map(*<name>.Str).unique -> $name {
with @logs.grep(*<Text>).map(*<Text>).grep(*<name>.Str eq $name) {
@data.push(
(
$name,
.elems.Str,
.map(*<message>.words).sum.Str,
.grep(*<message> eq "You deleted this message"|"This message was deleted").elems.Str,
.grep(*<message> eq "<Media omitted>").elems.Str,
.map(*<time>[0][0].Int).Bag.max(*.values).key.Str,
$name eq $profile-name
?? @logs.grep(*<Notice>).grep(*<Notice><message> eq "You left").elems.Str
!! @logs.grep(*<Notice>).grep(*<Notice><message> eq "{$name} left").elems.Str,
)
);
@given-data.push(
(
$name,
.grep(*<message>.lc.contains("fuck")).elems.Str,
)
);
}
}
put "Generated data in " ~ (now - ENTER now) ~ "s";
print-table(@data, :style<single>);
print-table(@given-data, :style<single>);
}
}
|