Github Stats

Display download stats about the last release of Github projects.

目前为 2015-07-20 提交的版本,查看 最新版本

  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. }