Gitea Downloader Plugin

一个用于下载Gitea代码库中所有代码的Python插件。

import os
import sys
import requests
import subprocess
import argparse
from datetime import datetime

class GiteaDownloader:
    def __init__(self, base_url, token=None, output_dir="."):
        self.base_url = base_url.rstrip('/')
        self.token = token
        self.output_dir = output_dir
        os.makedirs(self.output_dir, exist_ok=True)
    
    def get_headers(self):
        headers = {"Accept": "application/json"}
        if self.token:
            headers["Authorization"] = f"token {self.token}"
        return headers
    
    def get_repos(self):
        """获取所有代码库列表"""
        repos = []
        page = 1
        per_page = 100
        
        while True:
            url = f"{self.base_url}/api/v1/user/repos?page={page}&per_page={per_page}"
            response = requests.get(url, headers=self.get_headers())
            
            if response.status_code != 200:
                print(f"Error fetching repos: {response.status_code}")
                print(response.json())
                break
            
            page_repos = response.json()
            if not page_repos:
                break
            
            repos.extend(page_repos)
            page += 1
        
        return repos
    
    def download_repo(self, repo):
        """下载单个代码库"""
        repo_name = repo['name']
        repo_url = repo['clone_url']
        
        # 如果提供了token,使用带认证的URL
        if self.token:
            # 从clone_url中提取基础URL
            if repo_url.startswith('https://'):
                auth_url = repo_url.replace('https://', f'https://oauth2:{self.token}@')
            elif repo_url.startswith('http://'):
                auth_url = repo_url.replace('http://', f'http://oauth2:{self.token}@')
            else:
                auth_url = repo_url
        else:
            auth_url = repo_url
        
        repo_path = os.path.join(self.output_dir, repo_name)
        
        print(f"Downloading {repo_name}...")
        
        # 检查目录是否存在,如果存在则更新
        if os.path.exists(repo_path):
            # 如果是git仓库,执行pull
            if os.path.exists(os.path.join(repo_path, '.git')):
                print(f"Repository {repo_name} already exists, updating...")
                result = subprocess.run(
                    ['git', 'pull'],
                    cwd=repo_path,
                    capture_output=True,
                    text=True
                )
                if result.returncode == 0:
                    print(f"Updated {repo_name} successfully")
                    # 获取所有分支
                    fetch_result = subprocess.run(
                        ['git', 'fetch', '--all'],
                        cwd=repo_path,
                        capture_output=True,
                        text=True
                    )
                    if fetch_result.returncode == 0:
                        print(f"Fetched all branches for {repo_name}")
                    else:
                        print(f"Error fetching branches for {repo_name}: {fetch_result.stderr}")
                else:
                    print(f"Error updating {repo_name}: {result.stderr}")
            else:
                print(f"Directory {repo_name} exists but is not a git repository, skipping...")
        else:
            # 克隆新仓库
            result = subprocess.run(
                ['git', 'clone', auth_url, repo_path],
                capture_output=True,
                text=True
            )
            if result.returncode == 0:
                print(f"Cloned {repo_name} successfully")
                # 获取所有分支
                fetch_result = subprocess.run(
                    ['git', 'fetch', '--all'],
                    cwd=repo_path,
                    capture_output=True,
                    text=True
                )
                if fetch_result.returncode == 0:
                    print(f"Fetched all branches for {repo_name}")
                else:
                    print(f"Error fetching branches for {repo_name}: {fetch_result.stderr}")
            else:
                print(f"Error cloning {repo_name}: {result.stderr}")
    
    def download_all_repos(self):
        """下载所有代码库"""
        print(f"Fetching repositories from {self.base_url}...")
        repos = self.get_repos()
        print(f"Found {len(repos)} repositories")
        
        for repo in repos:
            self.download_repo(repo)
        
        print("\nAll repositories downloaded successfully!")

def main():
    parser = argparse.ArgumentParser(description="Download all repositories from a Gitea server")
    parser.add_argument("base_url", help="Gitea server base URL (e.g., https://gitea.example.com)")
    parser.add_argument("--token", help="Gitea API token for authentication")
    parser.add_argument("--output", default=".", help="Output directory for downloaded repositories")
    
    args = parser.parse_args()
    
    # 如果output目录不存在,创建它
    os.makedirs(args.output, exist_ok=True)
    
    downloader = GiteaDownloader(
        base_url=args.base_url,
        token=args.token,
        output_dir=args.output
    )
    
    downloader.download_all_repos()

if __name__ == "__main__":
    main()

功能特性

  • 自动获取Gitea服务器上的所有代码库
  • 支持使用API token进行身份验证
  • 支持克隆新仓库和更新现有仓库
  • 简单易用的命令行接口

依赖项

  • Python 3.6+
  • requests 库
  • Git 命令行工具

安装依赖

 

使用方法

基本用法

python gitea_downloader.py https://gitea.example.com

使用API token

python gitea_downloader.py https://gitea.example.com --token YOUR_API_TOKEN

指定输出目录

python gitea_downloader.py https://gitea.example.com --output /path/to/download

完整示例

python gitea_downloader.py https://gitea.example.com --token YOUR_API_TOKEN --output ./repos

API Token 获取方法

  1. 登录Gitea服务器
  2. 进入用户设置页面
  3. 点击"应用"选项卡
  4. 生成新的API token,设置适当的权限
  5. 复制生成的token并在命令中使用

注意事项

  • 确保Git命令行工具已安装并添加到系统路径
  • 对于私有仓库,必须提供有效的API token
  • 下载速度取决于网络连接和仓库大小
  • 大型仓库可能需要较长时间下载

错误处理

  • 如果遇到认证错误,请检查API token是否有效
  • 如果遇到网络错误,请检查网络连接和Gitea服务器状态
  • 如果遇到Git错误,请确保Git命令行工具正常工作

示例输出

Fetching repositories from https://gitea.example.com...
Found 5 repositories
Downloading repo1...
Cloned repo1 successfully
Downloading repo2...
Cloned repo2 successfully
Downloading repo3...
Repository repo3 already exists, updating...
Updated repo3 successfully

All repositories downloaded successfully!
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐