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)