13
13
namespace Omines \AntiSpamBundle \Command ;
14
14
15
15
use Omines \AntiSpamBundle \AntiSpam ;
16
+ use Omines \AntiSpamBundle \Utility \StringCounter ;
16
17
use Symfony \Component \Console \Attribute \AsCommand ;
17
18
use Symfony \Component \Console \Command \Command ;
19
+ use Symfony \Component \Console \Helper \Table ;
20
+ use Symfony \Component \Console \Helper \TableCell ;
18
21
use Symfony \Component \Console \Input \InputInterface ;
22
+ use Symfony \Component \Console \Input \InputOption ;
19
23
use Symfony \Component \Console \Output \OutputInterface ;
20
24
use Symfony \Component \Finder \Finder ;
21
25
use Symfony \Component \Yaml \Yaml ;
@@ -31,6 +35,7 @@ public function __construct(private readonly AntiSpam $antiSpam)
31
35
protected function configure (): void
32
36
{
33
37
$ this
38
+ ->addOption ('limit ' , 'l ' , InputOption::VALUE_OPTIONAL , 'Number of results to show in rankings. Defaults to number of days in quarantine. ' )
34
39
->setHelp (<<<'EOF'
35
40
The <info>%command.name%</info> command lists general statistics from the file based anti-spam quarantine.
36
41
@@ -49,27 +54,59 @@ protected function execute(InputInterface $input, OutputInterface $output)
49
54
return self ::FAILURE ;
50
55
}
51
56
52
- $ output ->writeln (sprintf ('<info>Gathering data from quarantine folder at %s</info> ' , $ config ['dir ' ]));
57
+ $ output ->writeln (sprintf ('<info>Analyzing data from quarantine folder at %s</info> ' , $ config ['dir ' ]));
58
+
59
+ $ limit = $ input ->getOption ('limit ' );
60
+ $ limit = (is_string ($ limit ) ? intval ($ limit ) : 0 ) ?: $ config ['max_days ' ] ?: 25 ;
53
61
54
62
$ finder = (new Finder ())
55
63
->files ()
56
64
->name ('*.yaml ' )
57
65
->in ($ config ['dir ' ])
66
+ ->sortByName ()
58
67
;
68
+
69
+ $ ips = new StringCounter ();
70
+ $ causes = new StringCounter ();
71
+ $ dates = new StringCounter ();
59
72
foreach ($ finder as $ file ) {
60
73
$ items = Yaml::parse ($ file ->getContents ());
61
74
if (!is_array ($ items )) {
62
75
$ output ->writeln (sprintf ('<error>Quarantine file %s is corrupted and could not be read</error> ' , $ file ->getFilename ()));
63
76
continue ;
64
77
}
65
78
foreach ($ items as $ item ) {
66
- $ output ->writeln ('' );
67
- $ output ->writeln (sprintf ('<info>Time:</info> %s ' , $ item ['time ' ]));
68
- $ output ->writeln (sprintf ('<info>Message:</info> %s ' , $ item ['antispam ' ][0 ]['message ' ]));
69
- $ output ->writeln (sprintf ('<info>Cause:</info> %s ' , $ item ['antispam ' ][0 ]['cause ' ]));
79
+ if (array_key_exists ('request ' , $ item )) {
80
+ $ ips ->add ($ item ['request ' ]['client_ip ' ]);
81
+ }
82
+ $ dates ->add ((new \DateTimeImmutable ($ item ['time ' ]))->format ('Y-m-d ' ));
83
+ $ causes ->add ($ item ['antispam ' ][0 ]['cause ' ]);
70
84
}
71
85
}
72
86
87
+ $ table = new Table ($ output );
88
+ $ table ->setHeaders ([
89
+ [new TableCell ('By date ' , ['colspan ' => 2 ]), new TableCell ('By IP ' , ['colspan ' => 2 ]), new TableCell ('By cause ' , ['colspan ' => 2 ])],
90
+ ['Date ' , '# ' , 'IP ' , '# ' , 'Cause ' , '# ' ],
91
+ ]);
92
+
93
+ $ dates = $ dates ->getScores ();
94
+ $ ips = $ ips ->getRanking ($ limit );
95
+ $ causes = $ causes ->getRanking ($ limit );
96
+ $ max = max (count ($ dates ), count ($ ips ), count ($ causes ));
97
+
98
+ for ($ i = 0 ; $ i < $ max ; ++$ i ) {
99
+ @$ table ->addRow ([
100
+ $ dates [$ i ][0 ],
101
+ $ dates [$ i ][1 ],
102
+ $ ips [$ i ][0 ],
103
+ $ ips [$ i ][1 ],
104
+ $ causes [$ i ][0 ],
105
+ $ causes [$ i ][1 ],
106
+ ]);
107
+ }
108
+ $ table ->render ();
109
+
73
110
return self ::SUCCESS ;
74
111
}
75
112
}
0 commit comments