GitHub Repo Size

在 GitHub 仓库页面显示仓库大小信息

当前为 2024-12-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GitHub Repo Size
  3. // @namespace https://github.com/
  4. // @version 1.1
  5. // @description 在 GitHub 仓库页面显示仓库大小信息
  6. // @author cscnk52 & ChatPGT
  7. // @match https://github.com/*/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant GM_registerMenuCommand
  12. // @connect api.github.com
  13. // @run-at document-body
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. "use strict";
  18.  
  19. if (!/https:\/\/github\.com\/[^\/]+\/[^\/]+$/.test(window.location.href)) {
  20. return;
  21. }
  22.  
  23. const token = GM_getValue("token", null);
  24. const apiUrl = `https://api.github.com/repos${window.location.pathname}`;
  25.  
  26. GM_registerMenuCommand("config token", function () {
  27. const currentToken = token
  28. ? `current Token: ${token}`
  29. : "No Token configured";
  30. const newToken = prompt(`${currentToken}\nEnter new Token:`);
  31.  
  32. if (newToken) {
  33. GM_setValue("token", newToken);
  34. alert("Token update!");
  35. } else if (newToken === "") {
  36. alert("Token unchanged!");
  37. }
  38. });
  39.  
  40. function fetchRepoSize() {
  41. return new Promise((resolve, reject) => {
  42. GM_xmlhttpRequest({
  43. method: "GET",
  44. url: apiUrl,
  45. headers: {
  46. Accept: "application/vnd.github.v3+json",
  47. "User-Agent": "Mozilla/5.0",
  48. Authorization: `Bearer ${token}`,
  49. },
  50. onload: function (response) {
  51. if (response.status === 200) {
  52. const repoData = JSON.parse(response.responseText);
  53. if (repoData && repoData.size) {
  54. let size = repoData.size;
  55. let sizeDisplay;
  56.  
  57. if (size >= 0.9 * 1024 * 1024) {
  58. sizeDisplay = (size / (1024 * 1024)).toFixed(2) + " GB";
  59. } else if (size >= 0.9 * 1024) {
  60. sizeDisplay = (size / 1024).toFixed(2) + " MB";
  61. } else {
  62. sizeDisplay = size.toFixed(2) + " KB";
  63. }
  64.  
  65. resolve(sizeDisplay);
  66. } else {
  67. resolve("Size not available");
  68. }
  69. } else if (response.status === 401) {
  70. resolve("Error: Token invalid");
  71. } else if (response.status === 403) {
  72. resolve("Error: Token permissions are insufficient");
  73. } else if (response.status === 429) {
  74. resolve(
  75. "Error: GitHub API limit reached. Configure a token to fix.",
  76. );
  77. } else {
  78. resolve(`Error: HTTP Code ${response.status}`);
  79. }
  80. },
  81. onerror: function (error) {
  82. reject(`Error: ${error}`);
  83. },
  84. });
  85. });
  86. }
  87.  
  88. async function displayRepoSize() {
  89. try {
  90. const text = await fetchRepoSize();
  91. const formattedText = text.replace(
  92. /(\d+(\.\d+)?)/g,
  93. "<strong>$1</strong>",
  94. );
  95. const sizeElement = document.createElement("div");
  96. sizeElement.className = "mt-2";
  97.  
  98. sizeElement.innerHTML = `
  99. <a href="#" data-view-component="true" class="Link Link--muted">
  100. <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-size mr-2">
  101. <path d="M3.333333 8.333333c0 0.208667 0.308667 0.571 1.02 0.927667C5.402667 9.956667 6.742667 10 8 10c1.257333 0 2.597333-0.043333 3.646667-0.7392 0.713067-0.342933 1.02-0.683733 1.02-0.927667v-1.481067C11.844267 7.747733 9.209867 8 8 8s-3.844267-0.445333-5.018667-1.142133V8.333333z m9.248 1.931267C11.844267 10.963733 9.209867 11.2 8 11.2s-3.844267-0.445333-5.018667-1.142133V11.946667c0 0.208667 0.308667 0.571 1.02 0.927467C5.402667 13.011733 6.742667 13.2 8 13.2c1.257333 0 2.597333-0.043333 3.646667-0.7392 0.713067-0.342933 1.02-0.683733 1.02-0.927467v-1.481067zM2 11.946667V5.333333C2 3.439467 4.686667 2 8 2s6 1.439467 6 3.333333v6.613334c0 1.893867-2.686667 3.333333-6 3.333333s-6-1.439467-6-3.333333z m6-5.12c1.257333 0 2.597333-0.043333 3.646667-0.7392C12.687467 5.705067 13 5.364267 13 5.12c0-0.208667-0.308667-0.571-1.02-0.927467C10.597333 3.522667 9.257333 3.333333 8 3.333333c-1.257333 0-2.597333 0.043333-3.646667 0.7392C3.312533 4.126933 3 4.467733 3 4.712c0 0.208667 0.308667 0.571 1.02 0.927467C5.402667 6.1568 6.742667 6.333333 8 6.333333z"></path>
  102. </svg>
  103. ${formattedText}
  104. </a>
  105. `;
  106.  
  107. const mt2Divs = document.querySelectorAll("div.mt-2");
  108.  
  109. mt2Divs.forEach((div) => {
  110. if (div.querySelector("svg.octicon.octicon-repo-forked.mr-2")) {
  111. div.insertAdjacentElement("afterend", sizeElement);
  112. return;
  113. }
  114. });
  115. } catch (error) {
  116. console.error("Error displaying repo size:", error);
  117. }
  118. }
  119.  
  120. displayRepoSize();
  121. })();