Adding stats view.
This commit is contained in:
parent
c152abc0e6
commit
5c5fa005e5
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"secrets": ["secret_change_for_pwgen_generated_one_with_at_least 255 chars"],
|
||||||
|
"bcrypt_pass_stats": ["change_for_bcrypted_password"],
|
||||||
"db": {
|
"db": {
|
||||||
"database": "example"
|
"database": "example"
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ sub startup ($self) {
|
|||||||
my $config = $self->plugin('JSONConfig');
|
my $config = $self->plugin('JSONConfig');
|
||||||
$self->config(
|
$self->config(
|
||||||
hypnotoad => { proxy => 1, listen => ['http://localhost:3000'] } );
|
hypnotoad => { proxy => 1, listen => ['http://localhost:3000'] } );
|
||||||
|
$self->secrets($self->config->{secrets});
|
||||||
|
|
||||||
# Router
|
# Router
|
||||||
my $r = $self->routes;
|
my $r = $self->routes;
|
||||||
@ -28,10 +29,13 @@ sub startup ($self) {
|
|||||||
$r->get('/')->to('Page#index');
|
$r->get('/')->to('Page#index');
|
||||||
|
|
||||||
# $r->get('/:post')->to('Page#post');
|
# $r->get('/:post')->to('Page#post');
|
||||||
|
$r->get('/stats')->to('Metrics#stats');
|
||||||
$r->get('/<:category>.rss')->to('Page#category_rss');
|
$r->get('/<:category>.rss')->to('Page#category_rss');
|
||||||
$r->get('/:category')->to('Page#category');
|
$r->get('/:category')->to('Page#category');
|
||||||
$r->get('/posts/<:slug>-preview.png')->to('Page#get_post_preview');
|
$r->get('/posts/<:slug>-preview.png')->to('Page#get_post_preview');
|
||||||
$r->get('/posts/:slug')->to('Page#post');
|
$r->get('/posts/:slug')->to('Page#post');
|
||||||
|
$r->get('/stats/login')->to('Metrics#login');
|
||||||
|
$r->post('/stats/login')->to('Metrics#submit_login');
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -13,8 +13,11 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||||||
|
|
||||||
use DateTime::Format::ISO8601;
|
use DateTime::Format::ISO8601;
|
||||||
use DateTime::Format::Mail;
|
use DateTime::Format::Mail;
|
||||||
|
use Crypt::Bcrypt qw/bcrypt bcrypt_check/;
|
||||||
|
|
||||||
my $tracking;
|
my $tracking;
|
||||||
|
|
||||||
|
my $iso8601 = DateTime::Format::ISO8601->new;
|
||||||
sub request {
|
sub request {
|
||||||
shift;
|
shift;
|
||||||
my $c = shift;
|
my $c = shift;
|
||||||
@ -24,4 +27,80 @@ sub request {
|
|||||||
}
|
}
|
||||||
$tracking->register_request($c);
|
$tracking->register_request($c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub stats {
|
||||||
|
my $self = shift;
|
||||||
|
if (!$self->valid_login) {
|
||||||
|
$self->res->headers->location('/stats/login');
|
||||||
|
$self->render(text => 'You must login', status => 302);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $data = $tracking->get_global_data($self);
|
||||||
|
$self->render(tracking_data => $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub submit_login {
|
||||||
|
my $self = shift;
|
||||||
|
if ($self->valid_login) {
|
||||||
|
$self->res->headers->location('/stats');
|
||||||
|
$self->render(text => 'Already logged in.', status => 302);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $password = $self->param('password');
|
||||||
|
if (!defined $password) {
|
||||||
|
$self->render(text => 'No password passed.', status => 400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $bcrypted_pass = $self->config->{bcrypt_pass_stats};
|
||||||
|
if (!defined $bcrypted_pass) {
|
||||||
|
warn "No bcrypt pass.";
|
||||||
|
$self->render(text => 'Server error.', status => 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
say $password;
|
||||||
|
say $bcrypted_pass;
|
||||||
|
if (!bcrypt_check( $password, $bcrypted_pass )) {
|
||||||
|
$self->render(text => 'Wrong password', status => 401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
say STDERR 'Login success.';
|
||||||
|
my $expiration_date = DateTime->now->add( days => 1);
|
||||||
|
$self->session->{login} = "date_end_login:$expiration_date";
|
||||||
|
$self->res->headers->location('/stats');
|
||||||
|
$self->render(text => 'Login success.', status => 302);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub valid_login {
|
||||||
|
my $self = shift;
|
||||||
|
my $login_cookie = $self->session->{login};
|
||||||
|
if (!defined $login_cookie) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($date_text) = $login_cookie =~ /^date_end_login:(.*)$/;
|
||||||
|
my $date;
|
||||||
|
eval {
|
||||||
|
$date = $iso8601->parse_datetime($date_text);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
warn "Bad date in cookie $login_cookie.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my $current_date = DateTime->now();
|
||||||
|
if ($current_date > $date) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub login {
|
||||||
|
my $self = shift;
|
||||||
|
if ($self->valid_login) {
|
||||||
|
$self->res->headers->location('/stats');
|
||||||
|
$self->render(text => 'You are already logged in.', status => 302);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$self->render;
|
||||||
|
}
|
||||||
1;
|
1;
|
||||||
|
@ -37,4 +37,35 @@ EOF
|
|||||||
say "Registered $remote_address with user agent $user_agent visited $path with $params_json";
|
say "Registered $remote_address with user agent $user_agent visited $path with $params_json";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_global_data {
|
||||||
|
my $self = shift;
|
||||||
|
my $c = shift;
|
||||||
|
my $app = $c->app;
|
||||||
|
my $dbh = BurguillosInfo::DB->connect($app);
|
||||||
|
my $data = $dbh->selectrow_hashref(<<'EOF', undef);
|
||||||
|
SELECT
|
||||||
|
(
|
||||||
|
SELECT COUNT(DISTINCT remote_address) FROM requests
|
||||||
|
) as unique_ips,
|
||||||
|
(
|
||||||
|
SELECT COUNT(DISTINCT remote_address)
|
||||||
|
FROM requests
|
||||||
|
where date > NOW() - interval '1 day'
|
||||||
|
) as unique_ips_last_24_hours,
|
||||||
|
(
|
||||||
|
SELECT COUNT(DISTINCT remote_address)
|
||||||
|
FROM requests
|
||||||
|
where date > NOW() - interval '1 week'
|
||||||
|
) as unique_ips_last_week,
|
||||||
|
(
|
||||||
|
SELECT COUNT(DISTINCT remote_address)
|
||||||
|
FROM requests
|
||||||
|
where date > NOW() - interval '1 month'
|
||||||
|
) as unique_ips_last_month;
|
||||||
|
|
||||||
|
|
||||||
|
EOF
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -79,6 +79,9 @@ body {
|
|||||||
font-size: 60px;
|
font-size: 60px;
|
||||||
}
|
}
|
||||||
div.description {
|
div.description {
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
div.suscribirse-rss {
|
div.suscribirse-rss {
|
||||||
img {
|
img {
|
||||||
|
16
templates/layouts/stats.html.ep
Normal file
16
templates/layouts/stats.html.ep
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="/css/styles.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="site-wrapper">
|
||||||
|
</div>
|
||||||
|
<div class="page-contents">
|
||||||
|
<nav class="desktop">
|
||||||
|
<a href="/stats"><img class="index-image-menu" src="/img/burguillos.png"</img></a>
|
||||||
|
</nav>
|
||||||
|
<%= content %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
8
templates/metrics/login.html.ep
Normal file
8
templates/metrics/login.html.ep
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
% layout 'stats';
|
||||||
|
<div class="description">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form enctype="application/json" method="post" action="/stats/login">
|
||||||
|
<input name="password" placeholder="Password" type="password"/>
|
||||||
|
<input type="submit" value="login">
|
||||||
|
</form>
|
||||||
|
</div>
|
9
templates/metrics/stats.html.ep
Normal file
9
templates/metrics/stats.html.ep
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
% layout 'stats';
|
||||||
|
<div class="description">
|
||||||
|
<h2>Stats</h2>
|
||||||
|
|
||||||
|
<p>Unique visitors <%=$tracking_data->{unique_ips}%></p>
|
||||||
|
<p>Unique visitors last 24 hours <%=$tracking_data->{unique_ips_last_24_hours}%></p>
|
||||||
|
<p>Unique visitors last week <%=$tracking_data->{unique_ips_last_week}%></p>
|
||||||
|
<p>Unique visitors last month <%=$tracking_data->{unique_ips_last_month}%></p>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user