Skip to content

Commit 8172a00

Browse files
committed
update suggestions
1 parent 1c2d637 commit 8172a00

File tree

1 file changed

+60
-58
lines changed

1 file changed

+60
-58
lines changed

backend/apps/mentorship/management/commands/sync_module_issues.py

Lines changed: 60 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from django.core.management.base import BaseCommand
66
from django.db import transaction
7+
from django.utils import timezone
78
from github.GithubException import GithubException
89

910
from apps.github.auth import get_github_client
@@ -23,8 +24,13 @@ class Command(BaseCommand):
2324
ALLOWED_GITHUB_HOSTS = {"github.com", "www.github.com"}
2425
REPO_PATH_PARTS = 2
2526

26-
def _extract_repo_full_name(self, repo_url):
27-
parsed = urlparse(repo_url or "")
27+
def _extract_repo_full_name(self, repository):
28+
"""Extract repository full name from Repository model or URL string."""
29+
if hasattr(repository, "path"):
30+
return repository.path
31+
32+
repo_url = str(repository) if repository else ""
33+
parsed = urlparse(repo_url)
2834
if parsed.netloc in self.ALLOWED_GITHUB_HOSTS:
2935
parts = parsed.path.strip("/").split("/")
3036
if len(parts) >= self.REPO_PATH_PARTS:
@@ -45,18 +51,19 @@ def _get_status(self, issue, assignee):
4551
def _get_last_assigned_date(self, repo, issue_number, assignee_login):
4652
"""Find the most recent 'assigned' event for a specific user using PyGithub."""
4753
try:
48-
issue = repo.get_issue(number=issue_number)
49-
50-
events_list = list(issue.get_events())
51-
events_list.reverse()
52-
53-
for event in events_list:
54+
gh_issue = repo.get_issue(number=issue_number)
55+
last_dt = None
56+
for event in gh_issue.get_events():
5457
if (
5558
event.event == "assigned"
5659
and event.assignee
5760
and event.assignee.login == assignee_login
5861
):
59-
return event.created_at
62+
last_dt = event.created_at
63+
64+
if last_dt and timezone.is_naive(last_dt):
65+
return timezone.make_aware(last_dt, timezone.utc)
66+
return last_dt # noqa: TRY300
6067

6168
except GithubException as e:
6269
self.stderr.write(
@@ -69,15 +76,14 @@ def _build_repo_label_to_issue_map(self):
6976
"""Build a map from (repository_id, normalized_label_name) to a set of issue IDs."""
7077
self.stdout.write("Building a repository-aware map of labels to issues...")
7178
repo_label_to_issue_ids = {}
72-
73-
issues_query = Issue.objects.select_related("repository").prefetch_related("labels")
74-
for issue in issues_query:
75-
if not issue.repository_id:
76-
continue
77-
for label in issue.labels.all():
78-
normalized_label = normalize_name(label.name)
79-
key = (issue.repository_id, normalized_label)
80-
repo_label_to_issue_ids.setdefault(key, set()).add(issue.id)
79+
rows = (
80+
Issue.objects.filter(labels__isnull=False, repository__isnull=False)
81+
.values_list("id", "repository_id", "labels__name")
82+
.iterator(chunk_size=5000)
83+
)
84+
for issue_id, repo_id, label_name in rows:
85+
key = (repo_id, normalize_name(label_name))
86+
repo_label_to_issue_ids.setdefault(key, set()).add(issue_id)
8187

8288
self.stdout.write(
8389
f"Map built. Found issues for {len(repo_label_to_issue_ids)} unique repo-label pairs."
@@ -120,11 +126,26 @@ def _process_module(
120126
)
121127

122128
for issue in issues:
123-
new_assignee = issue.assignees.first()
124-
assigned_date = None
125-
if new_assignee and issue.repository:
126-
repo_full_name = self._extract_repo_full_name(str(issue.repository.url))
129+
assignee = issue.assignees.first()
130+
if not assignee:
131+
continue
132+
133+
status = self._get_status(issue, assignee)
134+
task, created = Task.objects.get_or_create(
135+
issue=issue,
136+
assignee=assignee,
137+
defaults={"module": module, "status": status},
138+
)
127139

140+
updates = {}
141+
if task.module != module:
142+
updates["module"] = module
143+
if task.status != status:
144+
updates["status"] = status
145+
146+
# Only fetch assigned_at when needed.
147+
if (created or task.assigned_at is None) and issue.repository:
148+
repo_full_name = self._extract_repo_full_name(issue.repository)
128149
if repo_full_name:
129150
if repo_full_name not in repo_cache:
130151
try:
@@ -136,49 +157,30 @@ def _process_module(
136157
)
137158
)
138159
repo_cache[repo_full_name] = None
139-
140-
repo = repo_cache[repo_full_name]
160+
repo = repo_cache.get(repo_full_name)
141161
if repo:
142162
assigned_date = self._get_last_assigned_date(
143163
repo=repo,
144164
issue_number=issue.number,
145-
assignee_login=new_assignee.login,
165+
assignee_login=assignee.login,
146166
)
147-
148-
if new_assignee:
149-
status = self._get_status(issue, new_assignee)
150-
151-
task, created = Task.objects.get_or_create(
152-
issue=issue,
153-
assignee=new_assignee,
154-
defaults={
155-
"module": module,
156-
"status": status,
157-
"assigned_at": assigned_date,
158-
},
167+
if assigned_date:
168+
updates["assigned_at"] = assigned_date
169+
170+
if created:
171+
num_tasks_created += 1
172+
self.stdout.write(
173+
self.style.SUCCESS(
174+
f"Task created for user '{assignee.login}' on issue "
175+
f"{issue.repository.name}#{issue.number} "
176+
f"in module '{module.name}'"
177+
)
159178
)
160179

161-
if created:
162-
num_tasks_created += 1
163-
self.stdout.write(
164-
self.style.SUCCESS(
165-
f"Task created for user '{new_assignee.login}' on issue "
166-
f"{issue.repository.name}#{issue.number} "
167-
f"in module '{module.name}' "
168-
f"(assigned on {assigned_date})"
169-
)
170-
)
171-
else:
172-
updates = {}
173-
if task.module != module:
174-
updates["module"] = module
175-
if task.status != status:
176-
updates["status"] = status
177-
178-
if updates:
179-
for field, value in updates.items():
180-
setattr(task, field, value)
181-
task.save(update_fields=list(updates.keys()))
180+
if updates:
181+
for field, value in updates.items():
182+
setattr(task, field, value)
183+
task.save(update_fields=list(updates.keys()))
182184

183185
num_linked = len(matched_issue_ids)
184186
if num_linked > 0:

0 commit comments

Comments
 (0)