This commit is contained in:
2017-01-10 09:47:21 +08:00
commit 3e7b6bec82
7 changed files with 411 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# Created by https://www.gitignore.io/api/node,linux
### Node ###
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# End of https://www.gitignore.io/api/node,linux
+19
View File
@@ -0,0 +1,19 @@
{
"name": "compare_github_repos",
"version": "0.0.1",
"description": "Compare github repositories",
"main": "index.js",
"scripts": {
"start": "http-server -o",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "wassname",
"license": "ISC",
"dependencies": {
"datatables": "^1.10.13",
"gh.js": "^3.0.8",
"jquery": "^3.1.1",
"lodash": "^4.17.4",
"moment": "^2.17.1"
}
}
View File
+33
View File
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Compare github repository statistics</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.13/css/jquery.dataTables.css">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div>
<label><a href="https://github.com/settings/tokens">Github api token: </a></label>
<input id="token" placeholder="token" />
</div>
<table id="table" class="display" width="100%">
<textbox id="markdown"></textbox>
</table>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.13/js/jquery.dataTables.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js" charset="utf-8"></script>
src="https://cdnjs.cloudflare.com/ajax/libs/gh.js/3.0.8/gh.min.js" charset="utf-8"></script>
src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.js" charset="utf-8"></script>
<script src="js/main.js" charset="utf-8"></script>
</html>
File diff suppressed because one or more lines are too long
+113
View File
@@ -0,0 +1,113 @@
/**
* TODO cache requests by date
*/
// cache and save github api token
$('#token').val(localStorage['gh_token'])
$('#token').on('change', function() {
localStorage['gh_token'] = $('$token').val()
})
let gh = new GitHub(localStorage['gh_token'] || '')
function promiseGitHubStats(url) {
var apiUrl = url.replace('https://github.com/', '')
var promiseStats = new Promise(function(resolve, reject) {
gh.get("repos/" + apiUrl, (err, response) => {
if (err)
reject(err)
else
resolve(response)
})
})
var promiseContributors = new Promise(function(resolve, reject) {
gh.get("repos/" + apiUrl + '/stats/contributors', (err, response) => {
if (err)
reject(err)
else
resolve(response)
})
}).then(r => {
return {
contributors: r.length,
//commits: _.sum(r.map(c => c.total))
}
})
var promiseCommits = new Promise(function(resolve, reject) {
gh.get("repos/" + apiUrl + '/stats/participation', (err, response) => {
if (err)
reject(err)
else
resolve(response)
})
}).then(r => {
return {
'commits_per_week': _.round(_.mean(r.all), 3)
}
})
var promiseReleases = new Promise(function(resolve, reject) {
gh.get("repos/" + apiUrl + '/releases', (err, response) => {
if (err)
reject(err)
else
resolve(response)
})
}).then(r => {
return {'releases': r.length}
})
https : //api.github.com/repos/bitcoin/bitcoin/releases
return Promise.all([promiseStats, promiseContributors, promiseCommits, promiseReleases]).then(data => _.merge(...data))
}
function promiseBitbucketStats(url) {
url = url.replace('https://bitbucket.org/', 'https://api.bitbucket.org/2.0/repositories/')
// get all commits using a while(res.next) loop, then filter by date, to get comits per week. This part is slow
console.log(url)
var promiseCommits = new Promise(function(resolve, reject) {
var data = []
var doSeq = (curl) => {
$.get(curl).then(r => {
data.push(...r.values)
if (!r.next) {
return resolve(data)
} else {
return doSeq(r.next)
}
})
}
return doSeq(url + '/commits?pagelen=100')
}).then(data => {
// keep only commits this year, then get average
var year_ago = moment().subtract(1, 'year')
var commits_per_week = data.filter(dat => moment(dat.date) > year_ago).length / 52
commits_per_week = _.round(commits_per_week, 3)
return {commits_per_week}
})
return Promise.all([
promiseCommits,
$.get(url),
$.get(url + '/forks').then(data => ({forks: data.size})),
$.get(url + '/issues').then(data => ({issues: data.size})),
$.get(url + '/watchers').then(data => ({watchers: data.size})),
$.get(url + '/issues').then(data => ({open_issues: data.size})),
$.get(url + '/downloads').then(data => ({releases: data.size}))
]).then(data => _.merge(...data)).then(data => {
data.updated_at = data.updated_on
data.created_at = data.created_on
return data
})
}
+130
View File
@@ -0,0 +1,130 @@
/**
TODO:
- consider using add/minus as well/instead of commits
- total commits (add contributor contributions)
- sum projects over organisations
- paginate contributors to get over 100
- see if it's a fork?
**/
// format: name from on coinmarketcap: core Github project or repo
var columns = [
{
"data": "coin",
"title": "coin"
}, {
"data": "commits_per_week",
"title": "commits_per_week (for last year)"
}, {
"data": "watchers",
"title": "watchers"
}, {
"data": "open_issues",
"title": "open_issues"
},
//{
// "data": "size",
// "title": "size"
//},
{
"data": "created_at",
"title": "created_at"
}, {
"data": "updated_at",
"title": "updated_at"
}, {
"data": "contributors",
"title": "contributors (up to 100)"
}, {
"data": "forks",
"title": "forks"
}, {
"data": "releases",
"title": "releases"
}, {
"data": "language",
"title": "language"
},
//{
// "data": "description",
// "title": "description"
//},
{
"data": "url",
"title": "url"
}
]
/** parse dates then format **/
function parseDates(data) {
return data.map(row => {
for (key in row) {
if (key.endsWith('_at') && typeof key == "string") {
row[key] = new moment(row[key]).format('YYYY/MM/DD')
}
}
return row
})
}
// dirty hack - make a markdown table for reddit
function makeMarkDownTable(data) {
var table_cols = [
"coin",
"commits_per_week",
"watchers",
"open_issues",
"created_at",
"updated_at",
"contributors"
]
var d2 = data.map(row => _.pick(row, table_cols))
d2 = d2.sort((a, b) => b.commits_per_week - a.commits_per_week)
var h = columns.filter(col => table_cols.includes(col.data)).map(c => c.title)
var table = ''
table += '|' + h.join('|') + '|\n'
table += '|' + h.map(n => '---').join('|') + '|\n'
table += d2.map(row => '|' + _.values(row).join('|') + '|\n').join('')
return table
}
$(document).ready(function() {
// Collect data
let promises = Object.keys(coins).map(coin => {
var url = coins[coin]
if (url.includes('github.com')) {
return promiseGitHubStats(url).then(data => {
data.coin = coin
data.url = url
return data
})
} else {
return promiseBitbucketStats(url).then(data => {
data.coin = coin
data.url = url
return data
})
}
})
Promise.all(promises).then(data => {
data = parseDates(data)
localStorage['gh-data'] = JSON.stringify(data)
$('#table').DataTable({
data: _.values(data),
columns,
"order": [
[1, "desc"]
]
})
$('#markdown').val(makeMarkDownTable(data))
})
})