Skip to content

Commit 7f369be

Browse files
Merge pull request #91 from moevm/79-Calls-changed
Invites and contributors fixes
2 parents 42ea30d + 3a89681 commit 7f369be

File tree

9 files changed

+300
-158
lines changed

9 files changed

+300
-158
lines changed

GitHubRepoAPI.py

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,45 @@
88
WikiPage,
99
Branch,
1010
IRepositoryAPI,
11+
User,
12+
Comment,
13+
Invite,
1114
)
12-
from github import Github
1315

1416

1517
class GitHubRepoAPI(IRepositoryAPI):
1618

1719
def __init__(self, client):
1820
self.client = client
1921

22+
def get_user_data(self, user) -> User:
23+
return User(login=user.login, username=user.name, email=user.email, html_url=user.html_url, node_id=user.node_id, type=user.type, bio=user.bio, site_admin=user.site_admin, _id=user.id)
24+
25+
2026
def get_repository(self, id: str) -> Repository | None:
2127
try:
2228
repo = self.client.get_repo(id)
23-
return Repository(_id=repo.full_name, name=repo.name, url=repo.html_url)
29+
return Repository(_id=repo.full_name, name=repo.name, url=repo.html_url, default_branch=Branch(name=repo.default_branch, last_commit=None), owner=User(login=repo.owner.login,username=repo.owner.name,email=repo.owner.email,html_url=repo.owner.html_url))
2430
except Exception as e:
2531
logging.error(f"Failed to get repository {id} from GitHub: {e}")
2632
return None
2733

28-
def get_commits(self, repo: Repository) -> list[Commit]:
34+
def get_collaborator_permission(self, repo: Repository, user: User) -> str:
35+
return self.client.get_repo(repo._id).get_collaborator_permission(user.login)
36+
37+
def get_commits(self, repo: Repository, files: bool = True) -> list[Commit]:
2938
try:
3039
commits = self.client.get_repo(repo._id).get_commits()
3140
return [
3241
Commit(
3342
_id=c.sha,
3443
message=c.commit.message,
35-
author=Contributor(
36-
c.author.login if c.author else "unknown", c.commit.author.email
37-
),
44+
author=self.get_user_data(c.author),
3845
date=c.commit.author.date,
46+
files=[
47+
f.filename
48+
for f in c.files
49+
] if files else None
3950
)
4051
for c in commits
4152
]
@@ -62,8 +73,17 @@ def get_issues(self, repo: Repository) -> list[Issue]:
6273
Issue(
6374
_id=i.number,
6475
title=i.title,
65-
author=Contributor(i.user.login, i.user.email or ""),
6676
state=i.state,
77+
created_at=i.created_at,
78+
closed_at=i.closed_at,
79+
closed_by=self.get_user_data(i.closed_by) if i.closed_by else None,
80+
body=i.body,
81+
user=self.get_user_data(i.user),
82+
labels= [
83+
l.name
84+
for l in i.labels
85+
],
86+
milestone=i.milestone.title if i.milestone else None
6787
)
6888
for i in issues
6989
]
@@ -78,8 +98,24 @@ def get_pull_requests(self, repo: Repository) -> list[PullRequest]:
7898
PullRequest(
7999
_id=p.number,
80100
title=p.title,
81-
author=Contributor(p.user.login, p.user.email or ""),
101+
author=self.get_user_data(p.user),
82102
state=p.state,
103+
created_at=p.created_at,
104+
head_label=p.head.label,
105+
base_label=p.base.label,
106+
head_ref=p.head.ref,
107+
base_ref=p.base.ref,
108+
merged_by=self.get_user_data(p.merged_by) if p.merged_by else None,
109+
files=[
110+
f.filename
111+
for f in p.get_files()
112+
],
113+
issue_url=p.issue_url,
114+
labels= [
115+
l.name
116+
for l in p.labels
117+
],
118+
milestone=p.milestone.title if p.milestone else None
83119
)
84120
for p in pulls
85121
]
@@ -122,8 +158,57 @@ def get_branches(self, repo: Repository) -> list[Branch]:
122158
return []
123159

124160
def get_wiki_pages(self, repo: Repository) -> list[WikiPage]:
125-
pass
161+
return
162+
163+
def get_forks(self, repo: Repository) -> list[Repository]:
164+
repo_client = self.client.get_repo(repo._id)
165+
result = []
166+
for r in repo_client.get_forks():
167+
result.append(Repository(_id=repo.full_name, name=repo.name, url=repo.html_url))
168+
return result
169+
170+
def get_comments(self, repo, obj) -> list[Comment]:
171+
result = []
172+
if type(obj) == Issue:
173+
# TODO оптимизировать
174+
issues = self.client.get_repo(repo._id).get_issues(state='all')
175+
issue = None
176+
for i in issues:
177+
if i.number == obj._id:
178+
issue = i
179+
break
180+
for c in issue.get_comments():
181+
result.append(Comment(body=c.body,created_at=c.created_at,author=self.get_user_data(c.user)))
182+
elif type(obj) == PullRequest:
183+
# TODO оптимизировать
184+
pulls = self.client.get_repo(repo._id).get_pulls(state='all')
185+
pull = None
186+
for p in pulls:
187+
if p.number == obj._id:
188+
pull = p
189+
break
190+
for c in pull.get_comments():
191+
result.append(Comment(body=c.body,created_at=c.created_at,author=self.get_user_data(c.user.login)))
192+
193+
return result
126194

195+
def get_invites(self, repo: Repository) -> list[Invite]:
196+
try:
197+
invites = self.client.get_repo(repo._id).get_pending_invitations()
198+
return [
199+
Invite(
200+
_id=i._id,
201+
invitee=self.get_user_data(i.invitee),
202+
created_at=i.created_at,
203+
html_url=i.html_url
204+
)
205+
for i in invites
206+
]
207+
except Exception as e:
208+
logging.error(
209+
f"Failed to get invites from GitHub for repo {repo.name}: {e}"
210+
)
211+
return []
127212

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

commits_parser.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from utils import logger
22
import pytz
33
from time import sleep
4-
from github import Github, Repository, GithubException, PullRequest
4+
#from github import Github, Repository, GithubException, PullRequest
5+
from interface_wrapper import IRepositoryAPI, Repository
56

67
EMPTY_FIELD = 'Empty field'
78
TIMEDELTA = 0.05
@@ -18,7 +19,7 @@
1819
)
1920

2021

21-
def log_repository_commits(repository: Repository, csv_name, start, finish, branch):
22+
def log_repository_commits(client: IRepositoryAPI, repository: Repository, csv_name, start, finish, branch):
2223
branches = []
2324
match branch:
2425
case 'all':
@@ -31,45 +32,41 @@ def log_repository_commits(repository: Repository, csv_name, start, finish, bran
3132

3233
for branch in branches:
3334
print(f'Processing branch {branch}')
34-
# TODO add support of since and until in https://pygithub.readthedocs.io/en/stable/github_objects/Repository.html#github.Repository.Repository.get_commits
35-
for commit in repository.get_commits(sha=branch):
35+
commits = client.get_commits(repository)
36+
for commit in commits:
3637
if (
37-
commit.commit.author.date.astimezone(pytz.timezone(TIMEZONE)) < start
38-
or commit.commit.author.date.astimezone(pytz.timezone(TIMEZONE))
39-
> finish
38+
commit.date.astimezone(pytz.timezone(TIMEZONE)) < start
39+
or commit.date.astimezone(pytz.timezone(TIMEZONE)) > finish
4040
):
4141
continue
42-
if commit.commit is not None:
43-
nvl = lambda val: val or EMPTY_FIELD
44-
commit_data = [
45-
repository.full_name,
46-
commit.commit.author.name,
47-
nvl(commit.author.login if commit.author else None),
48-
nvl(commit.commit.author.email),
49-
commit.commit.author.date,
50-
'; '.join([file.filename for file in commit.files]),
51-
commit.commit.sha,
52-
branch,
53-
]
54-
info = dict(zip(FIELDNAMES, commit_data))
42+
commit_data = [
43+
repository.name,
44+
commit.author.username,
45+
commit.author.email or EMPTY_FIELD,
46+
commit.date,
47+
'; '.join([file for file in commit.files]),
48+
commit._id,
49+
branch,
50+
]
51+
info = dict(zip(FIELDNAMES, commit_data))
5552

56-
logger.log_to_csv(csv_name, FIELDNAMES, info)
57-
logger.log_to_stdout(info)
53+
logger.log_to_csv(csv_name, FIELDNAMES, info)
54+
logger.log_to_stdout(info)
5855

59-
sleep(TIMEDELTA)
56+
sleep(TIMEDELTA)
6057

6158

62-
def log_commits(working_repos, csv_name, start, finish, branch, fork_flag):
59+
def log_commits(client: IRepositoryAPI, working_repos, csv_name, start, finish, branch, fork_flag):
6360
logger.log_to_csv(csv_name, FIELDNAMES)
6461

6562
for repo, token in working_repos:
6663
try:
67-
logger.log_title(repo.full_name)
68-
log_repository_commits(repo, csv_name, start, finish, branch)
64+
logger.log_title(repo.name)
65+
log_repository_commits(client, repo, csv_name, start, finish, branch)
6966
if fork_flag:
70-
for forked_repo in repo.get_forks():
67+
for forked_repo in client.get_forks(repo):
7168
logger.log_title("FORKED:", forked_repo.full_name)
72-
log_repository_commits(forked_repo, csv_name, start, finish, branch)
69+
log_repository_commits(client, forked_repo, csv_name, start, finish, branch)
7370
sleep(TIMEDELTA)
7471
sleep(TIMEDELTA)
7572
except Exception as e:

contributors_parser.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from utils import logger
22
from time import sleep
33
from typing import Generator
4-
from github import Github, Repository, GithubException
4+
from interface_wrapper import IRepositoryAPI, Repository, User
55

66
EMPTY_FIELD = 'Empty field'
77
TIMEDELTA = 0.05
@@ -22,24 +22,23 @@
2222
)
2323

2424

25-
def log_repository_contributors(repository: Repository, csv_name: str):
26-
contributors_stats = get_contributors_stats(repository)
25+
def log_repository_contributors(client: IRepositoryAPI, repository: Repository, csv_name: str):
26+
contributors_stats = get_contributors_stats(client, repository)
2727

2828
nvl = lambda val: val or EMPTY_FIELD
2929

3030
for contributor_stat in contributors_stats.values():
3131
contributor = contributor_stat["contributor_object"]
32-
contributor_permissons = repository.get_collaborator_permission(contributor)
32+
contributor_permissions = client.get_collaborator_permission(repository, contributor)
3333

3434
info_tmp = {
35-
'repository name': repository.full_name,
35+
'repository name': repository.name,
3636
'login': contributor.login,
37-
'name': nvl(contributor.name),
37+
'name': nvl(contributor.username),
3838
'email': nvl(contributor_stat['email']),
3939
'url': contributor.html_url,
40-
'permissions': nvl(contributor_permissons),
40+
'permissions': nvl(contributor_permissions),
4141
'total_commits': contributor_stat['total_commits'],
42-
'id': contributor.id,
4342
'node_id': contributor.node_id,
4443
'type': contributor.type,
4544
'bio': nvl(contributor.bio),
@@ -51,17 +50,17 @@ def log_repository_contributors(repository: Repository, csv_name: str):
5150

5251
sleep(TIMEDELTA)
5352

54-
55-
def get_contributors_stats(repository: Repository) -> dict:
53+
def get_contributors_stats(client: IRepositoryAPI, repository: Repository) -> dict:
5654
contributors_stats = dict()
55+
commits = client.get_commits(repository, False)
5756

58-
for commit in repository.get_commits():
57+
for commit in commits:
5958
contributor = commit.author
6059

6160
if not contributor.login in contributors_stats:
6261
contributors_stats[contributor.login] = {
6362
'total_commits': 0,
64-
'email': commit.commit.author.email,
63+
'email': contributor.email,
6564
'contributor_object': contributor,
6665
}
6766

@@ -72,20 +71,20 @@ def get_contributors_stats(repository: Repository) -> dict:
7271
return contributors_stats
7372

7473

75-
def log_contributors(working_repos: Generator, csv_name: str, fork_flag: bool):
74+
def log_contributors(client: IRepositoryAPI, working_repos: Generator, csv_name: str, fork_flag: bool):
7675
logger.log_to_csv(csv_name, FIELDNAMES)
7776

7877
for repo, token in working_repos:
7978
try:
80-
logger.log_title(repo.full_name)
81-
log_repository_contributors(repo, csv_name)
79+
logger.log_title(repo.name)
80+
log_repository_contributors(client, repo, csv_name)
8281

8382
if fork_flag:
84-
for forked_repo in repo.get_forks():
85-
logger.log_title("FORKED:", forked_repo.full_name)
86-
log_repository_contributors(forked_repo, csv_name)
83+
for forked_repo in client.get_forks(repo):
84+
logger.log_title("FORKED:", forked_repo.name)
85+
log_repository_contributors(client, forked_repo, csv_name)
8786
sleep(TIMEDELTA)
8887

89-
except GithubException as e:
88+
except Exception as e:
9089
print(e)
9190
exit(1)

git_logger.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from github import Github, GithubException, PullRequest
2+
from interface_wrapper import IRepositoryAPI, RepositoryFactory, Repository, User, Branch
23
from time import sleep
34

45
TIMEDELTA = 0.05
@@ -32,7 +33,8 @@ def __init__(self, tokens: list[str]):
3233

3334
def _init_clients(self, tokens: list[str]) -> list[dict]:
3435
clients = [{"client": login(token), "token": token} for token in tokens]
35-
# нужно ли нам рейзить ошибку в случае 403, или просто временно пропускать эти токены?
36+
for c in clients:
37+
c["api"] = RepositoryFactory.create_api("github", c["client"])
3638

3739
return clients
3840

@@ -74,10 +76,12 @@ def get_next_repo(clients: GithubClients, repositories):
7476
exit(1)
7577
else:
7678
print(cur_client['token'])
77-
yield repo, cur_client['token']
79+
yield Repository(_id=repo.full_name,name=repo.name,url=repo.html_url, default_branch=Branch(name=repo.default_branch, last_commit=None), owner=cur_client['api'].get_user_data(repo.owner)), cur_client['token']
7880

7981

8082
def get_assignee_story(github_object):
83+
# TODO
84+
return ""
8185
assignee_result = ""
8286
events = (
8387
github_object.get_issue_events()

0 commit comments

Comments
 (0)