Is there any easy way to see how many users on a site have attained a particular privilege?
For example, the number of users on this site who have the 3,000 reputation needed to cast close/re-open votes.
Meta Stack Exchange is a question and answer site for meta-discussion of the Stack Exchange family of Q&A websites. It only takes a minute to sign up.
Sign up to join this communityIs there any easy way to see how many users on a site have attained a particular privilege?
For example, the number of users on this site who have the 3,000 reputation needed to cast close/re-open votes.
The closest thing I can think of is the reputation league table per site which can be reached by going to the Users tab of a site and clicking reputation leagues
at the bottom of that page.
It kind of misses the 15K and a lot of the lower reputation level, but it is as simple as it gets
You can leverage the Stack Exchange API for that.
The /users endpoint offers an 'min' search parameter, which can be used to query the field you sort on, in this scenario that will be reputation
.
I created below Stack Snippet to fetch all sites and then offers you to select a site and a reputation level.
After selecting the site, the privileges are fetched as well as those can vary per site.
Click on the calculate button to see how many users match the give reputation criteria.
The script will call /users to fetch the total number users with at least that reputation level.
// build api url for an endpoint and its optional parameters
function apiBuilder(endpoint, params) {
var url = 'https://api.stackexchange.com/2.2/',
urlPath = url + endpoint;
if (params !== undefined) {
var query = [];
for(var prop in params) {
if (params.hasOwnProperty(prop)) {
query.push( prop + '=' + params[prop]);
}
}
urlPath = urlPath + '?' + query.join('&');
}
return urlPath;
}
// build url for /users endpoint
function apiUsersBuilder(site, rep) {
return apiBuilder(
'users',
{
site: site,
order: 'desc',
page: 1,
pagesize: 1,
min: rep,
sort: 'reputation',
filter: '!6XcF36OyeUd48'
});
}
// build url for /sites api endpoint
function apiSitesBuilder() {
return apiBuilder(
'sites',
{
pagesize: 500,
filter: '!2--Yion.3M.K5PJ6Ea0*R'
});
}
// build url for /privileges api endpoint
function apiPrivilegesBuilder(site) {
return apiBuilder(
'privileges',
{
site: site,
pagesize: 100
});
}
// do a get on the API for the given url
// and invoke the callback with the JSON result
function API () {
var backlog = [],
getfunction;
// simply push the params on the queue
function cacheget(url, callback) {
backlog.push({ url: url, callback: callback});
}
// this makes the actual xhr call
function realget(url, callback) {
var xhr = new XMLHttpRequest();
// handles pending calls by invoking realget
// and resetting the getfunction when
// the backlog is cleared
function handleBacklog() {
var item = backlog.shift();
if (item !== undefined) {
console.log('from cache');
// handle this single item
realget(item.url, item.callback);
}
if (backlog.length === 0) {
// if the backlog is empty
// use realget for the next call
getfunction = realget;
}
}
xhr.addEventListener('load', function () {
var response = JSON.parse(xhr.responseText);
var backoff = response.backoff || 0;
// backoff received
if (backoff > 0) {
// start caching calls
console.log('backoff recv');
getfunction = cacheget;
}
// process pending backlog
setTimeout(handleBacklog, backoff * 1000);
// invoke the callback
callback(response);
});
xhr.open('GET', url);
xhr.send();
}
// calls either xhr or the cache
function get(url, callback)
{
getfunction(url, callback);
}
// initially we start with a realget
getfunction = realget;
// return the public api
return {
get: get
}
}
var SEApi = new API(); // keep an instance
// calls the API
function get(url, callback) {
SEApi.get(url, callback);
}
// for a given site and rep, fetch number of users
// and populate usercount html element
function getPrivilegedUserCount(site, rep) {
get(
apiUsersBuilder(site, rep),
function (result) {
var uc = document.getElementById('usercount');
uc.textContent = result.total;
});
}
// build option
function buildSiteOption(site) {
// build option element
var opt = document.createElement('option');
opt.value = site.api_site_parameter;
opt.textContent = site.name;
return opt;
}
function buildPrivilege(privilege, datalist) {
var dd,
num,
span,
des;
dd = document.createElement('dd');
num = document.createElement('dt');
span = document.createElement('span');
span.textContent = privilege.reputation;
num.appendChild(span);
des = document.createElement('dd');
des.textContent = privilege.short_description;
dd.appendChild(num);
dd.appendChild(des);
datalist.appendChild(dd);
}
// fetch and show privileges for a site
function updatePrivileges(key) {
get(apiPrivilegesBuilder(key),
function (result) {
var dl = document.getElementById('priv'),
i;
while(dl.firstChild) {
dl.removeChild(dl.firstChild);
}
for(i = 0; i < result.items.length; i++) {
buildPrivilege(
result.items[i],
dl
);
}
});
}
// loadsites and populate site select list
// keep site records in allsites array
function loadSites(search) {
get(apiSitesBuilder(), function(result) {
var sites = document.getElementById('sites'),
i;
// loop over the items, being site types
for(i = 0; i < result.items.length; i = i + 1) {
// add site selection element
sites.appendChild(
buildSiteOption(result.items[i])
);
}
search.disabled = false;
sites.addEventListener(
'change',
function(e) {
var key = sites.item(sites.selectedIndex).value;
updatePrivileges(key);
});
updatePrivileges(sites.item(0).value);
});
}
// hookup search button and start loadsites
function init() {
var go = document.getElementById('go');
go.addEventListener('click', function () {
var sites = document.getElementById('sites'),
site,
siteKey;
if (sites.selectedIndex > -1) {
siteKey = sites.item(sites.selectedIndex).value;
getPrivilegedUserCount(
siteKey,
document.getElementById('rep').value);
}
});
go.disabled = true;
loadSites(go);
}
// startup!
init();
label {display:block; padding: 5px;}
select {margin-left: 45px;}
button {padding: 5px; margin: 5px 5px 5px 5px;}
dt { width: 50px; clear:left;float:left;}
dd { margin-left: 25px; }
dt > span { width: 80%; text-align: right; display:inline-block;}
<p>Number of users for a site above given reputation</p>
<label>Site : <select id="sites">
</select>
</label>
<label>
Reputation :
<input id="rep" value="3000" type="text"/>
</label>
<div id="result">
<button id="go">Calculate</button>
users : <span id="usercount"></span>
</div>
Privileges/reputation
<dl id="priv">
</dl>