script-active-users 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/perl
  2. use local::lib;
  3. use v5.10;
  4. use strict;
  5. use warnings;
  6. use FindBin qw( $RealBin );
  7. use lib "$RealBin/lib";
  8. BEGIN {
  9. $ENV{TZ} = 'UTC';
  10. }
  11. use DateTime qw ();
  12. use LogBot::Config qw( find_config load_config );
  13. use LogBot::Database qw( dbh replace_sql_placeholders );
  14. use LogBot::Util qw( logbot_init );
  15. # dump a csv with a tallys of active users by channel
  16. # ./script-active-users <network> [minimum event count]
  17. # 'minimum event count' defaults to 1
  18. my $config = load_config(find_config(shift) || die "script-active-users <network> [minimum event count]\n");
  19. logbot_init(
  20. $config,
  21. name => 'script ',
  22. quiet => 1,
  23. );
  24. my $min_event_count = shift // 1;
  25. my $dbh = dbh($config);
  26. my $now = DateTime->now->truncate(to => 'month');
  27. my $start = $now->clone->subtract(months => 12);
  28. print 'channel,';
  29. each_date(
  30. sub {
  31. my ($date) = @_;
  32. print $date->format_cldr('MMM yyyy');
  33. print ',' unless $date == $now;
  34. }
  35. );
  36. print "\n";
  37. my @channels = @{
  38. $dbh->selectcol_arrayref('SELECT DISTINCT channel FROM logs WHERE time >= ? ORDER BY channel',
  39. undef, $start->epoch,)
  40. };
  41. unshift @channels, 'all';
  42. foreach my $channel (@channels) {
  43. print qq{"$channel",};
  44. each_date(
  45. sub {
  46. my ($date) = @_;
  47. my $sql = "
  48. SELECT COUNT(*)
  49. FROM (
  50. SELECT nick, count(*) AS events
  51. FROM logs
  52. WHERE {where}
  53. GROUP BY nick COLLATE NOCASE
  54. ) t
  55. WHERE events >= $min_event_count
  56. ";
  57. my @where;
  58. my @values;
  59. if ($channel ne 'all') {
  60. push @where, 'channel = ?';
  61. push @values, $channel;
  62. }
  63. push @where, 'time >= ?';
  64. push @values, $date->epoch;
  65. push @where, 'time < ?';
  66. push @values, $date->clone->add(months => 1)->epoch;
  67. my $where = '(' . join(') AND (', @where) . ')';
  68. $sql =~ s/\{where\}/$where/;
  69. say ' ', replace_sql_placeholders($dbh, $sql, \@values) if $ENV{DEBUG};
  70. my $count = $dbh->selectrow_array($sql, undef, @values,);
  71. print $count;
  72. print ',' unless $date == $now;
  73. }
  74. );
  75. print "\n";
  76. }
  77. sub each_date {
  78. my ($callback) = @_;
  79. my $date_iter = $start->clone;
  80. while ($date_iter <= $now) {
  81. $callback->($date_iter);
  82. $date_iter->add(months => 1);
  83. }
  84. }