Github Stats

Display download stats about the last release of Github projects.

Ekde 2015/07/20. Vidu La ĝisdata versio.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

  1. // ==UserScript==
  2. // @name Github Stats
  3. // @namespace stratehm.github
  4. // @include https://github.com/*/*
  5. // @version 3
  6. // @grant GM_xmlhttpRequest
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_deleteValue
  10. // @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
  11. // @description Display download stats about the last release of Github projects.
  12. // ==/UserScript==
  13.  
  14. var lastReleaseItemList;
  15.  
  16. this.$ = this.jQuery = jQuery.noConflict(true);
  17. $(document).ready(function() {
  18. init();
  19. });
  20.  
  21. function init() {
  22. lastReleaseItemList = $('<ul/>').attr({
  23. style: 'font-size: 11px; line-height: 10px; white-space: nowrap;'
  24. }).append('<b>Last release: </b>');
  25. $('h1.entry-title.public').append(lastReleaseItemList);
  26. var userProject = getCurrentUserProjectUrlPart();
  27. if(userProject) {
  28. getDownloadCount(userProject);
  29. }
  30. if(window.location.pathname.indexOf("/settings/tokens") >= 0) {
  31. $('.column.three-fourths').append('<div class="boxed-group access-token-group" id="GM_Form"><h3>Set your Gihtub login credentials for the GreaseMonkey userscript</h3><div class="boxed-group-inner"><p>Your login credentials will be used by the userscript to show the number of downloads for repositories.</p><ul class="boxed-group-list"><li style="line-height:32px;"><p>Username: <input type="text" id="clientId" style="float:right;width:480px;" /></p><p style="line-height:32px;">Password: <input type="password" id="clientSecret" style="float:right;width:480px;"/></p></li><li><button id="GM_submit" type="submit" type="button" class="btn btn-primary">Save</button>&nbsp;&nbsp;<button id="GM_reset" type="submit" type="button" class="btn btn-danger">Clear</button></li></ul><p class="help"><i class="octicon octicon-question"></i>Without your login credentials, you are rate limited to <a href="https://developer.github.com/v3/#rate-limiting">60 api calls per hour</a>.</p></div></div>');
  32. $('#clientId').val(GM_getValue('clientId',''));
  33. $('#clientSecret').val(GM_getValue('clientSecret',''));
  34. $('#GM_submit').click(function() {
  35. GM_setValue("clientId",$('#clientId').val());
  36. GM_setValue("clientSecret",$('#clientSecret').val());
  37. console.log({clientId:GM_getValue("clientId"),clientSecret:GM_getValue("clientSecret")});
  38. $('#GM_submit').fadeTo(1000,0.01).fadeTo(1000,1);
  39. gotoSourceUrl();
  40. });
  41. $('#GM_done').fadeIn(1000).fadeOut(1000);
  42. $('#GM_reset').click(function(){
  43. $('#clientId').val('');
  44. $('#clientSecret').val('');
  45. GM_deleteValue("clientId");
  46. GM_deleteValue("clientSecret");
  47. $('#GM_reset').fadeTo(1000,0.01).fadeTo(1000,1);
  48. gotoSourceUrl();
  49. });
  50. } else {
  51. saveSourceUrl();
  52. }
  53. }
  54.  
  55. function getCurrentUserProjectUrlPart() {
  56. var splittedPath = window.location.pathname.split('/');
  57. if(splittedPath.length >= 3) {
  58. return splittedPath[1] + '/' + splittedPath[2];
  59. }
  60. }
  61.  
  62. function getDownloadCount(userProjectUserPart) {
  63. var url = "https://api.github.com/repos/" + userProjectUserPart + "/releases";
  64. var headers = {
  65. "Cache-Control": "no-cache"
  66. }
  67. if(isTokenSet()) {
  68. headers.Authorization = "Basic " + btoa(GM_getValue("clientId")+":"+GM_getValue("clientSecret"));
  69. }
  70. GM_xmlhttpRequest({
  71. method: "GET",
  72. headers: headers,
  73. url: url,
  74. onload: parseDownloadStatsReponse
  75. });
  76. }
  77.  
  78. function parseDownloadStatsReponse(response) {
  79. var status = response.status;
  80. var data = $.parseJSON(response.responseText);
  81. // Check if login credentials are accepted
  82. if(status == 401) {
  83. onUnauthorized();
  84. } else if(data.message && data.message.indexOf("API rate limit exceeded") >-1) {
  85. // Credentials are requested
  86. accessTokenNeeded();
  87. } else {
  88. // Parsing of the response only if some data are present.
  89. if(data && data.length > 0) {
  90. parseLastReleaseDownloadCount(data);
  91. parseTotalDownloadCount(data);
  92. } else {
  93. lastReleaseItemList.append("No release<br>");
  94. }
  95. if(isTokenSet()) {
  96. lastReleaseItemList.append("Change/Clear your <a href='https://github.com/settings/tokens'>Gihtub login credentials</a>");
  97. }
  98. }
  99. }
  100.  
  101. function parseLastReleaseDownloadCount(data) {
  102. var releaseName = data[0].name;
  103. var htmlUrl = data[0].html_url;
  104. lastReleaseItemList.append($('<a/>').attr({
  105. href: htmlUrl
  106. }).append(releaseName));
  107. if(data[0].assets && data[0].assets.length > 0) {
  108. for(var i = 0 ; i < data[0].assets.length ; i++) {
  109. var assetName = data[0].assets[i].name;
  110. var assetDlCount = data[0].assets[i].download_count;
  111. var assetUrl = data[0].assets[i].browser_download_url;
  112. appendAssetDlItem(assetName, assetDlCount, assetUrl);
  113. }
  114. } else {
  115. lastReleaseItemList.append("<br>No binaries in the last release<br>");
  116. }
  117. }
  118.  
  119. function parseTotalDownloadCount(data) {
  120. var totalDownloadCount = 0;
  121. for(var i = 0 ; i < data.length ; i++) {
  122. if(data[i].assets && data[i].assets.length > 0) {
  123. for(var j = 0 ; j < data[i].assets.length ; j++) {
  124. totalDownloadCount += data[i].assets[j].download_count;
  125. }
  126. }
  127. }
  128. lastReleaseItemList.append("All releases download count: " + totalDownloadCount + "<br>");
  129. }
  130.  
  131. function appendAssetDlItem(assetName, assetDlCount, assetUrl) {
  132. lastReleaseItemList.append($('<li/>').attr({
  133. style: "margin-left: 20px;"
  134. }).append("<b>Name:</b> <a href='" + assetUrl + "'>" + assetName + '</a>, <b>Dl Count:</b> ' + assetDlCount));
  135. }
  136.  
  137.  
  138. function accessTokenNeeded() {
  139. lastReleaseItemList.append($('<li/>').attr({
  140. style: "margin-left: 20px;"
  141. }).append("Your api limit has been hit. Please add a <a href='https://github.com/settings/tokens'>Gihtub login credentials</a>"));
  142. }
  143.  
  144. function onUnauthorized() {
  145. lastReleaseItemList.append($('<li/>').attr({
  146. style: "margin-left: 20px;"
  147. }).append("Bad credentials. Please check your <a href='https://github.com/settings/tokens'>Gihtub login credentials</a>"));
  148. }
  149.  
  150. function isTokenSet() {
  151. return GM_getValue("clientId","") && GM_getValue("clientSecret","");
  152. }
  153.  
  154. function saveSourceUrl() {
  155. GM_setValue("sourceUrl", window.location.href);
  156. }
  157. function gotoSourceUrl() {
  158. var sourceUrl = GM_getValue("sourceUrl", "");
  159. console.log("Restore location: " + sourceUrl);
  160. if(sourceUrl) {
  161. window.location.href = sourceUrl;
  162. }
  163. }