diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4a017de --- /dev/null +++ b/readme.md @@ -0,0 +1,8 @@ +Static site for comparing github repos/users. + +TODO: + +- [x] bitbucket +- [x] github organisations +- [x] progbar +- [x] configurable repos diff --git a/src/index.html b/src/index.html index f8c70e8..99a768f 100644 --- a/src/index.html +++ b/src/index.html @@ -10,11 +10,68 @@
-
- + +
+ + +
+
+ + +
@@ -33,7 +90,6 @@ - diff --git a/src/js/fetch_stats.js b/src/js/fetch_stats.js index ded1498..c0d72cd 100644 --- a/src/js/fetch_stats.js +++ b/src/js/fetch_stats.js @@ -1,6 +1,8 @@ /** * TODO cache requests by date */ +LITE_MODE = localStorage['LITE_MODE'] + let gh = new GitHub(localStorage['gh_token'] || '') @@ -38,6 +40,8 @@ function promiseGitHubRepoStats(url) { }) }) + if (LITE_MODE) {return promiseStats} + var promiseContributors = new Promise(function(resolve, reject) { gh.get(apiUrl + '/contributors', {all:true, opts:{per_page:100}}, (err, response) => { if (err) @@ -102,7 +106,7 @@ function promiseGitHubRepoStatsMulti(repos){ function promiseGitHubOrgStats(org){ - var apiUrl = "orgs/" + org.replace('https://github.com/', '') + '/repos' + var apiUrl = org.replace('https://github.com/', '') + '/repos' return new Promise(function(resolve, reject) { gh.get(apiUrl, {opts:{per_page:100}}, (err, response) => { if (err) @@ -111,7 +115,15 @@ function promiseGitHubOrgStats(org){ resolve(response) }) }) - .then(data => data.map(row=>row.full_name)) + .then(data => data + // we could filter out minor repos here + .filter(row => + row.stargazers_count>7 && + moment(row.updated_at)>moment().subtract(12, 'months') && + row.private === false && + row.archived === false + ) + .map(row=>row.full_name)) .then(promiseGitHubRepoStatsMulti) } diff --git a/src/js/main.js b/src/js/main.js index 4dacad1..9ce1d8e 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -12,54 +12,54 @@ function renderUrl(data){return ''+data+''} function renderDate(data){return data?moment(data).format('YYYY/MM/DD'):data} // ideally I want the input to bea list of github users or repos -var coins = { - "Bitcoin": 'https://github.com/bitcoin/bitcoin', - "Ethereum": 'https://github.com/ethereum/go-ethereum', - "Ripple": 'https://github.com/ripple/rippled', - "Litecoin": 'https://github.com/litecoin-project/litecoin', - "Monero": 'https://github.com/monero-project/monero', - 'Dash': 'https://github.com/dashpay/dash', - "Augur": "https://github.com/AugurProject/augur-core", - "Maidsafe": "https://github.com/maidsafe/safe_client_libs", - "Steem": "https://github.com/steemit/steem", - "NEM": "https://github.com/NemProject/nem.core", - //'Iconomi':'', - "Factom": 'https://github.com/FactomProject/factomd', - 'Dogecoin': 'https://github.com/dogecoin/dogecoin', - 'Waves': 'https://github.com/wavesplatform/Waves', - 'ZCash': 'https://github.com/zcash/zcash', - 'DigixDAO': 'https://github.com/DigixGlobal/digixdao-contracts', - 'Stellar Lumens': 'https://github.com/stellar/stellar-core', - 'Lisk': 'https://github.com/LiskHQ/lisk', - 'Tether': 'https://bitbucket.org/tetherto/tether-api-client-ruby', - // 'E-Dinar Coin': 'https://github.com/edincoin/EDINARCOIN', - //'ARDOR':'', - 'GameCredits': 'https://github.com/gamecredits-project/GameCredits', - 'Swiscoin': 'https://github.com/SCNPay/swiscoin', - 'Bitshares': 'https://github.com/bitshares/bitshares-2', - /** Notable below top 25 **/ - "Golem": "https://github.com/golemfactory/golem", - "PIVX":"https://github.com/PIVX-Project/PIVX", - "Nxt": 'https://bitbucket.org/JeanLucPicard/nxt', // bitbucket - "Iota": "https://github.com/iotaledger/iri", - "IotaOrg": "https://github.com/iotaledger", - "Vertcoin": 'https://github.com/vertcoin/vertcoin', - 'Stratis': 'https://github.com/stratisproject/stratisX', - 'VCash': 'https://github.com/openvcash/vcash', - "BitcoinUnlimited": "https://github.com/BitcoinUnlimited/BitcoinUnlimited", - "Bitcoinclassic": "https://github.com/bitcoinclassic/bitcoinclassic", - "Burstcoin": "https://github.com/BurstProject/burstcoin", - "Blocknet": "https://github.com/atcsecure/blocknet", - "Syscoin": "https://github.com/syscoin/syscoin2", - "Gnosis":"https://github.com/gnosis/gnosis-contracts", - // "":"https://github.com/voxelus" - "Qora": "https://github.com/Qoracoin/Qora", - "Storj": "https://github.com/Storj/core", - "Sia": "https://github.com/NebulousLabs/Sia", - "Bitcore": "https://github.com/dgbholdings/bitcore", - - 'Tittiecoin': 'https://github.com/tittiecoin/tittiecoin', // example shitcoin -} +// var coins = { +// "Bitcoin": 'https://github.com/bitcoin/bitcoin', +// "Ethereum": 'https://github.com/ethereum/go-ethereum', +// "Ripple": 'https://github.com/ripple/rippled', +// "Litecoin": 'https://github.com/litecoin-project/litecoin', +// "Monero": 'https://github.com/monero-project/monero', +// 'Dash': 'https://github.com/dashpay/dash', +// "Augur": "https://github.com/AugurProject/augur-core", +// "Maidsafe": "https://github.com/maidsafe/safe_client_libs", +// "Steem": "https://github.com/steemit/steem", +// "NEM": "https://github.com/NemProject/nem.core", +// //'Iconomi':'', +// "Factom": 'https://github.com/FactomProject/factomd', +// 'Dogecoin': 'https://github.com/dogecoin/dogecoin', +// 'Waves': 'https://github.com/wavesplatform/Waves', +// 'ZCash': 'https://github.com/zcash/zcash', +// 'DigixDAO': 'https://github.com/DigixGlobal/digixdao-contracts', +// 'Stellar Lumens': 'https://github.com/stellar/stellar-core', +// 'Lisk': 'https://github.com/LiskHQ/lisk', +// 'Tether': 'https://bitbucket.org/tetherto/tether-api-client-ruby', +// // 'E-Dinar Coin': 'https://github.com/edincoin/EDINARCOIN', +// //'ARDOR':'', +// 'GameCredits': 'https://github.com/gamecredits-project/GameCredits', +// 'Swiscoin': 'https://github.com/SCNPay/swiscoin', +// 'Bitshares': 'https://github.com/bitshares/bitshares-2', +// /** Notable below top 25 **/ +// "Golem": "https://github.com/golemfactory/golem", +// "PIVX":"https://github.com/PIVX-Project/PIVX", +// "Nxt": 'https://bitbucket.org/JeanLucPicard/nxt', // bitbucket +// "Iota": "https://github.com/iotaledger/iri", +// "IotaOrg": "https://github.com/iotaledger", +// "Vertcoin": 'https://github.com/vertcoin/vertcoin', +// 'Stratis': 'https://github.com/stratisproject/stratisX', +// 'VCash': 'https://github.com/openvcash/vcash', +// "BitcoinUnlimited": "https://github.com/BitcoinUnlimited/BitcoinUnlimited", +// "Bitcoinclassic": "https://github.com/bitcoinclassic/bitcoinclassic", +// "Burstcoin": "https://github.com/BurstProject/burstcoin", +// "Blocknet": "https://github.com/atcsecure/blocknet", +// "Syscoin": "https://github.com/syscoin/syscoin2", +// "Gnosis":"https://github.com/gnosis/gnosis-contracts", +// // "":"https://github.com/voxelus" +// "Qora": "https://github.com/Qoracoin/Qora", +// "Storj": "https://github.com/Storj/core", +// "Sia": "https://github.com/NebulousLabs/Sia", +// "Bitcore": "https://github.com/dgbholdings/bitcore", +// +// 'Tittiecoin': 'https://github.com/tittiecoin/tittiecoin', // example shitcoin +// } var columns = [ { @@ -216,7 +216,6 @@ function makeMarkDownTable(data) { /** fill missing attribtes so datatables stops complaining **/ function fillAll(data, columns){ - // TODO log undefine and NaN rows return data .filter(_.isObject) .map(row=>{ @@ -228,63 +227,79 @@ function fillAll(data, columns){ }) } -$(document).ready(function() { - $('#refresh').on('click', function(){ - localStorage['gh-data'] = '' - window.location.reload() - }) + +function refresh(){ + + var coins = $('#repos').val() + .trim() + .split('\n') + .filter(row=>!row.startsWith('#')) + .map(row=>row.split(',', 2)) + .reduce((o,[key,value])=>{ + o[key]=value + return o + },{}) // Collect data let promises - var nanobar = new Nanobar({}); - let total = Object.keys(coins).length - let finished_count = 0 + let countdown = Object.keys(coins).length + let total = countdown*1 + $("#go").prop('disabled', true); + $("#go").text(''+countdown) if (!localStorage['gh-data']) promises = Promise.all(Object.keys(coins).map(coin => { var url = coins[coin] // TODO(mjc) if its a user, list repos // TODO(mjc) if url is a list, do promiseGitHubRepoStatsMulti if (url.includes('github.com')) { - if (url.replace('https://github.com/','').includes('/')){ - return promiseGitHubRepoStats(url).then(data => { + if (url.includes(' ')) { + // handle a list of repos + return promiseGitHubRepoStatsMulti(url.split(' ')) + .then(data => { data.coin = coin data.url = url return data - }) - } else { + }).catch(err => {console.error(err, url, coin)}) + } + else if (url.includes('https://github.com/orgs') || url.includes('https://github.com/users')){ + // handle github org or user return promiseGitHubOrgStats(url).then(data => { data.coin = coin data.url = url return data - }) + }).catch(err => {console.error(err, url, coin)}) + + } else { + return promiseGitHubRepoStats(url).then(data => { + data.coin = coin + data.url = url + return data + }).catch(err => {console.error(err, url, coin)}) } } else { return promiseBitbucketRepoStats(url).then(data => { data.coin = coin data.url = url return data - }).catch(err => {console.error(err)}) + }).catch(err => {console.error(err, url, coin)}) } }).map(promise=>promise .then(value => { - // progressbar - finished_count+=1 - nanobar.go(finished_count/total*100) + countdown -= 1 + $("#go").text(`${countdown}/${total}`) return value }) // .catch(err => {console.error(err)}) ) ) .then((data) => { - // cache - localStorage['gh-data'] = JSON.stringify(data) + // cache so I can provide an offline snapshot + localStorage['gh-data2'] = JSON.stringify(data) return data }) else promises = Promise.resolve(JSON.parse(localStorage['gh-data'])) - - promises.then(data => { // data = parseDates(data) data = fillAll(data, columns) @@ -293,7 +308,7 @@ $(document).ready(function() { data: _.values(data), columns, "order": [ - [1, "desc"] + [1, "asc"] ], pageLength: 100, "lengthMenu": [ 10, 25, 50, 75, 100,800], @@ -303,5 +318,18 @@ $(document).ready(function() { }) $('#markdown').val(makeMarkDownTable(data)) + $("#go").prop('disabled', false); + $("#go").text("Go") + }) +} + +$(document).ready(function() { + // DEV purposes only + $('#clear').on('click', function(){ + localStorage['gh-data'] = '' + window.location.reload() + }) + $('#go').on('click', function(){ + refresh() }) })