/*! CPAN Distributions List - v1.0.3 - 2016-04-16
* https://github.com/guillaumeaubert/jquery-cpan-distributions-list
* Copyright (c) 2016 Guillaume Aubert; Licensed MIT */
(
function($)
{
/**
* createDistributionsList
*
* @class Makes the createDistributionsList() method available to JQuery
* selectors.
*
* @param {hash} options The options for generating the list of distributions.
*/
$.fn.createDistributionsList = function(options)
{
/***** MAIN *****/
var container = this;
// Remove existing rows, in case we're refreshing the container.
container.find('tbody:last tr.distribution').remove();
// Parse options and add defaults if needed.
var settings = $.extend(
{
pause_id: 'AUBERTG',
github_id: 'guillaumeaubert',
coveralls: true,
travis_ci: true,
repositories: {},
repository_lowercase: false,
template_row: this.find('tr.template:first')
},
options
);
retrieve_metacpan_information(container, settings);
};
/***** SUPPORTING FUNCTIONS *****/
/**
* Retrieve the distribution information from MetaCPAN.
*
* @param {JQuery selector} container The container to display the
* distribution rows in.
* @param {hash} settings The settings to use for display.
*/
function retrieve_metacpan_information(container, settings)
{
$.ajax(
{
type: 'GET',
async: true,
dataType: "json",
url: "https://api.metacpan.org/v0/release/_search?q=author:"+settings.pause_id+"%20AND%20status:latest&fields=version,distribution,date,tests&size=100&sort=distribution",
success: function(json)
{
if (json.timed_out === 'false')
{
alert('MetaCPAN timed out (' + json.timed_out + ')!');
return;
}
if (json.hits.total === 0)
{
alert('MetaCPAN returned no distributions for this author!');
return;
}
// Display the number of distributions found.
$('.cpan_distributions_count').html( json.hits.total );
// Display each distribution.
json.hits.hits.forEach(
function(element, index)
{
display_distribution(
container,
settings,
index,
element.fields
);
}
);
// Asynchronous population of GitHub data.
populate_github_information(container, settings);
},
error: function(xhr)
{
console.log('Error querying MetaCPAN for information about the distributions: ' + xhr.statusText);
}
}
);
}
/**
* Retrieve the repository information from GitHub and populate where
* needed.
*
* @param {JQuery selector} container The container to display the
* distribution rows in.
* @param {hash} settings The settings to use for display.
*/
function populate_github_information(container, settings, page)
{
// Default to page 1.
if (typeof(page) === 'undefined') {
page = 1;
}
$.ajax(
{
type: 'GET',
async: true,
dataType: "json",
url: "https://api.github.com/users/"+settings.github_id+"/repos?page="+page+"&per_page=100",
success: function(json)
{
if (json.length <= 0)
{
// Callback for success, if needed.
if (settings.on_success)
{
settings.on_success(json);
}
// There is no more information to query, return.
return;
}
// Add GitHub information to the appropriate rows.
json.forEach(
function(element, index)
{
var distribution = element.name;
var repository = get_repository(settings, distribution);
container.find('tr#distribution_'+distribution+' td.github_open_issues').html(
$('')
.attr('href', "https://github.com/"+settings.github_id+"/"+repository+"/issues")
.html(element.open_issues_count)
);
}
);
// Query the next page.
var max_github_requests = typeof(settings.max_github_requests) === 'undefined'
? 5
: settings.max_github_requests;
if (page < max_github_requests) {
populate_github_information(container, settings, page+1);
}
},
error: function(xhr)
{
console.log('Error querying GitHub for repository information: ' + xhr.statusText);
}
}
);
}
/**
* Retrieve the name of the repository from the name of the distribution.
*
* @param {hash} settings The settings to use for display.
* @param {string} distribution The name of the distribution.
*/
function get_repository(settings, distribution)
{
return settings.repositories[distribution]
? settings.repositories[distribution]
: settings.repository_lowercase
? distribution.toLowerCase()
: distribution;
}
/**
* Display a distribution in the container table.
*
* @param {JQuery selector} container The container to display the
* distribution rows in.
* @param {hash} settings The settings to use for display.
* @param {integer} index The index of the distribution retrieved.
* @param {string} metacpan_data The data returned by MetaCPAN for the distribution.
*/
function display_distribution(container, settings, index, metacpan_data)
{
var distribution = metacpan_data.distribution;
var repository = get_repository(settings, distribution);
// Create a placeholder if MetaCPAN didn't return test information. This
// seems to occasionally happen.
if (typeof(metacpan_data.tests) === 'undefined') {
metacpan_data.tests = {
'pass': '',
'fail': '',
'na': '',
'unknown': ''
};
}
// Gather all the data that we will use to build the table.
var data =
{
'distribution': distribution,
'metacpan-distname': $('')
.attr('href', 'https://metacpan.org/release/'+distribution)
.html(distribution),
'version': metacpan_data.version,
'date': metacpan_data.date,
'travis_status_badge':
settings.travis_ci
? $('')
.attr('href', 'https://travis-ci.org/'+settings.github_id+'/'+repository)
.html(
$('')
.attr('src', 'https://travis-ci.org/'+settings.github_id+'/'+repository+'.svg?branch=master')
.attr('alt', 'Build Status')
)
: '',
'coveralls_badge':
settings.coveralls
? $('')
.attr('href', 'https://coveralls.io/r/'+settings.github_id+'/'+repository+'?branch=master')
.html(
$('')
.attr('src', 'https://coveralls.io/repos/'+settings.github_id+'/'+repository+'/badge.svg?branch=master')
.attr('alt', 'Coverage Status')
)
: '',
'github': $('')
.attr('href', 'https://github.com/'+settings.github_id+'/'+repository)
.html('GitHub'),
'metacpan': $('')
.attr('href', 'https://metacpan.org/release/'+distribution)
.html('MetaCPAN'),
'cpants': $('')
.attr('href', 'http://cpants.cpanauthors.org/dist/'+distribution)
.html('CPANTS'),
'cpan-testers-pass': metacpan_data.tests.pass,
'cpan-testers-fail': metacpan_data.tests.fail,
'cpan-testers-na': metacpan_data.tests.na,
'cpan-testers-unknown': metacpan_data.tests.unknown
};
// Clone row.
var tr = settings.template_row.clone();
// Add information to the row.
for (var key in data)
{
tr.find('.'+key).html(data[key]);
}
tr.css('display', '');
tr.attr('id', 'distribution_'+distribution);
tr.addClass('distribution');
tr.removeClass('template');
// Append the row at the end of the table.
container.find('tbody:last').append(tr);
}
}(jQuery)
);