Github项目批量删除

Github项目批量删除,fork的项目太多了,注意:需要先申请操作token,申请地址https://github.com/settings/tokens,请至少选择Delete Repos,如果频繁出现删除失败,请重新生成token(github有限制)

  1. // ==UserScript==
  2. // @name Github项目批量删除
  3. // @namespace https://github.com/mengyou658/github-repositories-manage
  4. // @version 1.1.7
  5. // @description Github项目批量删除,fork的项目太多了,注意:需要先申请操作token,申请地址https://github.com/settings/tokens,请至少选择Delete Repos,如果频繁出现删除失败,请重新生成token(github有限制)
  6. // @author yunchaoq/mengyou658
  7. // @license GPL License
  8. // @match *://github.com/*
  9. // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
  10. // @require https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/layer.min.js
  11. // @resource layerCss https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/theme/default/layer.min.css
  12. // @grant GM_addStyle
  13. // @grant GM_setClipboard
  14. // @grant GM_getResourceText
  15. // ==/UserScript==
  16. (function () {
  17. 'use strict';
  18. GM_addStyle(GM_getResourceText('layerCss'))
  19. // GM_addStyle(GM_getResourceText('layuiCss'))
  20. var location = window.location.href;
  21. var pathname = window.location.pathname;
  22. var userName = pathname.replace("/", "");
  23. var checkList = [];
  24. var tmpCode = localStorage.getItem("gitto");
  25.  
  26. var detailPageBodyTmp = $('ul[class*="UnderlineNav-body"]');
  27. var detailPageFlag = detailPageBodyTmp.length && detailPageBodyTmp.find('span[data-content="Settings"]').length;
  28. let homePageFlag = location.indexOf("tab=repositories") > -1;
  29. if (homePageFlag || detailPageFlag) {
  30. init();
  31. }
  32.  
  33. function init() {
  34.  
  35. if (homePageFlag) {
  36. homePageInit();
  37. }
  38. if (detailPageFlag) {
  39. detailPageInit();
  40. }
  41.  
  42. tipsShow();
  43. $('#user-repositories-code').on('click', function () {
  44. tipsShow();
  45. openMsg();
  46. });
  47. if (!tmpCode) {
  48. openMsg();
  49. }
  50.  
  51. }
  52.  
  53. function openMsg() {
  54. layer.prompt({
  55. title: '输入申请的token,并点击确认,<a href="https://github.com/settings/tokens" target="_blank">点击这里是申请,请至少选择Delete Repos,注意如果频繁出现删除失败,请重新生成token</a>',
  56. formType: 1
  57. }, function (token, index) {
  58. if (token) {
  59. tmpCode = token;
  60. localStorage.setItem('gitto', tmpCode);
  61. layer.closeAll();
  62. }
  63. });
  64. }
  65.  
  66. function tipsShow() {
  67. layer.tips('提示:先输入token,点击<a href="https://github.com/settings/tokens" target="_blank" style="color: red;">这里是申请</a>,请至少选择Delete Repos,注意如果频繁出现删除失败,请重新生成token', '#user-repositories-code', {
  68. tips: [1,'#2ea44f'] //还可配置颜色
  69. ,tipsMore:true
  70. ,time: 0,
  71. });
  72. }
  73.  
  74. function homePageInit() {
  75. $(".UnderlineNav-body:first").append('<a href="javascript:void(0);" id="user-repositories-code" class="UnderlineNav-item btn btn-primary " style="background-color: #2ea44f; margin-right: 10px;">输入token</a>');
  76.  
  77. $("#user-repositories-list li").each((id, it) => {
  78. $(it).append('<input type="checkbox" class="user-repositories-list-checkbox" name="repo-check" value="" >');
  79. });
  80.  
  81. $("#user-repositories-list li").on('click', function () {
  82.  
  83. let find = $(this).find('.user-repositories-list-checkbox');
  84. var href = $(this).find('.wb-break-all').find('a').attr('href');
  85. if (href.indexOf(pathname) > -1) {
  86. // var repoName = href.replace(pathname + "/", "");
  87. let index = checkList.indexOf(href);
  88. if (index > -1) {
  89. find.prop('checked', false);
  90. checkList.splice(index, 1);
  91. } else {
  92. find.prop('checked', true);
  93. checkList.push(href);
  94. }
  95. if (!$('#user-repositories-delete').length && checkList.length) {
  96. if (homePageFlag) {
  97. $(".UnderlineNav-body:first").append('<a href="javascript:void(0);" id="user-repositories-delete" class="UnderlineNav-item btn btn-primary " style="background-color: #2ea44f;">批量删除</a>');
  98. $("#user-repositories-delete").on('click', function () {
  99. if (!tmpCode) {
  100. openMsg();
  101. return;
  102. }
  103. var resList = {};
  104. var count = 0;
  105. var promiseList = [];
  106. checkList.forEach((it) => {
  107. var tmpPromise = new Promise((resolve, reject) => {
  108. var url = 'https://api.github.com/repos' + it
  109. $.ajax({
  110. url: url,
  111. method: 'DELETE',
  112. "headers": {
  113. "Accept": "application/vnd.github.v3+json",
  114. "Authorization": "token " + tmpCode
  115. },
  116. success: function (data, textStatus, jqXHR) {
  117. resList[it] = true;
  118. count++;
  119. resolve(count);
  120. }, error: function (XMLHttpRequest, textStatus, errorThrown) {
  121. resList[it] = false;
  122. count++;
  123. resolve(count);
  124. }
  125. })
  126. });
  127. promiseList.push(tmpPromise);
  128. })
  129.  
  130. Promise.all(promiseList).then((count) => {
  131. var resTxt = "";
  132. for (var i in resList) {
  133. if (resList[i] == true) {
  134. resTxt += " 删除【" + i + "】成功<br />";
  135. }
  136. }
  137. for (var ii in resList) {
  138. if (resList[ii] == false) {
  139. resTxt += " 删除【" + ii + "】失败<br />";
  140. }
  141. }
  142. checkList = [];
  143. layer.msg('删除结果:<br />' + resTxt, function () {
  144. window.location.reload();
  145. });
  146. });
  147.  
  148. });
  149. }
  150.  
  151. } else {
  152. if (!checkList.length) {
  153. $("#user-repositories-delete").remove();
  154. }
  155. }
  156.  
  157.  
  158. }
  159. });
  160.  
  161. }
  162.  
  163. function detailPageInit() {
  164. detailPageBodyTmp.find('li:last').append('<a href="javascript:void(0);" id="user-repositories-code" class="UnderlineNav-item btn btn-primary " style="background-color: #2ea44f; margin-right: 10px;">输入token</a>');
  165. if (!tmpCode) {
  166. openMsg();
  167. }
  168. detailPageBodyTmp.find('li:last').append('<a href="javascript:void(0);" id="user-repositories-delete" class="UnderlineNav-item btn btn-primary " style="background-color: #2ea44f;">快速删除当前仓库</a>');
  169. $("#user-repositories-delete").on('click', function () {
  170. if (!tmpCode) {
  171. openMsg();
  172. return;
  173. }
  174. var resList = {};
  175. var count = 0;
  176. var promiseList = [];
  177. var it = $('a[data-pjax="#js-repo-pjax-container"]').attr('href')
  178. var tmpPromise = new Promise((resolve, reject) => {
  179. var url = 'https://api.github.com/repos' + it
  180. $.ajax({
  181. url: url,
  182. method: 'DELETE',
  183. "headers": {
  184. "Accept": "application/vnd.github.v3+json",
  185. "Authorization": "token " + tmpCode
  186. },
  187. success: function (data, textStatus, jqXHR) {
  188. resList[it] = true;
  189. count++;
  190. resolve(count);
  191. }, error: function (XMLHttpRequest, textStatus, errorThrown) {
  192. resList[it] = false;
  193. count++;
  194. resolve(count);
  195. }
  196. })
  197. });
  198. promiseList.push(tmpPromise);
  199.  
  200. Promise.all(promiseList).then((count) => {
  201. var resTxt = "";
  202. for (var i in resList) {
  203. if (resList[i] == true) {
  204. resTxt += " 删除【" + i + "】成功<br />";
  205. }
  206. }
  207. for (var ii in resList) {
  208. if (resList[ii] == false) {
  209. resTxt += " 删除【" + ii + "】失败<br />";
  210. }
  211. }
  212. layer.msg('<p style="color:red">注意如果频繁出现删除失败,请重新生成token</p>删除结果:<br />' + resTxt, function () {
  213. window.location.reload();
  214. });
  215. });
  216.  
  217. });
  218. }
  219.  
  220. })();