Skip to content

Commit 3fc543b

Browse files
committed
Atualiza a geração de imagens e adiciona novos arquivos de configuração. Modificações incluem a correção na extração de dados de commits, PRs e issues, além da inclusão de um novo arquivo principal e um arquivo de configuração do projeto.
1 parent 15303c0 commit 3fc543b

File tree

5 files changed

+658
-69
lines changed

5 files changed

+658
-69
lines changed

generate_images.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ async def generate_overview(s: Stats) -> None:
4141
output = re.sub("{{ contributions }}", f"{await s.total_contributions:,}", output)
4242
output = re.sub("{{ views }}", f"{await s.views:,}", output)
4343
output = re.sub("{{ repos }}", f"{len(await s.repos):,}", output)
44-
commits = await s.total_commits()
45-
print(f"Total commits: {commits}")
46-
output = re.sub("{{ commits }}", f"{commits:,}", output) # Adicionado
47-
output = re.sub("{{ prs }}", f"{await s.total_prs():,}", output) # Adicionado
44+
output = re.sub("{{ commits }}", f"{await s.total_commits:,}", output)
45+
output = re.sub("{{ prs }}", f"{await s.prs:,}", output)
46+
output = re.sub("{{ issues }}", f"{await s.issues:,}", output)
4847

4948
generate_output_folder()
5049
with open("generated/overview.svg", "w") as f:
@@ -124,7 +123,7 @@ async def main() -> None:
124123
)
125124
emails = os.getenv("GIT_EMAILS")
126125
email_list = (
127-
{x.strip() for x in emails.split(",")} if emails else None
126+
list({x.strip() for x in emails.split(",")}) if emails else None
128127
)
129128

130129
async with aiohttp.ClientSession() as session:
@@ -135,8 +134,8 @@ async def main() -> None:
135134
exclude_repos=excluded_repos,
136135
exclude_langs=excluded_langs,
137136
ignore_forked_repos=ignore_forked_repos,
137+
emails=email_list,
138138
)
139-
s._emails = email_list # Add this line
140139
await asyncio.gather(generate_languages(s), generate_overview(s))
141140

142141

github_stats.py

Lines changed: 108 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ async def query(self, generated_query: str) -> Dict:
5151
result = await r_async.json()
5252
if result is not None:
5353
return result
54-
except:
54+
except Exception:
5555
print("aiohttp failed for GraphQL query")
5656
# Fall back on non-async requests
5757
async with self.semaphore:
@@ -97,7 +97,7 @@ async def query_rest(self, path: str, params: Optional[Dict] = None) -> Dict:
9797
result = await r_async.json()
9898
if result is not None:
9999
return result
100-
except:
100+
except Exception:
101101
print("aiohttp failed for rest query")
102102
# Fall back on non-async requests
103103
async with self.semaphore:
@@ -111,11 +111,47 @@ async def query_rest(self, path: str, params: Optional[Dict] = None) -> Dict:
111111
await asyncio.sleep(2)
112112
continue
113113
elif r_requests.status_code == 200:
114-
return r_requests.json()
114+
result_json = r_requests.json()
115+
if result_json is not None:
116+
return result_json
115117
# print(f"There were too many 202s. Data for {path} will be incomplete.")
116118
print("There were too many 202s. Data for this repository will be incomplete.")
117119
return dict()
118120

121+
@staticmethod
122+
def summary_query() -> str:
123+
"""
124+
:return: GraphQL query with summary of user stats
125+
"""
126+
return f"""query {{
127+
viewer {{
128+
login
129+
name
130+
repositories(first: 100, ownerAffiliations: OWNER, isFork: false) {{
131+
totalCount
132+
edges {{
133+
node {{
134+
stargazers {{
135+
totalCount
136+
}}
137+
forkCount
138+
}}
139+
}}
140+
}}
141+
pullRequests(first: 1) {{
142+
totalCount
143+
}}
144+
issues(first: 1) {{
145+
totalCount
146+
}}
147+
contributionsCollection {{
148+
totalCommitContributions
149+
restrictedContributionsCount
150+
}}
151+
}}
152+
}}
153+
"""
154+
119155
@staticmethod
120156
def repos_overview(
121157
contrib_cursor: Optional[str] = None, owned_cursor: Optional[str] = None
@@ -125,8 +161,8 @@ def repos_overview(
125161
"""
126162
return f"""{{
127163
viewer {{
128-
login,
129-
name,
164+
login
165+
name
130166
repositories(
131167
first: 100,
132168
orderBy: {{
@@ -258,22 +294,26 @@ def __init__(
258294
exclude_repos: Optional[Set] = None,
259295
exclude_langs: Optional[Set] = None,
260296
ignore_forked_repos: bool = False,
297+
emails: Optional[List[str]] = None,
261298
):
262299
self.username = username
263300
self._ignore_forked_repos = ignore_forked_repos
264301
self._exclude_repos = set() if exclude_repos is None else exclude_repos
265302
self._exclude_langs = set() if exclude_langs is None else exclude_langs
266303
self.queries = Queries(username, access_token, session)
304+
self._emails = emails
267305

268306
self._name: Optional[str] = None
269307
self._stargazers: Optional[int] = None
270308
self._forks: Optional[int] = None
271309
self._total_contributions: Optional[int] = None
310+
self._total_commits: Optional[int] = None
311+
self._prs: Optional[int] = None
312+
self._issues: Optional[int] = None
272313
self._languages: Optional[Dict[str, Any]] = None
273314
self._repos: Optional[Set[str]] = None
274315
self._lines_changed: Optional[Tuple[int, int]] = None
275316
self._views: Optional[int] = None
276-
self._emails: Optional[Set[str]] = None # Add this line
277317

278318
async def to_str(self) -> str:
279319
"""
@@ -296,6 +336,36 @@ async def to_str(self) -> str:
296336
Languages:
297337
- {formatted_languages}"""
298338

339+
async def get_summary_stats(self) -> None:
340+
"""
341+
Get lots of summary statistics using one big query. Sets many attributes
342+
"""
343+
raw_results = await self.queries.query(self.queries.summary_query())
344+
if raw_results is None:
345+
return
346+
viewer = raw_results.get("data", {}).get("viewer", {})
347+
if not viewer:
348+
return
349+
350+
self._name = viewer.get("name") or viewer.get("login", "No Name")
351+
self._stargazers = sum(
352+
[
353+
repo["node"]["stargazers"]["totalCount"]
354+
for repo in viewer["repositories"]["edges"]
355+
]
356+
)
357+
self._forks = sum(
358+
[repo["node"]["forkCount"] for repo in viewer["repositories"]["edges"]]
359+
)
360+
361+
self._prs = viewer.get("pullRequests", {}).get("totalCount", 0)
362+
self._issues = viewer.get("issues", {}).get("totalCount", 0)
363+
contributions = viewer.get("contributionsCollection", {})
364+
self._total_commits = (
365+
contributions.get("totalCommitContributions", 0)
366+
+ contributions.get("restrictedContributionsCount", 0)
367+
)
368+
299369
async def get_stats(self) -> None:
300370
"""
301371
Get lots of summary statistics using one big query. Sets many attributes
@@ -345,8 +415,8 @@ async def get_stats(self) -> None:
345415
if name in self._repos or name in self._exclude_repos:
346416
continue
347417
self._repos.add(name)
348-
self._stargazers += repo.get("stargazers").get("totalCount", 0)
349-
self._forks += repo.get("forkCount", 0)
418+
# self._stargazers += repo.get("stargazers").get("totalCount", 0)
419+
# self._forks += repo.get("forkCount", 0)
350420

351421
for lang in repo.get("languages", {}).get("edges", []):
352422
name = lang.get("node", {}).get("name", "Other")
@@ -375,11 +445,9 @@ async def get_stats(self) -> None:
375445
else:
376446
break
377447

378-
# TODO: Improve languages to scale by number of contributions to
379-
# specific filetypes
380448
langs_total = sum([v.get("size", 0) for v in self._languages.values()])
381449
for k, v in self._languages.items():
382-
v["prop"] = 100 * (v.get("size", 0) / langs_total)
450+
v["prop"] = 100 * (v.get("size", 0) / langs_total) if langs_total > 0 else 0
383451

384452
@property
385453
async def name(self) -> str:
@@ -388,7 +456,7 @@ async def name(self) -> str:
388456
"""
389457
if self._name is not None:
390458
return self._name
391-
await self.get_stats()
459+
await self.get_summary_stats()
392460
assert self._name is not None
393461
return self._name
394462

@@ -399,7 +467,7 @@ async def stargazers(self) -> int:
399467
"""
400468
if self._stargazers is not None:
401469
return self._stargazers
402-
await self.get_stats()
470+
await self.get_summary_stats()
403471
assert self._stargazers is not None
404472
return self._stargazers
405473

@@ -410,7 +478,7 @@ async def forks(self) -> int:
410478
"""
411479
if self._forks is not None:
412480
return self._forks
413-
await self.get_stats()
481+
await self.get_summary_stats()
414482
assert self._forks is not None
415483
return self._forks
416484

@@ -493,7 +561,7 @@ async def lines_changed(self) -> Tuple[int, int]:
493561
):
494562
continue
495563
author = author_obj.get("author", {}).get("login", "")
496-
if author != self.username:
564+
if author.lower() != self.username.lower():
497565
continue
498566

499567
for week in author_obj.get("weeks", []):
@@ -520,62 +588,39 @@ async def views(self) -> int:
520588

521589
self._views = total
522590
return total
523-
591+
592+
@property
524593
async def total_commits(self) -> int:
525594
"""
526595
Get the total number of commits made by the user.
527596
"""
597+
if self._total_commits is not None:
598+
return self._total_commits
599+
await self.get_summary_stats()
600+
assert self._total_commits is not None
601+
return self._total_commits
528602

529-
total_commits = 0
530-
for email in self._emails:
531-
query = """
532-
query {
533-
user(login: "%s") {
534-
contributionsCollection {
535-
totalCommitContributions
536-
}
537-
}
538-
}
539-
""" % self.username
540-
print(f"Running query for email: {email}")
541-
response = await self.queries.query(query)
542-
print(f"Response for email {email}: {response}")
543-
if 'data' in response and 'user' in response['data']:
544-
total_commits += response['data']['user']['contributionsCollection']['totalCommitContributions']
545-
else:
546-
print(f"Error: 'data' or 'user' not found in response for email {email}")
547-
print(response)
548-
print(f"Total commits: {total_commits}")
549-
return total_commits
550-
551-
query = """
552-
query {
553-
user(login: "%s") {
554-
contributionsCollection {
555-
totalCommitContributions
556-
}
557-
}
558-
}
559-
""" % self.username
560-
response = await self.queries.query(query)
561-
return response["data"]["user"]["contributionsCollection"]["totalCommitContributions"]
562-
563-
564-
async def total_prs(self) -> int:
603+
@property
604+
async def prs(self) -> int:
565605
"""
566606
Get the total number of pull requests made by the user.
567607
"""
568-
query = """
569-
query {
570-
user(login: "%s") {
571-
pullRequests {
572-
totalCount
573-
}
574-
}
575-
}
576-
""" % self.username
577-
response = await self.queries.query(query)
578-
return response["data"]["user"]["pullRequests"]["totalCount"]
608+
if self._prs is not None:
609+
return self._prs
610+
await self.get_summary_stats()
611+
assert self._prs is not None
612+
return self._prs
613+
614+
@property
615+
async def issues(self) -> int:
616+
"""
617+
Get the total number of issues opened by the user.
618+
"""
619+
if self._issues is not None:
620+
return self._issues
621+
await self.get_summary_stats()
622+
assert self._issues is not None
623+
return self._issues
579624

580625
###############################################################################
581626
# Main Function

main.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def main():
2+
print("Hello from stats!")
3+
4+
5+
if __name__ == "__main__":
6+
main()

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "stats"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"aiohttp>=3.12.13",
9+
"requests>=2.32.4",
10+
]

0 commit comments

Comments
 (0)