File size: 5,079 Bytes
dcc65ec 729cec6 43eeda5 408d354 dcc65ec |
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
from flask import Flask, send_file, request, render_template
import io
import zipfile
import os
app = Flask(__name__)
import subprocess
import re
from urllib.parse import urlparse, urlunparse
import shutil
def sanitize_git_url(url):
"""Sanitizes a Git repository URL."""
# Validate URL structure using urllib.parse
try:
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
print(f"Error: Invalid URL structure: {url}")
return None
if parsed_url.scheme not in ("https", "http", "git", "ssh"):
print(f"Error: Invalid URL scheme: {parsed_url.scheme}")
return None
except Exception:
print(f"Error: Could not parse url: {url}")
return None
# check input for suspicious characters
if re.search(r'[;&|]', url):
print(f"Error: Suspicious character in url {url}")
return None
# Normalize the url. Remove trailing slashes and .git suffix
normalized_url = url.rstrip("/").rstrip(".git")
return normalized_url
def git_clone(repo_url):
"""Clones a Git repository, using the repo name as the destination folder."""
sanitized_url = sanitize_git_url(repo_url)
if not sanitized_url:
return # If sanitize_git_url returned None, don't continue.
try:
# Extract the repository name from the URL
repo_name = extract_repo_name(sanitized_url)
if not repo_name:
print(f"Error: Unable to extract repository name from URL: {repo_url}")
return
destination_dir = repo_name # Use the extracted name for the destination folder
if os.path.isdir(destination_dir):
return repo_name
subprocess.run(
["git", "clone", sanitized_url, destination_dir],
check=True,
capture_output=True,
text=True
)
print(f"Successfully cloned {sanitized_url} to {destination_dir}")
return repo_name
except subprocess.CalledProcessError as e:
print(f"Error cloning {sanitized_url}:")
print(f" Return code: {e.returncode}")
print(f" Stdout:\n{e.stdout}")
print(f" Stderr:\n{e.stderr}")
def extract_repo_name(repo_url):
"""Extracts the repository name from a Git URL."""
# Example formats:
# https://github.com/user/repo.git
# [email protected]:user/repo.git
# https://gitlab.com/user/repo
match = re.search(r"([^/:]+)\/?$", repo_url.rstrip(".git/"))
if match:
return match.group(1)
else:
return None
def zip_folder_to_buffer(folder_path):
"""
Zips a folder and returns the zipped content in a BytesIO buffer.
Args:
folder_path: The path to the folder you want to zip.
Returns:
A io.BytesIO buffer containing the zipped folder data, or None if
there is an error.
"""
try:
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
for root, _, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, folder_path)
zf.write(file_path, arcname=arcname)
buffer.seek(0) # Reset buffer position to the beginning for reading
return buffer
except Exception as e:
print(f"Error creating zip file: {e}")
return None
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# folder_to_zip = "./my_folder" # Replace with the actual folder path
# deltemp = remove_all_files_and_directories("temp_folder") #clean temp folder
# # Create an example folder and files
# os.makedirs(folder_to_zip, exist_ok=True)
# with open(os.path.join(folder_to_zip, "file1.txt"), "w") as f:
# f.write("This is file1")
# with open(os.path.join(folder_to_zip, "file2.txt"), "w") as f:
# f.write("This is file2")
repo_url = request.form['giturl'] #"https://huggingface.co/spaces/stepenZEN/gitgud" # Example repo, can be very large
folder_to_zip = git_clone(repo_url)
# if not folder_to_zip:
# return
zipped_buffer = zip_folder_to_buffer(folder_to_zip)
if zipped_buffer:
# Send the zipped buffer as a file download
response = send_file(
zipped_buffer,
mimetype="application/zip", # Important: Set the correct MIME type
as_attachment=True,
download_name=f"{folder_to_zip}.zip" # Optional: Sets the suggested file name
)
# Clean up the example folder
# os.remove(os.path.join(folder_to_zip, "file1.txt"))
# os.remove(os.path.join(folder_to_zip, "file2.txt"))
# os.rmdir(folder_to_zip)
# shutil.rmtree(folder_to_zip)
return response
else:
return "Failed to create zip file", 500
return render_template('form.html') # Render form template
if __name__ == '__main__':
# app = create_app()
app.run(debug=True, port=5500)
|