2
2
import difflib
3
3
import json
4
4
import os
5
- import subprocess
6
5
import tempfile
6
+ import zipfile
7
+ from pathlib import Path
7
8
9
+ import aiohttp
8
10
from channels .generic .websocket import AsyncWebsocketConsumer
9
- from git import Repo
10
11
11
12
from website .utils import (
12
13
compare_model_fields ,
13
14
cosine_similarity ,
14
15
extract_django_models ,
15
16
extract_function_signatures_and_content ,
16
17
generate_embedding ,
18
+ git_url_to_zip_url ,
17
19
)
18
20
19
21
@@ -46,6 +48,8 @@ async def receive(self, text_data):
46
48
type2 = data .get ("type2" ) # 'github' or 'zip'
47
49
repo1 = data .get ("repo1" ) # GitHub URL or ZIP file path
48
50
repo2 = data .get ("repo2" ) # GitHub URL or ZIP file path
51
+ branch1 = data .get ("branch1" ) # Branch name for the first repository
52
+ branch2 = data .get ("branch2" ) # Branch name for the second repository
49
53
50
54
if not repo1 or not repo2 or not type1 or not type2 :
51
55
await self .send (
@@ -58,12 +62,14 @@ async def receive(self, text_data):
58
62
return
59
63
60
64
try :
61
- # Create a temporary directory for repository processing
62
65
temp_dir = tempfile .mkdtemp ()
63
66
64
67
# Download or extract the repositories
65
- repo1_path = await self .download_or_extract (repo1 , type1 , temp_dir , "repo1" )
66
- repo2_path = await self .download_or_extract (repo2 , type2 , temp_dir , "repo2" )
68
+
69
+ zip_repo1 = git_url_to_zip_url (repo1 , branch1 )
70
+ zip_repo2 = git_url_to_zip_url (repo2 , branch2 )
71
+ repo1_path = await self .download_or_extract (zip_repo1 , type1 , temp_dir , "repo1" )
72
+ repo2_path = await self .download_or_extract (zip_repo2 , type2 , temp_dir , "repo2" )
67
73
68
74
# Process similarity analysis
69
75
matching_details = await self .run_similarity_analysis (repo1_path , repo2_path )
@@ -88,7 +94,10 @@ async def receive(self, text_data):
88
94
# Handle unexpected errors and send an error message
89
95
await self .send (
90
96
json .dumps (
91
- {"status" : "error" , "error" : "Please check the repositories and try again." }
97
+ {
98
+ "status" : "error" ,
99
+ "error" : "Please check the repositories/branches and try again." ,
100
+ }
92
101
)
93
102
)
94
103
await self .close ()
@@ -125,29 +134,62 @@ async def download_or_extract(self, source, source_type, temp_dir, repo_name):
125
134
"""
126
135
dest_path = os .path .join (temp_dir , repo_name )
127
136
if source_type == "github" :
128
- try :
129
- # Clone the GitHub repository
130
- process = await self .clone_github_repo (source , dest_path )
131
- return dest_path
132
- except subprocess .CalledProcessError as e :
133
- # Handle errors during the cloning process
134
- raise Exception (f"Error cloning GitHub repository: { e .stderr .decode ('utf-8' )} " )
135
- except Exception as e :
136
- # General error handling for unexpected issues
137
- raise Exception (f"Unexpected error during GitHub cloning: { str (e )} " )
137
+ repo_path = await self .download_and_extract_zip (source , temp_dir , repo_name )
138
+ return repo_path
138
139
139
140
elif source_type == "zip" :
140
- # Handle ZIP extraction (Add your ZIP handling logic here)
141
- pass
141
+ # Assume `repo_url_or_path` is a direct path to a ZIP file
142
+ repo_path = await self .extract_zip (source , temp_dir , repo_name )
143
+ return repo_path
142
144
143
145
return dest_path
144
146
145
- async def clone_github_repo (self , repo_url , dest_path ):
147
+ async def download_and_extract_zip (self , zip_url , temp_dir , repo_name ):
148
+ """
149
+ Downloads and extracts a ZIP file from a URL.
150
+ """
151
+ try :
152
+ async with aiohttp .ClientSession () as session :
153
+ async with session .get (zip_url ) as response :
154
+ if response .status != 200 :
155
+ raise Exception (
156
+ f"Failed to download ZIP file. Status code: { response .status } "
157
+ )
158
+
159
+ # Extract the ZIP file
160
+ zip_file_path = Path (temp_dir ) / f"{ repo_name } .zip"
161
+ with open (zip_file_path , "wb" ) as zip_file :
162
+ zip_data = await response .read ()
163
+ zip_file .write (zip_data )
164
+
165
+ # Extract to a directory
166
+ extraction_path = Path (temp_dir ) / repo_name
167
+ try :
168
+ with zipfile .ZipFile (zip_file_path , "r" ) as zip_ref :
169
+ zip_ref .extractall (extraction_path )
170
+ except zipfile .BadZipFile as e :
171
+ raise Exception (f"Failed to extract ZIP file: { e } " )
172
+
173
+ return str (extraction_path )
174
+ except Exception as e :
175
+ raise
176
+
177
+ async def extract_zip (self , zip_file_path , temp_dir , repo_name ):
146
178
"""
147
- Clones a GitHub repository asynchronously.
179
+ Extracts a local ZIP file.
180
+
181
+ Args:
182
+ zip_file_path (str): Path to the local ZIP file.
183
+ temp_dir (str): Temporary directory to store files.
184
+ repo_name (str): Repository identifier.
185
+
186
+ Returns:
187
+ str: Path to the extracted contents.
148
188
"""
149
- loop = asyncio .get_event_loop ()
150
- await loop .run_in_executor (None , Repo .clone_from , repo_url , dest_path )
189
+ extraction_path = Path (temp_dir ) / repo_name
190
+ with zipfile .ZipFile (zip_file_path , "r" ) as zip_ref :
191
+ zip_ref .extractall (extraction_path )
192
+ return str (extraction_path )
151
193
152
194
def process_similarity_analysis (self , repo1_path , repo2_path ):
153
195
"""
0 commit comments