// ==UserScript== // @name imgur_show_user_stats_light // @namespace someName // @include http://imgur.com/user/* // @include https://imgur.com/user/* // @version 0.3.3 // @grant none // @description Show user statistics on imgur // @downloadURL none // ==/UserScript== // TODO: Catch errors and check result.success // TODO: Think about useable version numbers... // TODO: Add support for username.imgur.com style urls // TODO: Is there a way to request http://community.imgur.com/users/'+username+'.json without CORS problems ? // We could use greasemonkey ajax call, but that wouldn't work with bookmarklets and every other browser (i guess) // TODO: Show errors and handle no credits remaining ? $(window).ready(function () { var CLIENT_ID = 'cd0695f1226536b'; var MAX_SUB_PAGES = 15; var _submissions_left = -1; var _sub_site = 0; var _submissions = []; var _last_sub_id = -1; var _last_post = -1; function _update_limits_from_header(xhr) { xhr.getResponseHeader('Header') $('#stats_credits_user').html('User Credits: ' + xhr.getResponseHeader('X-RateLimit-UserRemaining') + ' / ' + xhr.getResponseHeader('X-RateLimit-UserLimit')); $('#stats_credits_script').html('Script Credits: : ' + xhr.getResponseHeader('X-RateLimit-ClientRemaining') + ' / ' + xhr.getResponseHeader('X-RateLimit-ClientLimit')); } function request_user_info(endpoint, success_cb, error_cb) { $.ajax({ url: 'https://api.imgur.com/3/account/' + username + '/' + endpoint, method: 'GET', headers: { Authorization: 'Client-ID ' + CLIENT_ID, Accept: 'application/json' }, success: function (a, b, c) { _update_limits_from_header(c); success_cb(a, b, c); }, error: error_cb }); } if (window.location.pathname.indexOf('/user/') === 0 && $('.button').filter('.comments').length > 0) { // Set up UI var username = window.location.pathname.split('/', 3) [2]; // TODO: look for a more stable way (is there an imgur js var maybe ?) var newBox = $('
'); var tble = $('| Account creation | - |
| Comments | - |
| Submissions | - |
| Albums | - |
| Images | - |
| Favorites | - |
| Last activity | |
| AVG post points | |
| AVG post views | |
| Most viral posts | |
| NSFW posts | |
| Top tags | |
| IC profile | |
| - | |
| - | |
');
$('#_btn_extend').click(function(){
if(_submissions_left == 0) return;
tble.find('._extended').show();
get_submissions();
});
// get coments / submission stats
request_user_info('gallery_profile', function (result, status, request) {
$('#stats_comments').html(result.data.total_gallery_comments.toLocaleString()).closest('td').children().show().filter('img').remove();
$('#stats_submissions').html(result.data.total_gallery_submissions.toLocaleString()).closest('td').children().show().filter('img').remove();
$('#stats_favorites').html(result.data.total_gallery_favorites.toLocaleString()).closest('td').children().show().filter('img').remove();
_submissions_left = result.data.total_gallery_submissions;
}, function (a, b, c) {
console.log('Failed to load', a, b, c);
$('#stats_comments, #stats_submissions, #stats_favorites').text('Failed to load').closest('td').children().show().filter('img').remove();
}
);
// get the exact (*) join date. TODO: I bet i messed up the time(zones) here.
request_user_info('', function (result, status, request) {
$('#stats_created').html(new Date(result.data.created * 1000).toLocaleDateString()).closest('td').children().show().filter('img').remove();
}, function (a, b, c) {
console.log('Failed to load', a, b, c);
$('#stats_created').text('Failed to load').closest('td').children().show().filter('img').remove();
}
);
// album count (inklusive not submitted to gallery), if album settings are set to public.
request_user_info('albums/count', function (result, status, request) {
$('#stats_albums').html(result.data.toLocaleString()).closest('td').children().show().filter('img').remove();
}, function (a, b, c) {
console.log('Failed to load', a, b, c);
$('#stats_albums').html('private').closest('td').children().show().filter('img').remove();
}
);
// image count (inklusive not submitted to gallery), if image settings are set to public.
request_user_info('images/count', function (result, status, request) {
$('#stats_images').html(result.data.toLocaleString()).closest('td').children().show().filter('img').remove();
}, function (a, b, c) {
console.log('Failed to load', a, b, c);
$('#stats_images').html('private').closest('td').children().show().filter('img').remove();
}
);
function get_submissions() {
if(_submissions_left <= 0) return;
console.log("Requesting submission page #" + _sub_site);
request_user_info('submissions/' + _sub_site, function (result, status, request) {
_submissions.push.apply(_submissions, result.data);
_submissions_left -= result.data.length;
var done = true;
if(result.data.length > 0 && _submissions_left > 0 && _last_sub_id != result.data[0].id){
if(_sub_site+1 == MAX_SUB_PAGES){
var a = $('!');
a.attr('title', 'Only the last '+ _submissions.length +' submissions are considered.');
$('#stats_score, #stats_views, #stats_toptags, #stats_nsfw, #stats_most_viral').parent().children('td:nth-child(1)').append(a);
}else{
_last_sub_id = result.data[0].id;
_sub_site += 1;
get_submissions();
done = false;
}
}
if(done){
if(_submissions.length > 0){
// TODO: are they always returned newest first ?
_last_post = _submissions[0].datetime;
}
calc_views();
calc_score();
collect_tags();
get_last_comment();
calc_most_viral();
calc_nsfw();
}
}, function (a, b, c) {
console.log('Failed to load', a, b, c);
}
);
}
function _get_field(array, field){
var ret = Array();
for(var i=0; i < array.length; ++i){
ret.push(array[i][field])
}
return ret;
}
// some array funcs for convinience
Array.prototype.sum = function() {
return this.reduce(function(a, b) { return a + b; }, 0);
};
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
Array.prototype.min = function() {
return Math.min.apply(null, this);
};
var round = Math.round;
function calc_views(){
var views = _get_field(_submissions ,'views');
var view_sum = views.sum();
var a = $('');
a.text(round(view_sum / views.length).toLocaleString());
a.attr('title', 'All: ' + round(view_sum).toLocaleString() + ". Max: " + views.max().toLocaleString() + ". Min: " + views.min().toLocaleString() + ".");
$('#stats_views').append(a).closest('td').children().show().filter('img').remove();
}
function calc_score(){
var points = _get_field(_submissions ,'points');
var ups = _get_field(_submissions ,'ups').sum() / points.length;
var downs = _get_field(_submissions ,'downs').sum() / points.length;
var point_sum = points.sum();
var a = $('');
a.text( round(point_sum / points.length).toLocaleString());
a.attr('title', 'Upvotes avg: ' + round(ups).toLocaleString() + ". Downvotes avg: " + round(downs).toLocaleString() + ".");
$('#stats_score').append(a).closest('td').children().show().filter('img').remove();
}
function calc_most_viral(){
var virals = _get_field(_submissions ,'in_most_viral');
var _sum = virals.sum();
if(virals.length > 0){
val = Math.round((100.0 / virals.length) * _sum);
}
var a = $('');
a.text( val + "%" );
a.attr('title', _sum + " / " + virals.length + " posts");
$('#stats_most_viral').append(a).closest('td').children().show().filter('img').remove();
}
function calc_nsfw(){
var nsfws = _get_field(_submissions ,'nsfw');
var _sum = nsfws.sum();
var val = 0;
if(nsfws.length > 0){
val = Math.round((100.0 / nsfws.length) * _sum);
}
var a = $('');
a.text( val + "%" );
a.attr('title', _sum + " / " + nsfws.length + " posts");
$('#stats_nsfw').append(a).closest('td').children().show().filter('img').remove();
}
function collect_tags(){
console.log('collect_tags');
var counter = {};
for(var i=0; i < _submissions.length; ++i){
var tags = _submissions[i].tags;
for(var j=0; j < tags.length; ++j){
var count = 1; var k = tags[j].display_name;
if( k in counter ){
count += counter[k][0];
}
counter[k] = [count, tags[j]];
}
}
var vals = Object.values(counter);
vals.sort(function(a, b) {
return b[0] - a[0];
});
$('#stats_toptags').children().show().filter('img').remove();
for(var i=0; i < 5 && i < vals.length; ++i){
var node = $('-