Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add recent contributors report, and allow reports to require auth to …
…view. Closes #73
- Loading branch information
1 parent
a6aaca5
commit 62a020c
Showing
8 changed files
with
208 additions
and
4 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# How to write Measure reports | ||
|
||
Measure allows the creation of "reports"; full-page summaries of data. These are very free-form; basically, a report can display whatever it wants without restriction. | ||
|
||
## Basic report creation | ||
|
||
Your widget is expected to be a Node.js module which exports one function. That function takes two parameters, `options` and `callback`. It should call the callback with an object with `title` and `html` keys. The `title` is displayed as the title of the report, and should be plain text; `html` is a block of HTML which is placed as-is, without escaping, into the body of the report page. Reports are automatically linked from the "Reports" summary page. | ||
|
||
## Authentication | ||
|
||
A report may contain restricted information. If so, it is possible to restrict the report to be viewed only by authenticated users. To do this, add a `requires_authentication: true` entry to the output object. Note that authentication has to be enabled in `config.yaml`, otherwise the report will not be generated at all (a warning is printed in this situation). It is not possible to restrict a report to _specific_ authenticated users; just authenticated or not. |
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
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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,112 @@ | ||
/* | ||
"Recent Contributors report" | ||
Report with name, org, and email address of everyone who's made a | ||
contribution in the last ___ where ___ is a dropdown with say | ||
week/month/quarter/year. Should not show if not authenticated. | ||
(https://github.com/MeasureOSS/Measure/issues/73) | ||
*/ | ||
var moment = require("moment"); | ||
var async = require("async"); | ||
|
||
module.exports = function(options, callback) { | ||
var people2Org = {}; | ||
for (var orgname in options.org2People) { | ||
options.org2People[orgname].forEach(p => { | ||
if (p.left != "") return; | ||
if (!people2Org[p.login]) people2Org[p.login] = new Set(); | ||
people2Org[p.login].add(orgname); | ||
}); | ||
} | ||
|
||
var mostRecentUserAction = {}; | ||
|
||
options.db.issue.find({}, {"user.login": 1, "closed_by.login": 1, created_at: 1, closed_at: 1}).toArray().then(issues => { | ||
issues.forEach(function(i) { | ||
if (i.closed_at) { | ||
var ca = moment(i.closed_at); | ||
var mr = mostRecentUserAction[i.closed_by.login]; | ||
if (mr) { | ||
mr = moment(mr); | ||
if (ca.isAfter(mr)) { | ||
mostRecentUserAction[i.closed_by.login] = ca; | ||
} | ||
} else { | ||
mostRecentUserAction[i.closed_by.login] = ca; | ||
} | ||
} | ||
|
||
var oa = moment(i.created_at); | ||
var mr = mostRecentUserAction[i.user.login]; | ||
if (mr) { | ||
mr = moment(mr); | ||
if (oa.isAfter(mr)) { | ||
mostRecentUserAction[i.user.login] = oa; | ||
} | ||
} else { | ||
mostRecentUserAction[i.user.login] = oa; | ||
} | ||
}) | ||
|
||
var peopleList = []; | ||
for (var k in mostRecentUserAction) { | ||
peopleList.push({ | ||
login: k, | ||
date: mostRecentUserAction[k], | ||
yyyymmdd: mostRecentUserAction[k].format("YYYY-MM-DD"), | ||
org: people2Org[k] || [], | ||
ts: mostRecentUserAction[k].unix() | ||
}) | ||
} | ||
peopleList.sort(function(b, a) { | ||
return a.ts - b.ts; | ||
}); | ||
|
||
var trs = peopleList.map(function(p) { | ||
var orglist = Array.from(p.org).map(function(o) { | ||
return '<a href="' + options.url("org", o) + '">' + o + '</a>'; | ||
}).join("/"); | ||
var contributor = '<a href="' + options.url("contributor", p.login) + '">' + p.login + "</a>"; | ||
return "<tr><td>" + contributor + "</td><td>" + orglist + | ||
"</td><td sorttable_customkey='"+p.ts+"'>" + p.yyyymmdd + "</td></tr>"; | ||
}) | ||
|
||
var table = '<table id="report_t" class="sortable">' + | ||
'<thead>\n<tr><th>Contributor</th><th>Organisations</th>' + | ||
'<th>Most recent contribution</th></tr>\n</thead>\n<tbody>' + | ||
trs.join("\n") + "<tbody></table>"; | ||
|
||
var dropdown = '<p>Show contributors from last ' + | ||
'<select id="report_dd" onchange="report_filter()"><option value="365">year</option>' + | ||
'<option value="90">quarter</option><option value="30">month</option>' + | ||
'<option value="7">week</option></select></p>'; | ||
var filter_script = `<script> | ||
var report_dd = document.getElementById("report_dd"); | ||
var report_t = document.getElementById("report_t"); | ||
function report_filter() { | ||
var days = report_dd.options[report_dd.selectedIndex].value; | ||
var ts = new Date().getTime(); | ||
var then = ts - (days * 24 * 60 * 60 * 1000); | ||
var then_yyyymmdd = (new Date(then)).toISOString().substring(0, 10); | ||
console.log("looking for dates bigger than", then_yyyymmdd); | ||
Array.prototype.slice.call(report_t.rows).forEach(function(r) { | ||
var dval = r.cells[2].textContent; | ||
if (dval > then_yyyymmdd) { | ||
r.style.display = "" | ||
} else { | ||
r.style.display = "none"; | ||
} | ||
}); | ||
} | ||
report_filter(); | ||
</script> | ||
`; | ||
|
||
var html = dropdown + table + filter_script; | ||
|
||
return callback(null, { | ||
title: "Recent Contributors", | ||
html: html, | ||
requires_authentication: true | ||
}) | ||
}) | ||
} |
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 |
---|---|---|
@@ -1,5 +1,27 @@ | ||
{{> mainlessheader.tmpl}} | ||
<div class="main wrapper clearfix report"> | ||
{{#requires_authentication}} | ||
<?php | ||
require("../authlist.php"); | ||
|
||
$report = <<<EOF | ||
<h1>{{title}}</h1> | ||
{{{html}}} | ||
EOF; | ||
$isok = generic_verify($_COOKIE["MeasureAuth"]); | ||
|
||
if ($isok) { | ||
echo $report; | ||
} else { | ||
echo '<p>This report is only available after logging in. Please '; | ||
echo '<a href="../login.php" class="login-required-link">log in</a> to view.</p>'; | ||
} | ||
?> | ||
|
||
{{/requires_authentication}} | ||
|
||
{{^requires_authentication}} | ||
<h1>{{title}}</h1> | ||
{{{html}}} | ||
{{/requires_authentication}} | ||
{{> footer.tmpl}} |
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