您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Backup GitHub repositories directly from user profile page
// ==UserScript== // @name Backup GitHub Repository // @namespace Violentmonkey Scripts // @version 2.1 // @description Backup GitHub repositories directly from user profile page // @author maanimis // @match https://github.com/*?tab=repositories // @grant GM_registerMenuCommand // @grant GM_download // @run-at document-end // @license MIT // @require https://update.gf.qytechs.cn/scripts/530526/1558038/ProgressUI-Module.js // ==/UserScript== (function() { 'use strict'; function extractBaseUrl(urlString = location.href) { const urlObj = new URL(urlString); return `${urlObj.origin}${urlObj.pathname.split("/").slice(0, 2).join("/")}`; } function extractRepoData() { const ulElement = document.querySelector('ul[data-filterable-for="your-repos-filter"][data-filterable-type="substring"]'); if (!ulElement){ alert("ulElement not found!!") return } const liElements = ulElement.querySelectorAll("li"); const liArray = Array.from(liElements); return liArray.map(li => { const repoLink = li.querySelector('a[itemprop="name codeRepository"]'); if (!repoLink) return null; const repository = repoLink.href; const name = repoLink.textContent.trim(); const language = li.querySelector('span[itemprop="programmingLanguage"]')?.textContent.trim(); const lastUpdated = li.querySelector("relative-time")?.getAttribute("datetime"); const isPublic = li.querySelector(".Label.Label--secondary")?.textContent.trim() === "Public"; const downloadLinks = [ `${repository}/archive/refs/heads/master.zip`, `${repository}/archive/refs/heads/main.zip` ]; return { name, language, lastUpdated, isPublic, repository, downloadLinks }; }).filter(Boolean); } function downloadRepos() { const repos = extractRepoData(); if (repos.length === 0) { ProgressUI.showQuick('No repositories found on this page', { percent: 100, theme: 'dark', duration: 3000 }); return; } const progress = new ProgressUI({ position: 'bottom-right', theme: 'dark', title: 'GitHub Repository Downloader', closable: true, width: '350px', }); let downloadedCount = 0; let failedCount = 0; const totalCount = repos.length; progress.update(`Starting download of ${totalCount} repositories...`, 0); repos.forEach((repo, index) => { const mainZipUrl = repo.downloadLinks[1]; const masterZipUrl = repo.downloadLinks[0]; setTimeout(() => { progress.update(`Downloading ${repo.name} (${index + 1}/${totalCount})...`, (index / totalCount) * 100); GM_download({ url: mainZipUrl, name: `${repo.name}-main.zip`, onload: () => { downloadedCount++; updateProgressStatus(progress, downloadedCount, failedCount, totalCount); }, onerror: () => { progress.update(`Trying master branch for ${repo.name}...`, (index / totalCount) * 100); GM_download({ url: masterZipUrl, name: `${repo.name}-master.zip`, onload: () => { downloadedCount++; updateProgressStatus(progress, downloadedCount, failedCount, totalCount); }, onerror: () => { failedCount++; progress.update(`Failed to download ${repo.name}`, (index / totalCount) * 100); updateProgressStatus(progress, downloadedCount, failedCount, totalCount); } }); } }); }, index * 1000); }); } function updateProgressStatus(progress, downloaded, failed, total) { const completed = downloaded + failed; const percent = Math.round((completed / total) * 100); if (completed === total) { if (failed === 0) { progress.update(`All ${total} repositories downloaded successfully!`, 100); } else { progress.update(`Download completed: ${downloaded} successful, ${failed} failed`, 100); } progress.scheduleCleanup(5000); } else { progress.update(`Downloaded: ${downloaded}, Failed: ${failed}, Remaining: ${total - completed}`, percent); } } GM_registerMenuCommand("Download GitHub Repositories", downloadRepos); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址