1+ from github import Github , GithubException
2+
13from 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
1420class 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# Точка входа для тестирования
139274if __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