This repository has been archived by the owner on Jan 14, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement monthly stats [closes #55]
This implements a fake model that aggregates statistics about badge issuances and exposes that information at `/admin/stats`. Right now the information given is low fidelity -- it only gives a total count of badges per month, not a breakdown of total per badge. We could improve upon this later if needed.
- Loading branch information
1 parent
0bd0576
commit 568333a
Showing
6 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const BadgeInstance = require('./badge-instance'); | ||
|
||
const Stats = {}; | ||
|
||
function isoMonthDay(date) { | ||
return date.toISOString().slice(0, 7); | ||
} | ||
|
||
Stats.monthly = function monthlyStats(callback) { | ||
const months = {}; | ||
BadgeInstance.find({}, function (err, instances) { | ||
if (err) return callback(err); | ||
instances.forEach(function (instance) { | ||
const month = isoMonthDay(instance.issuedOn); | ||
months[month] = (months[month] || 0) + 1; | ||
}); | ||
callback(null, months); | ||
}); | ||
}; | ||
|
||
module.exports = Stats; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const Stats = require('../models/stats'); | ||
|
||
exports.monthly = function monthly(req, res, next) { | ||
Stats.monthly(function (err, stats) { | ||
if (err) return next(err); | ||
const months = Object.keys(stats).map(function (month) { | ||
return { month: month, count: stats[month] }; | ||
}).reverse(); | ||
req.stats = months; | ||
return next(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
const test = require('./'); | ||
const db = require('../models'); | ||
const BadgeInstance = require('../models/badge-instance'); | ||
const Stats = require('../models/stats'); | ||
const util = require('../lib/util'); | ||
|
||
test.applyFixtures({ | ||
'instance': new BadgeInstance({ | ||
issuedOn: new Date('2012-10-15'), | ||
user: 'brian@example.org', | ||
hash: 'hash', | ||
badge: 'link-advanced', | ||
assertion: '{ "assertion" : "yep" }', | ||
}), | ||
'instance2': new BadgeInstance({ | ||
issuedOn: new Date('2012-11-15'), | ||
user: 'brian@example.org', | ||
hash: 'hash', | ||
badge: 'link-hyper-advanced', | ||
assertion: '{ "assertion" : "yep" }', | ||
}), | ||
'instance3': new BadgeInstance({ | ||
issuedOn: new Date('2012-12-15'), | ||
user: 'brian-delete@example.org', | ||
hash: 'hash', | ||
badge: 'link-hyper-advanced', | ||
assertion: '{ "assertion" : "yep" }', | ||
}), | ||
'instance4': new BadgeInstance({ | ||
issuedOn: new Date('2013-01-15'), | ||
user: 'brian-delete@example.org', | ||
hash: 'otherhash', | ||
badge: 'link-turbo-advanced', | ||
assertion: '{ "assertion" : "yep" }', | ||
}), | ||
'instance5': new BadgeInstance({ | ||
issuedOn: new Date('2013-01-16'), | ||
user: 'brian-delete@example.org', | ||
hash: 'otherhash', | ||
badge: 'link-mega-advanced', | ||
assertion: '{ "assertion" : "yep" }', | ||
}), | ||
}, function (fixtures) { | ||
test('Stats.monthly', function (t) { | ||
Stats.monthly(function (err, stats) { | ||
t.notOk(err, 'should not have an error'); | ||
t.same(stats['2011-01'], undefined, 'should not have badges for jan 2011'); | ||
t.same(stats['2012-10'], 1, 'should have one badge'); | ||
t.same(stats['2012-11'], 1, 'should have one badge'); | ||
t.same(stats['2012-12'], 1, 'should have one badge'); | ||
t.same(stats['2013-01'], 2, 'should have two badges'); | ||
t.end(); | ||
}); | ||
}); | ||
|
||
// necessary to stop the test runner | ||
test('shutting down #', function (t) { | ||
db.close(); t.end(); | ||
}); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "admin/base.html" %} | ||
{% block main %} | ||
|
||
<h1>Statistics</h1> | ||
|
||
<ul> | ||
{% for stat in stats %} | ||
<li> | ||
<dl> | ||
<dt>{{ stat.month }}</dt> | ||
<dd>{{ stat.count }} badges issued</dd> | ||
</dl> | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
|
||
{% endblock %} |