Skip to content

Commit 5f58144

Browse files
authored
Merge branch 'master' into 5_export_sheets
2 parents 3faecc5 + 02af10d commit 5f58144

File tree

3 files changed

+213
-23
lines changed

3 files changed

+213
-23
lines changed

git_logger.py

Lines changed: 187 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
from github import Github, Repository, GithubException
21
import csv
2+
import requests
3+
import json
4+
import pytz
5+
6+
from github import Github, Repository, GithubException, PullRequest
37

48
EMPTY_FIELD = 'Empty field'
9+
timezone = 'Europe/Moscow'
510

611
def login(token):
712
client = Github(login_or_token=token)
13+
814
try:
915
client.get_user().login
1016
except GithubException as err:
@@ -30,8 +36,27 @@ def get_next_repo(client: Github, repositories):
3036
yield repo
3137

3238

39+
def get_assignee_story(github_object):
40+
assignee_result = ""
41+
events = github_object.get_issue_events() if type(
42+
github_object) is PullRequest.PullRequest else github_object.get_events()
43+
for event in events:
44+
if event.event == "assigned" or event.event == "unassigned":
45+
date = event.created_at
46+
if event.event == "assigned":
47+
assigner = github_object.user.login
48+
assignee = event.assignee.login
49+
assignee_result += f"{date}: {assigner} -> {assignee}; "
50+
else:
51+
assigner = github_object.user.login
52+
assignee = event.assignee.login
53+
assignee_result += f"{date}: {assigner} -/> {assignee}; "
54+
return assignee_result
55+
56+
3357
def log_commit_to_csv(info, csv_name):
34-
fieldnames = ['repository name', 'commit id', 'author name', 'author login', 'author email', 'date and time', 'changed files']
58+
fieldnames = ['repository name', 'commit id', 'author name', 'author login', 'author email', 'date and time',
59+
'changed files']
3560
with open(csv_name, 'a', newline='') as file:
3661
writer = csv.DictWriter(file, fieldnames=fieldnames)
3762
writer.writerow(info)
@@ -41,16 +66,20 @@ def log_commit_to_stdout(info):
4166
print(info)
4267

4368

44-
def log_repository_commits(repository: Repository, csv_name):
69+
def log_repository_commits(repository: Repository, csv_name, start, finish):
4570
for commit in repository.get_commits():
71+
if commit.commit.author.date.astimezone(
72+
pytz.timezone(timezone)) < start or commit.commit.author.date.astimezone(
73+
pytz.timezone(timezone)) > finish:
74+
continue
4675
if commit.commit is not None:
4776
info = {'repository name': repository.full_name,
48-
'commit id': commit.commit.sha,
4977
'author name': commit.commit.author.name,
5078
'author login': EMPTY_FIELD,
5179
'author email': EMPTY_FIELD,
5280
'date and time': commit.commit.author.date,
53-
'changed files': '; '.join([file.filename for file in commit.files])}
81+
'changed files': '; '.join([file.filename for file in commit.files]),
82+
'commit id': commit.commit.sha}
5483

5584
if commit.author is not None:
5685
info['author login'] = commit.author.login
@@ -65,7 +94,9 @@ def log_repository_commits(repository: Repository, csv_name):
6594
def log_issue_to_csv(info, csv_name):
6695
fieldnames = ['repository name', 'number', 'title', 'state', 'task', 'created at', 'creator name', 'creator login',
6796
'creator email', 'closer name', 'closer login', 'closer email', 'closed at', 'comment body',
68-
'comment created at', 'comment author name', 'comment author login', 'comment author email']
97+
'comment created at', 'comment author name', 'comment author login', 'comment author email',
98+
'assignee story', 'connected pull requests']
99+
69100
with open(csv_name, 'a', newline='') as file:
70101
writer = csv.DictWriter(file, fieldnames=fieldnames)
71102
writer.writerow(info)
@@ -75,8 +106,72 @@ def log_issue_to_stdout(info):
75106
print(info)
76107

77108

78-
def log_repository_issues(repository: Repository, csv_name):
109+
def get_connected_pulls(issue_number, repo_owner, repo_name, token):
110+
access_token = token
111+
repo_owner = repo_owner.login
112+
# Формирование запроса GraphQL
113+
query = """
114+
{
115+
repository(owner: "%s", name: "%s") {
116+
issue(number: %d) {
117+
timelineItems(first: 50, itemTypes:[CONNECTED_EVENT,CROSS_REFERENCED_EVENT]) {
118+
filteredCount
119+
nodes {
120+
... on ConnectedEvent {
121+
ConnectedEvent: subject {
122+
... on PullRequest {
123+
number
124+
title
125+
url
126+
}
127+
}
128+
}
129+
... on CrossReferencedEvent {
130+
CrossReferencedEvent: source {
131+
... on PullRequest {
132+
number
133+
title
134+
url
135+
}
136+
}
137+
}
138+
}
139+
}
140+
}
141+
}
142+
}""" % (repo_owner, repo_name, issue_number)
143+
144+
# Формирование заголовков запроса
145+
headers = {
146+
"Authorization": f"Bearer {access_token}",
147+
"Content-Type": "application/json"
148+
}
149+
150+
# Отправка запроса GraphQL
151+
response = requests.post("https://api.github.com/graphql", headers=headers, data=json.dumps({"query": query}))
152+
response_data = response.json()
153+
# Обработка полученных данных
154+
pull_request_data = response_data["data"]["repository"]["issue"]
155+
list_url = []
156+
if (pull_request_data is not None):
157+
issues_data = pull_request_data["timelineItems"]["nodes"]
158+
for pulls in issues_data:
159+
if (pulls.get("CrossReferencedEvent") != None and pulls.get("CrossReferencedEvent").get("url") not in list_url) :
160+
list_url.append(pulls.get("CrossReferencedEvent").get("url"))
161+
if (pulls.get("ConnectedEvent") != None and pulls.get("ConnectedEvent").get("url") not in list_url):
162+
list_url.append(pulls.get("ConnectedEvent").get("url"))
163+
if (list_url == []):
164+
return 'Empty field'
165+
else:
166+
return list_url
167+
return 'Empty field'
168+
169+
170+
def log_repository_issues(repository: Repository, csv_name, token, start, finish):
79171
for issue in repository.get_issues(state='all'):
172+
if issue.created_at.astimezone(pytz.timezone(timezone)) < start or issue.created_at.astimezone(
173+
pytz.timezone(timezone)) > finish:
174+
continue
80175
info_tmp = {
81176
'repository name': repository.full_name, 'number': issue.number, 'title': issue.title,
82177
'state': issue.state, 'task': issue.body,
@@ -93,16 +188,23 @@ def log_repository_issues(repository: Repository, csv_name):
93188
'comment author name': EMPTY_FIELD,
94189
'comment author login': EMPTY_FIELD,
95190
'comment author email': EMPTY_FIELD,
191+
'assignee story': EMPTY_FIELD,
192+
'connected pull requests': EMPTY_FIELD
96193
}
194+
if issue.number is not None:
195+
info_tmp['connected pull requests'] = get_connected_pulls(issue.number, repository.owner, repository.name,
196+
token)
197+
198+
info_tmp['assignee story'] = get_assignee_story(issue)
97199

98200
if issue.user is not None:
99201
info_tmp['creator name'] = issue.user.name
100202
info_tmp['creator login'] = issue.user.login
101203

102204
if issue.closed_by is not None:
103205
info_tmp['closed at'] = issue.closed_at
104-
info_tmp['creator name'] = issue.closed_by.name
105-
info_tmp['creator login'] = issue.user.login
206+
info_tmp['closer name'] = issue.closed_by.name
207+
info_tmp['closer login'] = issue.user.login
106208

107209
if issue.get_comments().totalCount > 0:
108210
for comment in issue.get_comments():
@@ -120,10 +222,11 @@ def log_repository_issues(repository: Repository, csv_name):
120222

121223

122224
def log_pr_to_csv(info, csv_name):
123-
fieldnames = ['repository name', 'title', 'state', 'commit into', 'commit from', 'created at', 'creator name',
225+
fieldnames = ['repository name', 'title', 'id', 'state', 'commit into', 'commit from', 'created at', 'creator name',
124226
'creator login', 'creator email',
125227
'changed files', 'comment body', 'comment created at', 'comment author name', 'comment author login',
126-
'comment author email', 'merger name', 'merger login', 'merger email', 'source branch', 'target branch']
228+
'comment author email', 'merger name', 'merger login', 'merger email', 'source branch',
229+
'target branch', 'assignee story', 'related issues']
127230
with open(csv_name, 'a', newline='') as file:
128231
writer = csv.DictWriter(file, fieldnames=fieldnames)
129232
writer.writerow(info)
@@ -133,11 +236,61 @@ def log_pr_to_stdout(info):
133236
print(info)
134237

135238

136-
def log_repositories_pr(repository: Repository, csv_name):
239+
def get_related_issues(pull_request_number, repo_owner, repo_name, token):
240+
access_token = token
241+
repo_owner = repo_owner.login
242+
243+
# Формирование запроса GraphQL
244+
query = """
245+
{
246+
repository(owner: "%s", name: "%s") {
247+
pullRequest(number: %d) {
248+
id
249+
closingIssuesReferences(first: 50) {
250+
edges {
251+
node {
252+
id
253+
body
254+
number
255+
title
256+
url
257+
}
258+
}
259+
}
260+
}
261+
}
262+
}
263+
""" % (repo_owner, repo_name, pull_request_number)
264+
265+
# Формирование заголовков запроса
266+
headers = {
267+
"Authorization": f"Bearer {access_token}",
268+
"Content-Type": "application/json"
269+
}
270+
271+
# Отправка запроса GraphQL
272+
response = requests.post("https://api.github.com/graphql", headers=headers, data=json.dumps({"query": query}))
273+
response_data = response.json()
274+
# Обработка полученных данных
275+
pull_request_data = response_data["data"]["repository"]["pullRequest"]
276+
issues_data = pull_request_data["closingIssuesReferences"]["edges"]
277+
list_issues_url = []
278+
# сохранение информации об issues
279+
for issue in issues_data:
280+
issue_node = issue["node"]
281+
list_issues_url.append(issue_node["url"])
282+
return list_issues_url
283+
284+
285+
def log_repositories_pr(repository: Repository, csv_name, token, start, finish):
137286
for pull in repository.get_pulls(state='all'):
287+
if pull.created_at.astimezone(pytz.timezone(timezone)) < start or pull.created_at.astimezone(
288+
pytz.timezone(timezone)) > finish:
289+
continue
138290
info_tmp = {
139291
'repository name': repository.full_name,
140292
'title': pull.title,
293+
'id': pull.number,
141294
'state': pull.state,
142295
'commit into': pull.base.label,
143296
'commit from': pull.head.label,
@@ -156,13 +309,19 @@ def log_repositories_pr(repository: Repository, csv_name):
156309
'merger email': EMPTY_FIELD,
157310
'source branch': pull.head.ref,
158311
'target branch': pull.base.ref,
312+
'assignee story': EMPTY_FIELD,
313+
'related issues': EMPTY_FIELD
159314
}
315+
if pull.issue_url is not None:
316+
info_tmp['related issues'] = get_related_issues(pull.number, repository.owner, repository.name, token)
160317

161318
if pull.merged_by is not None:
162319
info_tmp['merger name'] = pull.merged_by.name
163320
info_tmp['merger login'] = pull.merged_by.login
164321
info_tmp['merger email'] = pull.merged_by.email
165322

323+
info_tmp['assignee story'] = get_assignee_story(pull)
324+
166325
if pull.get_comments().totalCount > 0:
167326
for comment in pull.get_comments():
168327
info = info_tmp
@@ -178,13 +337,14 @@ def log_repositories_pr(repository: Repository, csv_name):
178337
log_pr_to_stdout(info_tmp)
179338

180339

181-
def log_pull_requests(client: Github, repositories, csv_name):
340+
def log_pull_requests(client: Github, repositories, csv_name, token, start, finish):
182341
with open(csv_name, 'w', newline='') as file:
183342
writer = csv.writer(file)
184343
writer.writerow(
185344
(
186345
'repository name',
187346
'title',
347+
'id',
188348
'state',
189349
'commit into',
190350
'commit from',
@@ -203,14 +363,17 @@ def log_pull_requests(client: Github, repositories, csv_name):
203363
'merger email',
204364
'source branch',
205365
'target branch',
366+
'related issues'
367+
'assignee story',
368+
'related issues'
206369
)
207370
)
208371

209372
for repo in get_next_repo(client, repositories):
210-
log_repositories_pr(repo, csv_name)
373+
log_repositories_pr(repo, csv_name, token, start, finish)
211374

212375

213-
def log_issues(client: Github, repositories, csv_name):
376+
def log_issues(client: Github, repositories, csv_name, token, start, finish):
214377
with open(csv_name, 'w', newline='') as file:
215378
writer = csv.writer(file)
216379
writer.writerow(
@@ -222,36 +385,41 @@ def log_issues(client: Github, repositories, csv_name):
222385
'task',
223386
'created at',
224387
'creator name',
388+
'creator login',
225389
'creator email',
226390
'closer name',
391+
'closer login',
227392
'closer email',
228393
'closed at',
229394
'comment body',
230395
'comment created at',
231396
'comment author name',
232397
'comment author login',
233398
'comment author email',
399+
'connected pull requests'
400+
'assignee story',
401+
'connected pull requests'
234402
)
235403
)
236404

237405
for repo in get_next_repo(client, repositories):
238-
log_repository_issues(repo, csv_name)
406+
log_repository_issues(repo, csv_name, token, start, finish)
239407

240408

241-
def log_commits(client: Github, repositories, csv_name):
409+
def log_commits(client: Github, repositories, csv_name, start, finish):
242410
with open(csv_name, 'w', newline='') as file:
243411
writer = csv.writer(file)
244412
writer.writerow(
245413
(
246414
'repository name',
247-
'commit id',
248415
'author name',
249416
'author login',
250417
'author email',
251418
'date and time',
252419
'changed files',
420+
'commit id'
253421
)
254422
)
255423

256424
for repo in get_next_repo(client, repositories):
257-
log_repository_commits(repo, csv_name)
425+
log_repository_commits(repo, csv_name, start, finish)

0 commit comments

Comments
 (0)