root/veekun/trunk/lib/Vee/Controller/Users/Stats.pm @ 406

Revision 406, 2.8 KB (checked in by eevee, 22 months ago)

Database refactoring. Renamed columns and tables to be more consistent and more readable. (#58)

Line 
1package Vee::Controller::Users::Stats;
2
3use strict;
4use warnings;
5use base 'Catalyst::Controller';
6
7use List::Util qw/sum/;
8use Vee::Utils::SVG;
9
10=head1 NAME
11
12Vee::Controller::Users - Statistics controller
13
14=head1 SYNOPSIS
15
16See L<Vee>
17
18=head1 DESCRIPTION
19
20Catalyst Controller for dealing with user-based statistics.  Includes forum
21stats as well, since the forum is inherently user-based.
22
23These are grouped together primarily because a lot of the generated charts are
24their own SVG files included by <object> tags.
25
26=head1 METHODS
27
28=cut
29
30=head2 index
31
32=cut
33
34sub index : Path {
35    my ($self, $c) = @_;
36    my $s = $c->stash;
37
38    $s->{page_title} = 'User Statistics';
39    $s->{extra_css}  = 'users';
40    $s->{template}   = 'users/stats.tt';
41}
42
43=head2 top_posters
44
45Returns an SVG pie chart of the top ten posters and the remaining bulk of posts.
46
47=cut
48
49sub top_posters : Path('top-posters.svg') {
50    my ($self, $c) = @_;
51
52    $c->res->content_type('image/svg+xml');
53
54    my $posters_rs = $c->model('DBIC::Users')->search({
55        post_count => { '!=', 0 },
56    }, {
57        order_by   => 'post_count DESC',
58        rows       => 10,
59        columns    => [qw[ name post_count ]],
60    });
61    # TODO: when we figure out what "counts" as a post, adjust this to compensate
62    my $total_posts = $c->model('DBIC::Posts')->count;
63
64    my @fields = $posters_rs->get_column('name')->all;
65    my @data   = $posters_rs->get_column('post_count')->all;
66    my $top_total = sum @data;
67    if ($total_posts > $top_total) {
68        push @fields, 'Everyone else';
69        push @data,   $total_posts - $top_total;
70    }
71   
72    $c->res->body( Vee::Utils::SVG::piechart(\@fields, \@data) );
73}
74
75=head2 loudmouths
76
77Returns an SVG pie chart of the top ten shoutbox posters and the remaining bulk
78of shouts.
79
80=cut
81
82sub loudmouths : Path('loudmouths.svg') {
83    my ($self, $c) = @_;
84
85    $c->res->content_type('image/svg+xml');
86
87    my $loudmouths_rs = $c->model('DBIC::Shoutbox')->search(undef, {
88        group_by  => 'user_id',
89        '+select' => \'COUNT(*) AS shout_count',
90        '+as'     => 'shout_count',
91        order_by  => 'shout_count DESC',
92        rows      => 10,
93        columns   => [qw[ user.name ]],
94        join      => 'user',
95    });
96    my $total_shouts = $c->model('DBIC::Shoutbox')->count;
97
98    my @fields = map { $_->user->name                } $loudmouths_rs->all;
99    my @data   = map { $_->get_column('shout_count') } $loudmouths_rs->all;
100    my $top_total = sum @data;
101    if ($total_shouts > $top_total) {
102        push @fields, 'Everyone else';
103        push @data,   $total_shouts - $top_total;
104    }
105   
106    $c->res->body( Vee::Utils::SVG::piechart(\@fields, \@data) );
107}
108
109=head1 AUTHOR
110
111Maintainer: Alex "Eevee" Munroe (C<veekun@veekun.com>)
112
113See the included F<AUTHORS> file for a full list of contributers.
114
115=head1 LICENSE
116
117See the included F<LICENSE> file.
118
119=cut
120
1211;
Note: See TracBrowser for help on using the browser.