Skip to content

Commit 715d128

Browse files
committed
FIX, optimized: get_comments
1 parent eba7831 commit 715d128

File tree

1 file changed

+219
-80
lines changed

1 file changed

+219
-80
lines changed

GitHubRepoAPI.py

Lines changed: 219 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,149 @@
1+
from github import Github, GithubException
2+
13
from interface_wrapper import (
2-
logging,
3-
Repository,
4-
Contributor,
4+
Branch,
5+
Comment,
56
Commit,
7+
Contributor,
8+
Invite,
9+
IRepositoryAPI,
610
Issue,
711
PullRequest,
12+
Repository,
13+
User,
814
WikiPage,
9-
Branch,
10-
IRepositoryAPI,
15+
logging,
16+
WorkflowRun,
1117
)
12-
from github import Github
18+
1319

1420
class GitHubRepoAPI(IRepositoryAPI):
15-
16-
def __init__(self, client):
17-
self.client = client
18-
self._issue_cache = {}
19-
self._pull_cache = {}
21+
def __init__(self, client: Github):
22+
self.client = self._client_validation(client)
23+
24+
@staticmethod
25+
def _client_validation(client: Github) -> Github:
26+
try:
27+
client.get_user().login
28+
except GithubException as err:
29+
logging.error(f'Github: Connect: error {err.data}')
30+
logging.error(
31+
'Github: Connect: user could not be authenticated please try again.'
32+
)
33+
exit(1)
34+
else:
35+
return client
36+
37+
def get_user_data(self, user) -> User:
38+
return User(
39+
login=user.login,
40+
username=user.name,
41+
email=user.email, # always None
42+
html_url=user.html_url,
43+
node_id=user.node_id,
44+
type=user.type,
45+
bio=user.bio,
46+
site_admin=user.site_admin,
47+
_id=user.id,
48+
)
49+
50+
def get_commit_data(self, commit, files=False) -> Commit:
51+
return Commit(
52+
_id=commit.sha,
53+
message=commit.commit.message,
54+
author=self.get_user_data(commit.author),
55+
date=commit.commit.author.date,
56+
files=[f.filename for f in commit.files] if files else None,
57+
additions=commit.stats.additions,
58+
deletions=commit.stats.deletions,
59+
)
2060

2161
def get_repository(self, id: str) -> Repository | None:
2262
try:
2363
repo = self.client.get_repo(id)
24-
return Repository(_id=repo.full_name, name=repo.name, url=repo.html_url)
64+
return Repository(
65+
_id=repo.full_name,
66+
name=repo.name,
67+
url=repo.html_url,
68+
default_branch=Branch(name=repo.default_branch, last_commit=None),
69+
owner=self.get_user_data(repo.owner),
70+
)
2571
except Exception as e:
2672
logging.error(f"Failed to get repository {id} from GitHub: {e}")
2773
return None
2874

29-
def get_commits(self, repo: Repository) -> list[Commit]:
75+
def get_collaborator_permission(self, repo: Repository, user: User) -> str:
76+
return self.client.get_repo(repo._id).get_collaborator_permission(user.login)
77+
78+
def get_commits(self, repo: Repository, files: bool = True) -> list[Commit]:
3079
try:
3180
commits = self.client.get_repo(repo._id).get_commits()
32-
return [
33-
Commit(
34-
_id=c.sha,
35-
message=c.commit.message,
36-
author=Contributor(c.author.login if c.author else "unknown", c.commit.author.email),
37-
date=c.commit.author.date
38-
) for c in commits
39-
]
81+
return [self.get_commit_data(c, files) for c in commits]
82+
4083
except Exception as e:
41-
logging.error(f"Failed to get commits from GitHub for repo {repo.name}: {e}")
84+
logging.error(
85+
f"Failed to get commits from GitHub for repo {repo.name}: {e}"
86+
)
4287
return []
4388

4489
def get_contributors(self, repo: Repository) -> list[Contributor]:
4590
try:
4691
contributors = self.client.get_repo(repo._id).get_contributors()
4792
return [Contributor(c.login, c.email or "") for c in contributors]
4893
except Exception as e:
49-
logging.error(f"Failed to get contributors from GitHub for repo {repo.name}: {e}")
94+
logging.error(
95+
f"Failed to get contributors from GitHub for repo {repo.name}: {e}"
96+
)
5097
return []
5198

5299
def get_issues(self, repo: Repository) -> list[Issue]:
53100
try:
54-
repo_obj = self.client.get_repo(repo._id)
55-
issues = repo_obj.get_issues(state='all')
56-
57-
issue_dict = {}
58-
result = []
59-
for i in issues:
60-
issue_obj = Issue(
101+
issues = self.client.get_repo(repo._id).get_issues(state='all')
102+
return [
103+
Issue(
61104
_id=i.number,
62105
title=i.title,
63-
author=Contributor(i.user.login, i.user.email or ""),
64-
state=i.state
106+
state=i.state,
107+
created_at=i.created_at,
108+
closed_at=i.closed_at,
109+
closed_by=self.get_user_data(i.closed_by) if i.closed_by else None,
110+
body=i.body,
111+
user=self.get_user_data(i.user),
112+
labels=[label.name for label in i.labels],
113+
milestone=i.milestone.title if i.milestone else None,
65114
)
66-
result.append(issue_obj)
67-
issue_dict[i.number] = issue_obj
68-
69-
self._issue_cache[repo._id] = issue_dict
70-
return result
71-
115+
for i in issues
116+
]
72117
except Exception as e:
73118
logging.error(f"Failed to get issues from GitHub for repo {repo.name}: {e}")
74119
return []
75120

76121
def get_pull_requests(self, repo: Repository) -> list[PullRequest]:
77122
try:
78123
pulls = self.client.get_repo(repo._id).get_pulls(state='all')
79-
80-
pull_dict = {}
81-
result = []
82-
for p in pulls:
83-
pr_obj = PullRequest(
124+
return [
125+
PullRequest(
84126
_id=p.number,
85127
title=p.title,
86-
author=Contributor(p.user.login, p.user.email or ""),
87-
state=p.state
128+
author=self.get_user_data(p.user),
129+
state=p.state,
130+
created_at=p.created_at,
131+
head_label=p.head.label,
132+
base_label=p.base.label,
133+
head_ref=p.head.ref,
134+
base_ref=p.base.ref,
135+
merged_by=self.get_user_data(p.merged_by) if p.merged_by else None,
136+
files=[file.filename for file in p.get_files()],
137+
issue_url=p.issue_url,
138+
labels=[label.name for label in p.labels],
139+
milestone=p.milestone.title if p.milestone else None,
88140
)
89-
result.append(pr_obj)
90-
pull_dict[p.number] = pr_obj
91-
92-
self._pull_cache[repo._id] = pull_dict
93-
return result
94-
141+
for p in pulls
142+
]
95143
except Exception as e:
96-
logging.error(f"Failed to get pull requests from GitHub for repo {repo.name}: {e}")
144+
logging.error(
145+
f"Failed to get pull requests from GitHub for repo {repo.name}: {e}"
146+
)
97147
return []
98148

99149
def get_branches(self, repo: Repository) -> list[Branch]:
@@ -105,44 +155,129 @@ def get_branches(self, repo: Repository) -> list[Branch]:
105155
for branch in branches:
106156
commit = repo_client.get_commit(branch.commit.sha)
107157

108-
author = commit.author
109-
contributor = Contributor(
110-
username=author.login if author else "unknown",
111-
email=commit.commit.author.email or ""
158+
commit_obj = self.get_commit_data(commit)
159+
160+
result.append(Branch(name=branch.name, last_commit=commit_obj))
161+
162+
return result
163+
164+
except Exception as e:
165+
logging.error(
166+
f"Failed to get branches from GitHub for repo {repo.name}: {e}"
167+
)
168+
return []
169+
170+
def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
171+
return
172+
173+
def get_forks(self, repo: Repository) -> list[Repository]:
174+
repo_client = self.client.get_repo(repo._id)
175+
result = []
176+
177+
for r in repo_client.get_forks():
178+
default_branch = (Branch(name=r.default_branch, last_commit=None),)
179+
owner = (self.get_user_data(r.owner),)
180+
181+
result.append(
182+
Repository(
183+
_id=r.full_name,
184+
name=r.name,
185+
url=r.html_url,
186+
default_branch=default_branch,
187+
owner=owner,
112188
)
189+
)
190+
191+
return result
113192

114-
commit_obj = Commit(
115-
_id=commit.sha,
116-
message=commit.commit.message,
117-
author=contributor,
118-
date=commit.commit.author.date
193+
def get_comments(self, repo, obj) -> list[Comment]:
194+
result = []
195+
repo_client = self.client.get_repo(repo._id)
196+
197+
try:
198+
if isinstance(obj, Issue):
199+
# Получаем issue напрямую по номеру
200+
issue = repo_client.get_issue(number=obj._id)
201+
comments = issue.get_comments()
202+
elif isinstance(obj, PullRequest):
203+
# Получаем PR напрямую по номеру
204+
pull = repo_client.get_pull(number=obj._id)
205+
comments = pull.get_comments()
206+
else:
207+
return []
208+
209+
# Формируем результат
210+
return [
211+
Comment(
212+
body=comment.body,
213+
created_at=comment.created_at,
214+
author=self.get_user_data(comment.user),
119215
)
216+
for comment in comments
217+
]
218+
219+
except Exception as e:
220+
logging.error(f"Failed to get comments for {type(obj).__name__} {obj._id}: {e}")
221+
return []
120222

121-
result.append(
122-
Branch(
123-
name=branch.name,
124-
last_commit=commit_obj
125-
)
223+
def get_invites(self, repo: Repository) -> list[Invite]:
224+
try:
225+
invites = self.client.get_repo(repo._id).get_pending_invitations()
226+
return [
227+
Invite(
228+
_id=i._id,
229+
invitee=self.get_user_data(i.invitee),
230+
created_at=i.created_at,
231+
html_url=i.html_url,
126232
)
233+
for i in invites
234+
]
235+
except Exception as e:
236+
logging.error(
237+
f"Failed to get invites from GitHub for repo {repo.name}: {e}"
238+
)
239+
return []
127240

128-
return result
241+
def get_rate_limiting(self) -> tuple[int, int]:
242+
return self.client.rate_limiting
243+
244+
def get_workflow_runs(self, repo) -> list[WorkflowRun]:
245+
try:
246+
runs = self.client.get_repo(repo._id).get_workflow_runs()
247+
248+
return [
249+
WorkflowRun(
250+
display_title=r.display_title,
251+
event=r.event,
252+
head_branch=r.head_branch,
253+
head_sha=r.head_sha,
254+
name=r.name,
255+
path=r.path,
256+
created_at=r.created_at,
257+
run_started_at=r.run_started_at,
258+
updated_at=r.updated_at,
259+
conclusion=r.conclusion,
260+
status=r.status,
261+
url=r.url,
262+
)
263+
for r in runs
264+
]
129265

130266
except Exception as e:
131-
logging.error(f"Failed to get branches from GitHub for repo {repo.name}: {e}")
267+
logging.error(
268+
f"Failed to get workflow runs from GitHub for repo {repo.name}: {e}"
269+
)
132270
return []
133271

134-
def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
135-
pass
136-
137272

138273
# Точка входа для тестирования
139274
if __name__ == "__main__":
140275
# Создайте клиент GitHub (используйте ваш токен)
141-
client = Github("tocken")
142-
api = GitHubRepoAPI(client)
276+
#client = Github("")
277+
api = GitHubRepoAPI('client')
143278

144-
# Укажите ваш репозиторий
145-
repo_name = "repo-name"
279+
# Укажите ваш репозиторий
280+
repo_name = ""
146281

147282
# Получение репозитория
148283
repo = api.get_repository(repo_name)
@@ -156,8 +291,10 @@ def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
156291
# Получение коммитов
157292
commits = api.get_commits(repo)
158293
print(f"Total commits: {len(commits)}")
159-
for commit in commits[:10]:
160-
print(f"Commit: {commit._id}, Message: {commit.message}, Author: {commit.author.username}")
294+
for commit in commits[:10]: # Выведем первые 10 коммитов
295+
print(
296+
f"Commit: {commit._id}, Message: {commit.message}, Author: {commit.author.username}"
297+
)
161298

162299
# Получение контрибьюторов
163300
contributors = api.get_contributors(repo)
@@ -168,17 +305,19 @@ def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
168305
# Получение issues
169306
issues = api.get_issues(repo)
170307
print(f"Total issues: {len(issues)}")
171-
for issue in issues[:10]:
308+
for issue in issues[:10]: # Выведем первые 10 issues
172309
print(f"Issue: {issue._id}, Title: {issue.title}, State: {issue.state}")
173310

174311
# Получение pull requests
175312
pulls = api.get_pull_requests(repo)
176313
print(f"Total pull requests: {len(pulls)}")
177-
for pull in pulls[:10]:
314+
for pull in pulls[:10]: # Выведем первые 10 pull requests
178315
print(f"Pull Request: {pull._id}, Title: {pull.title}, State: {pull.state}")
179316

180317
# Получение веток
181318
branches = api.get_branches(repo)
182319
print(f"Total branches: {len(branches)}")
183320
for branch in branches:
184-
print(f"Branch: {branch.name}, Last Commit: {branch.last_commit._id if branch.last_commit else 'None'}")
321+
print(
322+
f"Branch: {branch.name}, Last Commit: {branch.last_commit._id if branch.last_commit else 'None'}"
323+
)

0 commit comments

Comments
 (0)