Skip to content

Commit e85469f

Browse files
committed
fixes to fully migrate to repository API wrapper
1 parent 63f190e commit e85469f

File tree

6 files changed

+54
-56
lines changed

6 files changed

+54
-56
lines changed

ForgejoRepoAPI.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
Invite
1414
)
1515
import base64
16+
import sys
1617
from pyforgejo import PyforgejoApi
18+
import isodate
1719

1820

1921
class ForgejoRepoAPI(IRepositoryAPI):
@@ -62,7 +64,7 @@ def get_collaborator_permission(self, repo: Repository, user: User) -> str:
6264
return permission.permission
6365

6466
except Exception as e:
65-
if "403" in str(e):
67+
if ("401" in str(e)) or ("403" in str(e)):
6668
logging.error(
6769
f"Permission error: Only admins or repo admins can view permissions for others in {repo.name}.")
6870
return f"Permission error: Only admins or repo admins can view permissions for others in {repo.name}."
@@ -77,7 +79,7 @@ def get_commits(self, repo: Repository, files: bool = True) -> list[Commit]:
7779
_id=c.sha,
7880
message=c.commit.message,
7981
author=self.get_user_data(c.author),
80-
date=c.commit.author.date,
82+
date=isodate.parse_datetime(c.commit.author.date),
8183
files=[f.filename for f in getattr(c, "files", [])] if files else None
8284
)
8385
for c in commits
@@ -122,7 +124,6 @@ def get_issues(self, repo: Repository) -> list[Issue]:
122124
def get_pull_requests(self, repo: Repository) -> list[PullRequest]:
123125
try:
124126
pulls = self.client.repository.repo_list_pull_requests(repo.owner.login, repo.name)
125-
126127
return [
127128
PullRequest(
128129
_id=p.number,
@@ -135,8 +136,8 @@ def get_pull_requests(self, repo: Repository) -> list[PullRequest]:
135136
head_ref=p.head.ref,
136137
base_ref=p.base.ref,
137138
merged_by=self.get_user_data(p.merged_by) if p.merged_by else None,
138-
files=[file.filename for file in p.files],
139-
issue_url=p.issue_url,
139+
files=[], #TODO если возможно
140+
issue_url=None, #TODO если возможно
140141
labels=[label.name for label in p.labels] if p.labels else [],
141142
milestone=p.milestone.title if p.milestone else None,
142143
)
@@ -258,6 +259,9 @@ def get_comments(self, repo, obj) -> list[Comment]:
258259
def get_invites(self, repo: Repository) -> list[Invite]:
259260
return []
260261

262+
def get_rate_limiting(self) -> tuple[int, int]:
263+
return sys.maxsize, sys.maxsize
264+
261265

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

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__":

git_logger.py

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
from github import Github, GithubException, PullRequest
21
from interface_wrapper import (
32
RepositoryFactory,
43
Repository,
54
Branch,
5+
IRepositoryAPI
66
)
77
from time import sleep
88

99
TIMEDELTA = 0.05
1010
TIMEZONE = 'Europe/Moscow'
1111

1212

13-
def login(token):
14-
client = Github(login_or_token=token)
15-
16-
try:
17-
client.get_user().login
18-
except GithubException as err:
19-
print(f'Github: Connect: error {err.data}')
20-
print('Github: Connect: user could not be authenticated please try again.')
21-
exit(1)
22-
else:
23-
return client
13+
def login(source, token, base_url):
14+
client = RepositoryFactory.create_api(source, token, base_url)
15+
return client
2416

2517

2618
def get_tokens_from_file(tokens_path: str) -> list[str]:
@@ -30,24 +22,22 @@ def get_tokens_from_file(tokens_path: str) -> list[str]:
3022
return tokens
3123

3224

33-
class GithubClients:
34-
def __init__(self, tokens: list[str]):
35-
self.clients = self._init_clients(tokens)
25+
class GitClients:
26+
def __init__(self, source: str, tokens: list[str], base_url: str | None = None):
27+
self.clients = self._init_clients(source, tokens, base_url)
3628
self.cur_client = None
3729

38-
def _init_clients(self, tokens: list[str]) -> list[dict]:
39-
clients = [{"client": login(token), "token": token} for token in tokens]
40-
for c in clients:
41-
c["api"] = RepositoryFactory.create_api("github", c["client"])
30+
def _init_clients(self, source: str, tokens: list[str], base_url: str | None) -> list[dict]:
31+
clients = [{"client": login(source, token, base_url), "token": token} for token in tokens]
4232

4333
return clients
4434

45-
def get_next_client(self) -> Github:
35+
def get_next_client(self) -> IRepositoryAPI:
4636
client = None
4737
max_remaining_limit = -1
4838

4939
for client_tmp in self.clients:
50-
remaining_limit, limit = client_tmp["client"].rate_limiting
40+
remaining_limit, limit = client_tmp["client"].get_rate_limiting()
5141

5242
# можно добавить вывод износа токена
5343
# можно дополнительно проверять на 403 и временно пропускать эти токены,
@@ -60,41 +50,36 @@ def get_next_client(self) -> Github:
6050
sleep(TIMEDELTA)
6151

6252
if client is None:
63-
raise Exception("No github-clients available")
53+
raise Exception("No git clients available")
6454

6555
self.cur_client = client
6656
return client
6757

6858

69-
def get_next_repo(clients: GithubClients, repositories):
59+
def get_next_repo(clients: GitClients, repositories):
7060
with open(repositories, 'r') as file:
7161
list_repos = [x for x in file.read().split('\n') if x]
7262
print(list_repos)
7363
for repo_name in list_repos:
7464
try:
7565
cur_client = clients.get_next_client()
76-
repo = cur_client['client'].get_repo(repo_name)
77-
except GithubException as err:
78-
print(f'Github: Connect: error {err.data}')
79-
print(f'Github: Connect: failed to load repository "{repo_name}"')
66+
repo = cur_client['client'].get_repository(repo_name)
67+
except Exception as err:
68+
print(f'get_next_repo(): error {err}')
69+
print(f'get_next_repo(): failed to load repository "{repo_name}"')
8070
exit(1)
8171
else:
8272
print(cur_client['token'])
83-
yield Repository(
84-
_id=repo.full_name,
85-
name=repo.name,
86-
url=repo.html_url,
87-
default_branch=Branch(name=repo.default_branch, last_commit=None),
88-
owner=cur_client['api'].get_user_data(repo.owner),
89-
), cur_client['token']
73+
yield repo, cur_client['token']
9074

9175

92-
def get_assignee_story(github_object):
76+
def get_assignee_story(git_object):
9377
# TODO
9478
return ""
79+
9580
assignee_result = ""
9681
events = (
97-
github_object.get_issue_events()
82+
git_object.get_issue_events()
9883
if type(github_object) is PullRequest.PullRequest
9984
else github_object.get_events()
10085
)

interface_wrapper.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from dataclasses import dataclass
44
import logging
55

6+
from github import Github
7+
from pyforgejo import PyforgejoApi
8+
69
# Настройка логирования
710
logging.basicConfig(
811
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
@@ -164,20 +167,24 @@ def get_comments(self, obj) -> list[Comment]:
164167
def get_invites(self, repo: Repository) -> list[Invite]:
165168
pass
166169

170+
@abstractmethod
171+
def get_rate_limiting(self) -> tuple[int, int]:
172+
pass
173+
167174

168175
# Фабрика для создания API
169176
class RepositoryFactory:
170177
@staticmethod
171-
def create_api(source: str, client) -> IRepositoryAPI:
178+
def create_api(source: str, token: str, base_url: str | None = None) -> IRepositoryAPI:
172179
from GitHubRepoAPI import GitHubRepoAPI
173180
from ForgejoRepoAPI import ForgejoRepoAPI
174181

175-
if client is None:
176-
raise ValueError("Client cannot be None")
177182
if source == 'github':
178-
return GitHubRepoAPI(client)
183+
return GitHubRepoAPI(Github(token))
179184
elif source == 'forgejo':
180-
return ForgejoRepoAPI(client)
185+
if not isinstance(base_url, str):
186+
raise ValueError(f"base_url for PyforgejoApi should be str, got {type(base_url)}")
187+
return ForgejoRepoAPI(PyforgejoApi(api_key=token, base_url=base_url))
181188
else:
182189
raise ValueError(f"Unsupported source: {source}")
183190

main.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import argparse
22
from datetime import datetime
33
import pytz
4+
import traceback
5+
46

57
import git_logger
68
import export_sheets
@@ -34,7 +36,7 @@ def parse_args():
3436
)
3537

3638
token = parser.add_mutually_exclusive_group(required=True)
37-
token.add_argument('-t', '--token', type=str, help='token github account')
39+
token.add_argument('-t', '--token', type=str, help='account access token')
3840
token.add_argument('--tokens', type=str, help='path to your tokens')
3941

4042
parser.add_argument(
@@ -150,11 +152,12 @@ def main():
150152
log_pr_comments = args.pr_comments
151153

152154
try:
153-
clients = git_logger.GithubClients(tokens)
155+
clients = git_logger.GitClients("github", tokens)
154156
except Exception as e:
155157
print(e)
158+
print(traceback.print_exc())
156159
else:
157-
client = RepositoryFactory.create_api("github", git_logger.login(tokens[0]))
160+
client = RepositoryFactory.create_api("github", tokens[0])
158161
working_repos = git_logger.get_next_repo(clients, repositories)
159162
start = parse_time(args.start.split('-'))
160163
finish = parse_time(args.finish.split('-'))

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ pygsheets==2.0.6
44
pandas==2.2.3
55
pytz==2024.2
66
requests==2.32.3
7-
pyforgejo==2.0.0
7+
pyforgejo==2.0.0
8+
isodate==0.7.2

0 commit comments

Comments
 (0)