stepenZEN commited on
Commit
dcc65ec
·
verified ·
1 Parent(s): 72d5b0c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -0
app.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, send_file, request, render_template
2
+ import io
3
+ import zipfile
4
+ import os
5
+
6
+ app = Flask(__name__)
7
+
8
+ import subprocess
9
+ import re
10
+ from urllib.parse import urlparse, urlunparse
11
+ import shutil
12
+
13
+ def sanitize_git_url(url):
14
+ """Sanitizes a Git repository URL."""
15
+
16
+ # Validate URL structure using urllib.parse
17
+ try:
18
+ parsed_url = urlparse(url)
19
+ if not all([parsed_url.scheme, parsed_url.netloc]):
20
+ print(f"Error: Invalid URL structure: {url}")
21
+ return None
22
+ if parsed_url.scheme not in ("https", "http", "git", "ssh"):
23
+ print(f"Error: Invalid URL scheme: {parsed_url.scheme}")
24
+ return None
25
+ except Exception:
26
+ print(f"Error: Could not parse url: {url}")
27
+ return None
28
+
29
+
30
+ # check input for suspicious characters
31
+ if re.search(r'[;&|]', url):
32
+ print(f"Error: Suspicious character in url {url}")
33
+ return None
34
+
35
+
36
+ # Normalize the url. Remove trailing slashes and .git suffix
37
+ normalized_url = url.rstrip("/").rstrip(".git")
38
+
39
+ return normalized_url
40
+
41
+
42
+ def git_clone(repo_url):
43
+ """Clones a Git repository, using the repo name as the destination folder."""
44
+
45
+ sanitized_url = sanitize_git_url(repo_url)
46
+ if not sanitized_url:
47
+ return # If sanitize_git_url returned None, don't continue.
48
+
49
+ try:
50
+ # Extract the repository name from the URL
51
+ repo_name = extract_repo_name(sanitized_url)
52
+ if not repo_name:
53
+ print(f"Error: Unable to extract repository name from URL: {repo_url}")
54
+ return
55
+
56
+ destination_dir = repo_name # Use the extracted name for the destination folder
57
+ if os.path.isdir(destination_dir):
58
+ return repo_name
59
+
60
+ subprocess.run(
61
+ ["git", "clone", sanitized_url, destination_dir],
62
+ check=True,
63
+ capture_output=True,
64
+ text=True
65
+ )
66
+ print(f"Successfully cloned {sanitized_url} to {destination_dir}")
67
+ return repo_name
68
+
69
+ except subprocess.CalledProcessError as e:
70
+ print(f"Error cloning {sanitized_url}:")
71
+ print(f" Return code: {e.returncode}")
72
+ print(f" Stdout:\n{e.stdout}")
73
+ print(f" Stderr:\n{e.stderr}")
74
+
75
+ def extract_repo_name(repo_url):
76
+ """Extracts the repository name from a Git URL."""
77
+ # Example formats:
78
+ # https://github.com/user/repo.git
79
+ # git@github.com:user/repo.git
80
+ # https://gitlab.com/user/repo
81
+ match = re.search(r"([^/:]+)\/?$", repo_url.rstrip(".git/"))
82
+ if match:
83
+ return match.group(1)
84
+ else:
85
+ return None
86
+
87
+ def zip_folder_to_buffer(folder_path):
88
+ """
89
+ Zips a folder and returns the zipped content in a BytesIO buffer.
90
+
91
+ Args:
92
+ folder_path: The path to the folder you want to zip.
93
+
94
+ Returns:
95
+ A io.BytesIO buffer containing the zipped folder data, or None if
96
+ there is an error.
97
+ """
98
+ try:
99
+ buffer = io.BytesIO()
100
+ with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
101
+ for root, _, files in os.walk(folder_path):
102
+ for file in files:
103
+ file_path = os.path.join(root, file)
104
+ arcname = os.path.relpath(file_path, folder_path)
105
+ zf.write(file_path, arcname=arcname)
106
+ buffer.seek(0) # Reset buffer position to the beginning for reading
107
+ return buffer
108
+ except Exception as e:
109
+ print(f"Error creating zip file: {e}")
110
+ return None
111
+
112
+
113
+ @app.route('/', methods=['GET', 'POST'])
114
+ def index():
115
+ if request.method == 'POST':
116
+ # folder_to_zip = "./my_folder" # Replace with the actual folder path
117
+ # deltemp = remove_all_files_and_directories("temp_folder") #clean temp folder
118
+
119
+ # # Create an example folder and files
120
+ # os.makedirs(folder_to_zip, exist_ok=True)
121
+ # with open(os.path.join(folder_to_zip, "file1.txt"), "w") as f:
122
+ # f.write("This is file1")
123
+ # with open(os.path.join(folder_to_zip, "file2.txt"), "w") as f:
124
+ # f.write("This is file2")
125
+
126
+ repo_url = request.form['giturl'] #"https://huggingface.co/spaces/stepenZEN/gitgud" # Example repo, can be very large
127
+
128
+ folder_to_zip = git_clone(repo_url)
129
+ # if not folder_to_zip:
130
+ # return
131
+
132
+ zipped_buffer = zip_folder_to_buffer(folder_to_zip)
133
+ if zipped_buffer:
134
+ # Send the zipped buffer as a file download
135
+ response = send_file(
136
+ zipped_buffer,
137
+ mimetype="application/zip", # Important: Set the correct MIME type
138
+ as_attachment=True,
139
+ download_name=f"{folder_to_zip}.zip" # Optional: Sets the suggested file name
140
+ )
141
+ # Clean up the example folder
142
+ # os.remove(os.path.join(folder_to_zip, "file1.txt"))
143
+ # os.remove(os.path.join(folder_to_zip, "file2.txt"))
144
+ # os.rmdir(folder_to_zip)
145
+ # shutil.rmtree(folder_to_zip)
146
+ return response
147
+ else:
148
+ return "Failed to create zip file", 500
149
+
150
+ return render_template('form.html') # Render form template
151
+
152
+ if __name__ == '__main__':
153
+ # app.run(debug=True, port=5500)
154
+