Skip to content

Commit ced7025

Browse files
authored
Merge pull request #125 from moevm/104-Forgejo-Automatic-Selection-Github
Forgejo Automatic Selection/Github
2 parents 547b5f4 + 36b55ab commit ced7025

File tree

4 files changed

+51
-66
lines changed

4 files changed

+51
-66
lines changed

GitHubRepoAPI.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ def _client_validation(client: Github) -> Github:
3030
logging.error(
3131
'Github: Connect: user could not be authenticated please try again.'
3232
)
33-
exit(1)
3433
else:
3534
return client
3635

git_logger.py

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
from interface_wrapper import IRepositoryAPI, RepositoryFactory
55

66

7-
def login(source, token, base_url):
8-
client = RepositoryFactory.create_api(source, token, base_url)
9-
return client
7+
def login(token, base_url):
8+
try:
9+
client = RepositoryFactory.create_api(token, base_url)
10+
return client
11+
except Exception:
12+
return None
1013

1114

1215
def get_tokens_from_file(tokens_path: str) -> list[str]:
@@ -24,61 +27,37 @@ def get_repos_from_file(repos_path: str) -> list[str]:
2427

2528

2629
class Clients:
27-
def __init__(self, source: str, tokens: list[str], base_url: str | None = None):
28-
# Возможно это можно переписать покрасивее
29-
if source == 'github':
30-
self.clients = self._init_clients(source, tokens, base_url)
31-
elif base_url == 'forgejo':
32-
self.client = RepositoryFactory.create_api(source, tokens[0], base_url)
33-
self.token = tokens[0]
34-
else:
35-
print(f"Unavailable source {source}, use [ 'github' | 'forgejo' ] instead")
36-
37-
self.source = source
30+
def __init__(self, tokens: list[str], base_url: str | None = None):
31+
self.clients = []
32+
self.token_map = {}
3833

39-
def _init_clients(
40-
self, source: str, tokens: list[str], base_url: str | None
41-
) -> list[dict]:
42-
clients = [
43-
{
44-
"client": RepositoryFactory.create_api(source, token, base_url),
45-
"token": token,
46-
}
47-
for token in tokens
48-
]
34+
for token in tokens:
35+
client = login(token, base_url)
36+
if client:
37+
self.clients.append(client)
38+
self.token_map[client] = token
4939

50-
return clients
40+
if not self.clients:
41+
raise Exception("No valid tokens for either GitHub or Forgejo")
5142

52-
def _get_next_git_client(self) -> tuple[IRepositoryAPI, str]:
43+
def _get_next_client(self) -> tuple[IRepositoryAPI, str]:
5344
client = None
5445
max_remaining_limit = -1
5546

56-
for client_tmp in self.clients:
57-
remaining_limit, limit = client_tmp["client"].get_rate_limiting()
58-
59-
# можно добавить вывод износа токена
60-
# можно дополнительно проверять на 403 и временно пропускать эти токены,
61-
# либо завести константу "минимальный коэффициент износа" и не трогать "изношенные" токены
62-
63-
if remaining_limit > max_remaining_limit:
64-
client = client_tmp
65-
max_remaining_limit = remaining_limit
66-
47+
for c in self.clients:
48+
remaining, _ = c.get_rate_limiting()
49+
if remaining > max_remaining_limit:
50+
client = c
51+
max_remaining_limit = remaining
6752
sleep(TIMEDELTA)
6853

6954
if client is None:
7055
raise Exception("No git clients available")
7156

72-
return client['client'], client['token']
73-
74-
def _get_next_forgejo_client(self) -> tuple[IRepositoryAPI, str]:
75-
return self.client, self.token
57+
return client, self.token_map[client]
7658

7759
def get_next_client(self) -> tuple[IRepositoryAPI, str]:
78-
if self.source == 'github':
79-
return self._get_next_git_client()
80-
elif self.source == 'forgejo':
81-
return self._get_next_forgejo_client
60+
return self._get_next_client()
8261

8362

8463
def get_next_binded_repo(clients: Clients, repositories: list[str]):

interface_wrapper.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,25 +194,26 @@ def get_workflow_runs(self, repo: Repository) -> list[WorkflowRun]:
194194
pass
195195

196196

197-
# Фабрика для создания API
198197
class RepositoryFactory:
199198
@staticmethod
200-
def create_api(
201-
source: str, token: str, base_url: str | None = None
202-
) -> IRepositoryAPI:
199+
def create_api(token: str, base_url: str | None = None) -> IRepositoryAPI:
203200
from ForgejoRepoAPI import ForgejoRepoAPI
204201
from GitHubRepoAPI import GitHubRepoAPI
205202

206-
if source == 'github':
203+
errors = []
204+
205+
try:
207206
return GitHubRepoAPI(Github(auth=Auth.Token(token)))
208-
elif source == 'forgejo':
209-
if not isinstance(base_url, str):
210-
raise ValueError(
211-
f"base_url for PyforgejoApi should be str, got {type(base_url)}"
212-
)
213-
return ForgejoRepoAPI(PyforgejoApi(api_key=token, base_url=base_url))
214-
else:
215-
raise ValueError(f"Unsupported source: {source}")
207+
except Exception as e:
208+
errors.append(f"GitHub login failed: {e}")
209+
210+
if base_url:
211+
try:
212+
return ForgejoRepoAPI(PyforgejoApi(api_key=token, base_url=base_url))
213+
except Exception as e:
214+
errors.append(f"Forgejo login failed: {e}")
215+
216+
raise Exception(" / ".join(errors))
216217

217218

218219
# Сервис для расчёта метрик

main.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ def parse_args():
3636
action="store_true",
3737
)
3838

39+
parser.add_argument(
40+
'--base_url',
41+
type=str,
42+
required=False,
43+
help='Base URL for Forgejo instance (if using Forgejo)',
44+
)
45+
3946
token = parser.add_mutually_exclusive_group(required=True)
4047
token.add_argument('-t', '--token', type=str, help='account access token')
4148
token.add_argument('--tokens', type=str, help='path to your tokens')
@@ -170,16 +177,15 @@ def main():
170177

171178
repositories = git_logger.get_repos_from_file(args.list)
172179

173-
print(repositories)
174-
175180
try:
176-
clients = git_logger.Clients("github", tokens)
181+
clients = git_logger.Clients(tokens, args.base_url)
177182
binded_repos = git_logger.get_next_binded_repo(clients, repositories)
178183
except Exception as e:
179-
print(e)
180-
print(traceback.print_exc())
181-
else:
182-
run(args, binded_repos, repositories)
184+
print(f"Failed to initialize any clients: {e}")
185+
print(traceback.format_exc())
186+
return
187+
188+
run(args, binded_repos, repositories)
183189

184190

185191
if __name__ == '__main__':

0 commit comments

Comments
 (0)