@@ -78,6 +78,7 @@ def handle(self, *args, **options):
78
78
79
79
total_prs_fetched = 0
80
80
total_prs_added = 0
81
+ total_prs_updated = 0
81
82
82
83
for repo_full_name in all_repos :
83
84
try :
@@ -93,12 +94,16 @@ def handle(self, *args, **options):
93
94
self .stdout .write (f"Reset last_pr_page_processed for { repo_full_name } " )
94
95
95
96
# Fetch closed PRs from the past specified days
96
- prs_fetched , prs_added = self .fetch_and_save_prs (repo , owner , repo_name , days , verbose )
97
+ prs_fetched , prs_added , prs_updated = self .fetch_and_save_prs (repo , owner , repo_name , days , verbose )
97
98
98
99
total_prs_fetched += prs_fetched
99
100
total_prs_added += prs_added
101
+ total_prs_updated += prs_updated
100
102
101
- self .stdout .write (f"Processed { repo_full_name } : Fetched { prs_fetched } PRs, Added { prs_added } new PRs" )
103
+ self .stdout .write (
104
+ f"Processed { repo_full_name } : Fetched { prs_fetched } PRs, "
105
+ f"Added { prs_added } new PRs, Updated { prs_updated } existing PRs"
106
+ )
102
107
103
108
except Exception as e :
104
109
logger .error (f"Error processing repository { repo_full_name } : { str (e )} " , exc_info = True )
@@ -107,7 +112,9 @@ def handle(self, *args, **options):
107
112
self .stdout .write (
108
113
self .style .SUCCESS (
109
114
f"Completed fetching PRs for GSoC repositories. "
110
- f"Total fetched: { total_prs_fetched } , Total added: { total_prs_added } "
115
+ f"Total fetched: { total_prs_fetched } , "
116
+ f"Total added: { total_prs_added } , "
117
+ f"Total updated: { total_prs_updated } "
111
118
)
112
119
)
113
120
@@ -158,10 +165,11 @@ def get_or_create_repo(self, owner, repo_name):
158
165
def fetch_and_save_prs (self , repo , owner , repo_name , days , verbose = False ):
159
166
"""
160
167
Fetch closed pull requests from GitHub API and save them to the database.
161
- Returns a tuple of (total_prs_fetched, total_prs_added).
168
+ Returns a tuple of (total_prs_fetched, total_prs_added, total_prs_updated ).
162
169
"""
163
170
total_prs_fetched = 0
164
171
total_prs_added = 0
172
+ total_prs_updated = 0
165
173
166
174
# Calculate date for filtering
167
175
since_date = timezone .now () - timedelta (days = days )
@@ -211,9 +219,10 @@ def fetch_and_save_prs(self, repo, owner, repo_name, days, verbose=False):
211
219
self .stdout .write (f"Found { merged_count } merged PRs on page { page } " )
212
220
213
221
# Process this page of PRs
214
- prs_added = self .save_prs_to_db (repo , data , verbose )
222
+ prs_added , prs_updated = self .save_prs_to_db (repo , data , verbose )
215
223
total_prs_fetched += len (data )
216
224
total_prs_added += prs_added
225
+ total_prs_updated += prs_updated
217
226
218
227
# Update the repository's last processed page
219
228
repo .last_pr_page_processed = page
@@ -243,26 +252,27 @@ def fetch_and_save_prs(self, repo, owner, repo_name, days, verbose=False):
243
252
)
244
253
self .stdout .write (f"Total merged PRs in database: { merged_prs } " )
245
254
246
- return total_prs_fetched , total_prs_added
255
+ return total_prs_fetched , total_prs_added , total_prs_updated
247
256
248
257
@transaction .atomic
249
258
def save_prs_to_db (self , repo , prs , verbose = False ):
250
259
"""
251
260
Save pull requests to the database.
252
- Returns the number of new PRs added.
261
+ Returns the number of new PRs added and updated .
253
262
"""
254
263
added_count = 0
264
+ updated_count = 0
255
265
skipped_count = 0
256
266
skipped_not_merged = 0
257
267
258
268
self .stdout .write (f"Processing { len (prs )} PRs for { repo .name } " )
259
269
260
270
for pr in prs :
261
- # Check if PR already exists in the database
262
- if GitHubIssue . objects . filter ( issue_id = pr [ "id" ]). exists ( ):
263
- skipped_count += 1
271
+ # Skip PRs that aren't merged
272
+ if not pr . get ( "merged_at" ):
273
+ skipped_not_merged += 1
264
274
if verbose :
265
- self .stdout .write (f"PR { pr ['number' ]} already exists in the database " )
275
+ self .stdout .write (f"PR { pr ['number' ]} is not merged, skipping " )
266
276
continue
267
277
268
278
# Parse dates
@@ -278,11 +288,6 @@ def save_prs_to_db(self, repo, prs, verbose=False):
278
288
if pr ["merged_at" ]:
279
289
merged_at = datetime .strptime (pr ["merged_at" ], "%Y-%m-%dT%H:%M:%SZ" ).replace (tzinfo = pytz .UTC )
280
290
is_merged = True
281
- else :
282
- skipped_not_merged += 1
283
- if verbose :
284
- self .stdout .write (f"PR { pr ['number' ]} is not merged, skipping" )
285
- continue
286
291
287
292
# Try to find the user profile
288
293
user_profile = None
@@ -291,31 +296,41 @@ def save_prs_to_db(self, repo, prs, verbose=False):
291
296
if not user_profile and verbose :
292
297
self .stdout .write (f"No user profile found for { pr ['user' ]['html_url' ]} " )
293
298
294
- # Create the GitHubIssue
295
- github_issue = GitHubIssue (
296
- issue_id = pr ["id" ],
297
- title = pr ["title" ],
298
- body = pr ["body" ] or "" ,
299
- state = pr ["state" ],
300
- type = "pull_request" ,
301
- created_at = created_at ,
302
- updated_at = updated_at ,
303
- closed_at = closed_at ,
304
- merged_at = merged_at ,
305
- is_merged = is_merged ,
306
- url = pr ["html_url" ],
307
- repo = repo ,
308
- user_profile = user_profile ,
309
- )
310
- github_issue .save ()
311
-
312
- added_count += 1
313
-
314
- if verbose :
315
- self .stdout .write (f"Added PR #{ pr ['number' ]} : { pr ['title' ]} " )
299
+ # Prepare the data for the GitHubIssue
300
+ issue_data = {
301
+ "title" : pr ["title" ],
302
+ "body" : pr ["body" ] or "" ,
303
+ "state" : pr ["state" ],
304
+ "type" : "pull_request" ,
305
+ "created_at" : created_at ,
306
+ "updated_at" : updated_at ,
307
+ "closed_at" : closed_at ,
308
+ "merged_at" : merged_at ,
309
+ "is_merged" : is_merged ,
310
+ "url" : pr ["html_url" ],
311
+ "repo" : repo ,
312
+ "user_profile" : user_profile ,
313
+ }
314
+
315
+ # Try to get the existing issue or create a new one
316
+ try :
317
+ github_issue , created = GitHubIssue .objects .update_or_create (issue_id = pr ["id" ], defaults = issue_data )
318
+
319
+ if created :
320
+ added_count += 1
321
+ if verbose :
322
+ self .stdout .write (f"Added PR #{ pr ['number' ]} : { pr ['title' ]} " )
323
+ else :
324
+ updated_count += 1
325
+ if verbose :
326
+ self .stdout .write (f"Updated PR #{ pr ['number' ]} : { pr ['title' ]} " )
327
+ except Exception as e :
328
+ self .stdout .write (self .style .ERROR (f"Error saving PR #{ pr ['number' ]} : { str (e )} " ))
329
+ skipped_count += 1
316
330
317
- self .stdout .write (f"Skipped { skipped_count } PRs that already exist in the database " )
331
+ self .stdout .write (f"Skipped { skipped_count } PRs due to errors " )
318
332
self .stdout .write (f"Skipped { skipped_not_merged } PRs that are not merged" )
319
333
self .stdout .write (f"Added { added_count } new PRs to the database" )
334
+ self .stdout .write (f"Updated { updated_count } existing PRs in the database" )
320
335
321
- return added_count
336
+ return added_count , updated_count
0 commit comments