Skip to content

Commit ffdb731

Browse files
authored
Merge pull request #97 from moevm/78_created_class_ForgejoRepoAPI
78 created class ForgejoRepoAPI
2 parents d5fc4fe + 1779257 commit ffdb731

File tree

6 files changed

+352
-55
lines changed

6 files changed

+352
-55
lines changed

ForgejoRepoAPI.py

Lines changed: 305 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,311 @@
11
from interface_wrapper import (
2+
logging,
23
IRepositoryAPI,
4+
Repository,
5+
Commit,
6+
Branch,
7+
User,
8+
Contributor,
9+
Issue,
10+
PullRequest,
11+
WikiPage,
12+
Comment,
13+
Invite
314
)
15+
import base64
16+
import sys
17+
from pyforgejo import PyforgejoApi
18+
import isodate
419

520

621
class ForgejoRepoAPI(IRepositoryAPI):
7-
...
22+
def __init__(self, client):
23+
self.client = client
24+
25+
def get_user_data(self, user) -> User:
26+
return User(
27+
login=user.login,
28+
username=getattr(user, 'full_name', "No name"),
29+
email=getattr(user, 'email', ""),
30+
html_url=user.html_url,
31+
node_id=user.id,
32+
type=getattr(user, 'type', ""),
33+
bio=getattr(user, 'bio', ""),
34+
site_admin=user.site_admin if hasattr(user, 'site_admin') else False,
35+
_id=user.id
36+
)
37+
38+
def get_repository(self, id: str) -> Repository | None:
39+
try:
40+
repo = self.client.repository.repo_get(owner=id.split('/')[0], repo=id.split('/')[1])
41+
42+
if not repo:
43+
logging.error(f"Failed to get repository {id} from Forgejo.")
44+
return None
45+
46+
return Repository(
47+
_id=repo.full_name,
48+
name=repo.name,
49+
url=repo.html_url,
50+
default_branch=Branch(name=repo.default_branch, last_commit=None),
51+
owner=self.get_user_data(repo.owner),
52+
)
53+
except Exception as e:
54+
logging.error(f"Failed to get repository {id} from Forgejo: {e}")
55+
return None
56+
57+
def get_collaborator_permission(self, repo: Repository, user: User) -> str:
58+
try:
59+
permission = self.client.repository.repo_get_repo_permissions(
60+
owner=repo.owner.login,
61+
repo=repo.name,
62+
collaborator=user.login
63+
)
64+
return permission.permission
65+
66+
except Exception as e:
67+
if ("401" in str(e)) or ("403" in str(e)):
68+
logging.error(
69+
f"Permission error: Only admins or repo admins can view permissions for others in {repo.name}.")
70+
return f"Permission error: Only admins or repo admins can view permissions for others in {repo.name}."
71+
logging.error(f"Failed to get collaborator permission for {user.login} in {repo.name}: {e}")
72+
return "Error"
73+
74+
def get_commits(self, repo: Repository, files: bool = True) -> list[Commit]:
75+
try:
76+
commits = self.client.repository.repo_get_all_commits(repo.owner.login, repo.name)
77+
return [
78+
Commit(
79+
_id=c.sha,
80+
message=c.commit.message,
81+
author=self.get_user_data(c.author),
82+
date=isodate.parse_datetime(c.commit.author.date),
83+
files=[f.filename for f in getattr(c, "files", [])] if files else None
84+
)
85+
for c in commits
86+
]
87+
except Exception as e:
88+
logging.error(
89+
f"Failed to get commits from Forgejo for repo {repo.name}: {e}"
90+
)
91+
return []
92+
93+
def get_contributors(self, repo: Repository) -> list[Contributor]:
94+
try:
95+
commits = self.client.repository.repo_get_all_commits(repo.owner.login, repo.name)
96+
contributors = {c.author.login: c.author.email or "" for c in commits if c.author}
97+
return [Contributor(login, email) for login, email in contributors.items()]
98+
except Exception as e:
99+
logging.error(f"Failed to get contributors from Forgejo for repo {repo.name}: {e}")
100+
return []
101+
102+
def get_issues(self, repo: Repository) -> list[Issue]:
103+
try:
104+
issues = self.client.issue.list_issues(repo.owner.login, repo.name)
105+
return [
106+
Issue(
107+
_id=i.id,
108+
title=i.title,
109+
state=i.state,
110+
created_at=i.created_at,
111+
closed_at=i.closed_at if i.state == 'closed' else None,
112+
closed_by=self.get_user_data(i.closed_by) if hasattr(i, 'closed_by') and i.closed_by else None,
113+
body=i.body,
114+
user=self.get_user_data(i.user),
115+
labels=[label.name for label in i.labels],
116+
milestone=i.milestone.title if i.milestone else None,
117+
)
118+
for i in issues
119+
]
120+
except Exception as e:
121+
logging.error(f"Failed to get issues from Forgejo for repo {repo.name}: {e}")
122+
return []
123+
124+
def get_pull_requests(self, repo: Repository) -> list[PullRequest]:
125+
try:
126+
pulls = self.client.repository.repo_list_pull_requests(repo.owner.login, repo.name)
127+
return [
128+
PullRequest(
129+
_id=p.number,
130+
title=p.title,
131+
author=self.get_user_data(p.user),
132+
state=p.state,
133+
created_at=p.created_at,
134+
head_label=p.head.ref,
135+
base_label=p.base.ref,
136+
head_ref=p.head.ref,
137+
base_ref=p.base.ref,
138+
merged_by=self.get_user_data(p.merged_by) if p.merged_by else None,
139+
files=[], # TODO если возможно
140+
issue_url=None, # TODO если возможно
141+
labels=[label.name for label in p.labels] if p.labels else [],
142+
milestone=p.milestone.title if p.milestone else None,
143+
)
144+
for p in pulls
145+
]
146+
except Exception as e:
147+
logging.error(f"Failed to get pull requests from Forgejo for repo {repo.name}: {e}")
148+
return []
149+
150+
def get_branches(self, repo: Repository) -> list[Branch]:
151+
try:
152+
branches = self.client.repository.repo_list_branches(repo.owner.login, repo.name)
153+
result = []
154+
155+
for branch in branches:
156+
commit = branch.commit
157+
158+
author = commit.author
159+
contributor = Contributor(
160+
username=author.username if author else "unknown",
161+
email=author.email if author and author.email else "",
162+
)
163+
164+
commit_details = self.client.repository.repo_get_single_commit(repo.owner.login, repo.name, commit.id)
165+
files = [file.filename for file in getattr(commit_details, "files", [])]
166+
167+
commit_obj = Commit(
168+
_id=commit.id,
169+
message=commit.message,
170+
author=contributor,
171+
date=commit.timestamp,
172+
files=files,
173+
)
174+
175+
result.append(Branch(name=branch.name, last_commit=commit_obj))
176+
177+
return result
178+
179+
except Exception as e:
180+
logging.error(f"Failed to get branches from Forgejo for repo {repo.name}: {e}")
181+
return []
182+
183+
def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
184+
try:
185+
pages = self.client.repository.repo_get_wiki_pages(repo.owner.login, repo.name)
186+
result = []
187+
188+
for page in pages:
189+
page_details = self.client.repository.repo_get_wiki_page(repo.owner.login, repo.name, page.title)
190+
191+
wiki_page = WikiPage(
192+
title=page_details.title,
193+
content=base64.b64decode(page_details.content_base_64).decode('utf-8')
194+
)
195+
result.append(wiki_page)
196+
197+
return result
198+
199+
except Exception as e:
200+
logging.error(f"Failed to get wiki pages from Forgejo for repo {repo.name}: {e}")
201+
return []
202+
203+
def get_forks(self, repo: Repository) -> list[Repository]:
204+
try:
205+
forks = self.client.repository.list_forks(repo.owner.login, repo.name)
206+
result = []
207+
208+
for fork in forks:
209+
default_branch = Branch(name=fork.default_branch, last_commit=None)
210+
owner = fork.owner
211+
212+
result.append(
213+
Repository(
214+
_id=fork.full_name,
215+
name=fork.name,
216+
url=fork.html_url,
217+
default_branch=default_branch,
218+
owner=owner
219+
220+
)
221+
)
222+
return result
223+
224+
except Exception as e:
225+
logging.error(f"Failed to get forks from Forgejo for repo {repo.name}: {e}")
226+
return []
227+
228+
def get_comments(self, repo, obj) -> list[Comment]:
229+
result = []
230+
try:
231+
if isinstance(obj, Issue):
232+
comments = self.client.issue.get_repo_comments(repo.owner.login, repo.name)
233+
result = [
234+
Comment(
235+
body=c.body,
236+
created_at=c.created_at,
237+
author=self.get_user_data(c.user),
238+
)
239+
for c in comments
240+
]
241+
242+
elif isinstance(obj, PullRequest):
243+
comments = self.client.repository.repo_get_pull_review_comments(repo.owner.login, repo.name, obj._id,
244+
100000) # нет id комментария
245+
result = [
246+
Comment(
247+
body=c.body,
248+
created_at=c.created_at,
249+
author=self.get_user_data(c.user),
250+
)
251+
for c in comments
252+
]
253+
254+
except Exception as e:
255+
logging.error(f"Failed to get comments for repo {repo.name}: {e}")
256+
257+
return result
258+
259+
def get_invites(self, repo: Repository) -> list[Invite]:
260+
return []
261+
262+
def get_rate_limiting(self) -> tuple[int, int]:
263+
return sys.maxsize, sys.maxsize
264+
265+
266+
# Точка входа для тестирования
267+
if __name__ == "__main__":
268+
client = PyforgejoApi(api_key="token", base_url="https://codeberg.org/api/v1")
269+
api = ForgejoRepoAPI(client)
270+
271+
repo = api.get_repository("harabat/pyforgejo")
272+
if not repo:
273+
print("Repository not found.")
274+
exit()
275+
276+
# Вывод информации о репозитории
277+
print(f"Repository: {repo.name}, URL: {repo.url}")
278+
279+
# Получение коммитов
280+
commits = api.get_commits(repo)
281+
print(f"Total commits: {len(commits)}")
282+
for commit in commits[:10]: # Выведем первые 10 коммитов
283+
print(
284+
f"Commit: {commit._id}, Message: {commit.message}, Author: {commit.author.username}"
285+
)
286+
287+
# Получение контрибьюторов
288+
contributors = api.get_contributors(repo)
289+
print(f"Total contributors: {len(contributors)}")
290+
for contributor in contributors:
291+
print(f"Contributor: {contributor.username}, Email: {contributor.email}")
292+
293+
# Получение issues
294+
issues = api.get_issues(repo)
295+
print(f"Total issues: {len(issues)}")
296+
for issue in issues[:10]: # Выведем первые 10 issues
297+
print(f"Issue: {issue._id}, Title: {issue.title}, State: {issue.state}")
298+
299+
# Получение pull requests
300+
pulls = api.get_pull_requests(repo)
301+
print(f"Total pull requests: {len(pulls)}")
302+
for pull in pulls[:10]: # Выведем первые 10 pull requests
303+
print(f"Pull Request: {pull._id}, Title: {pull.title}, State: {pull.state}")
304+
305+
# Получение веток
306+
branches = api.get_branches(repo)
307+
print(f"Total branches: {len(branches)}")
308+
for branch in branches:
309+
print(
310+
f"Branch: {branch.name}, Last Commit: {branch.last_commit._id if branch.last_commit else 'None'}"
311+
)

GitHubRepoAPI.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,7 @@ def get_repository(self, id: str) -> Repository | None:
4040
name=repo.name,
4141
url=repo.html_url,
4242
default_branch=Branch(name=repo.default_branch, last_commit=None),
43-
owner=User(
44-
login=repo.owner.login,
45-
username=repo.owner.name,
46-
email=repo.owner.email,
47-
html_url=repo.owner.html_url,
48-
),
43+
owner=self.get_user_data(repo.owner),
4944
)
5045
except Exception as e:
5146
logging.error(f"Failed to get repository {id} from GitHub: {e}")
@@ -232,6 +227,9 @@ def get_invites(self, repo: Repository) -> list[Invite]:
232227
)
233228
return []
234229

230+
def get_rate_limiting(self) -> tuple[int, int]:
231+
return self.client.rate_limiting
232+
235233

236234
# Точка входа для тестирования
237235
if __name__ == "__main__":

0 commit comments

Comments
 (0)