File size: 3,329 Bytes
2ea3a9e
 
 
 
 
484d85d
2ea3a9e
484d85d
 
 
4d5a12f
2ea3a9e
 
 
 
 
 
 
4d5a12f
 
 
 
 
 
2ea3a9e
 
 
 
 
db88506
2ea3a9e
16d59fe
2ea3a9e
 
 
16d59fe
4d5a12f
2ea3a9e
 
 
4d5a12f
16d59fe
2ea3a9e
470e738
2ea3a9e
 
 
 
 
 
 
 
 
 
470e738
2ea3a9e
 
 
 
4d5a12f
2ea3a9e
 
 
470e738
2ea3a9e
 
 
 
470e738
4d5a12f
2ea3a9e
 
 
 
 
470e738
2ea3a9e
470e738
2ea3a9e
6dcefc4
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import os
import tempfile
from flask import Flask, render_template, request, send_file, flash
from git import Repo
import shutil
import zipfile
import re

app = Flask(__name__)

def download_github_files(repo_url, file_paths, github_token=None):
    """从GitHub仓库下载指定路径的文件,并打包成zip。"""
    try:
        temp_dir = tempfile.mkdtemp()
        repo_name = repo_url.split('/')[-1].replace(".git", "")
        local_repo_path = os.path.join(temp_dir, repo_name)
        
        # 克隆仓库
        if github_token:
            repo_url_with_token = repo_url.replace("https://", f"https://{github_token}@")
            Repo.clone_from(repo_url_with_token, local_repo_path)
        else:
            Repo.clone_from(repo_url, local_repo_path)

        zip_file_path = os.path.join(temp_dir, f"{repo_name}_files.zip")
        with zipfile.ZipFile(zip_file_path, 'w', zipfile.ZIP_DEFLATED) as zf:
            for file_path in file_paths:
                abs_file_path = os.path.join(local_repo_path, file_path)
                if os.path.exists(abs_file_path) and os.path.isfile(abs_file_path):
                    zf.write(abs_file_path, os.path.basename(abs_file_path))
                elif os.path.exists(abs_file_path) and os.path.isdir(abs_file_path):
                    for root, dirs, files in os.walk(abs_file_path):
                        for file in files:
                            file_abs_path = os.path.join(root, file)
                            zf.write(file_abs_path, os.path.relpath(file_abs_path, local_repo_path))

        shutil.rmtree(local_repo_path)
        if os.path.exists(zip_file_path) and os.path.getsize(zip_file_path) > 0:
            return zip_file_path, f"{repo_name}_files.zip"
        else:
            return None, None
    except Exception:
        return None, None

def parse_github_url(url):
    """解析 GitHub URL,提取仓库 URL 和文件路径。"""
    match = re.match(r'https://github\.com/([^/]+)/([^/]+)/tree/([^/]+)(.*)', url)
    if match:
        owner, repo, branch, path = match.groups()
        repo_url = f'https://github.com/{owner}/{repo}.git'
        file_paths = [path.lstrip('/')] if path else []
        return repo_url, file_paths
    else:
        return None, None

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        repo_path = request.form.get('repo_path')
        github_token = request.form.get('github_token')
        if not repo_path:
            flash('请提供 GitHub 链接', 'error')
            return render_template('index.html')

        repo_url, file_paths = parse_github_url(repo_path)
        if not repo_url:
             flash('无效的 GitHub 链接', 'error')
             return render_template('index.html')

        zip_path, zip_filename = download_github_files(repo_url, file_paths, github_token)
        if zip_path:
            return send_file(zip_path, as_attachment=True, download_name=zip_filename)
        else:
            flash('下载失败,请检查链接和文件路径。', 'error')
            return render_template('index.html')

    return render_template('index.html')

if __name__ == '__main__':
    port = int(os.getenv("PORT", 5000)) # 获取环境变量 PORT,默认为 5000
    app.run(debug=False, host="0.0.0.0", port=port)