@@ -250,6 +250,52 @@ def repos_overview(
250250 }}
251251 }}
252252}}
253+ """
254+
255+ @staticmethod
256+ def repos_overview_org (
257+ org_name : str , owned_cursor : Optional [str ] = None
258+ ) -> str :
259+ """
260+ :param org_name: GitHub organization name
261+ :param owned_cursor: GraphQL cursor for pagination
262+ :return: GraphQL query with overview of organization repositories
263+ """
264+ return f"""query {{
265+ organization(login: "{ org_name } ") {{
266+ login,
267+ name,
268+ repositories(
269+ first: 100,
270+ orderBy: {{
271+ field: UPDATED_AT,
272+ direction: DESC
273+ }},
274+ after: { "null" if owned_cursor is None else '"' + owned_cursor + '"' }
275+ ) {{
276+ pageInfo {{
277+ hasNextPage
278+ endCursor
279+ }}
280+ nodes {{
281+ nameWithOwner
282+ stargazers {{
283+ totalCount
284+ }}
285+ forkCount
286+ languages(first: 10, orderBy: {{field: SIZE, direction: DESC}}) {{
287+ edges {{
288+ size
289+ node {{
290+ name
291+ color
292+ }}
293+ }}
294+ }}
295+ }}
296+ }}
297+ }}
298+ }}
253299"""
254300
255301 @staticmethod
@@ -317,6 +363,7 @@ def __init__(
317363 cache_ttl : int = 3600 ,
318364 include_views : bool = True ,
319365 include_lines_changed : bool = True ,
366+ org_name : Optional [str ] = None ,
320367 ):
321368 self .username = username
322369 self ._ignore_forked_repos = ignore_forked_repos
@@ -326,6 +373,7 @@ def __init__(
326373 self ._include_lines_changed = include_lines_changed
327374 self .queries = Queries (username , access_token , session )
328375 self .cache = SimpleCache (ttl = cache_ttl ) if enable_cache else None
376+ self .org_name = org_name
329377
330378 self ._name : Optional [str ] = None
331379 self ._stargazers : Optional [int ] = None
@@ -371,29 +419,52 @@ async def get_stats(self) -> None:
371419 next_owned = None
372420 next_contrib = None
373421 while True :
374- raw_results = await self .queries .query (
375- Queries .repos_overview (
376- owned_cursor = next_owned , contrib_cursor = next_contrib
422+ if self .org_name :
423+ raw_results = await self .queries .query (
424+ Queries .repos_overview_org (
425+ org_name = self .org_name , owned_cursor = next_owned
426+ )
427+ )
428+ else :
429+ raw_results = await self .queries .query (
430+ Queries .repos_overview (
431+ owned_cursor = next_owned , contrib_cursor = next_contrib
432+ )
377433 )
378- )
379434 raw_results = raw_results if raw_results is not None else {}
380435
381- self ._name = raw_results .get ("data" , {}).get ("viewer" , {}).get ("name" , None )
382- if self ._name is None :
383- self ._name = (
436+ if self .org_name :
437+ self ._name = raw_results .get ("data" , {}).get ("organization" , {}).get ("name" , None )
438+ if self ._name is None :
439+ self ._name = (
440+ raw_results .get ("data" , {})
441+ .get ("organization" , {})
442+ .get ("login" , "No Name" )
443+ )
444+
445+ owned_repos = (
384446 raw_results .get ("data" , {})
385- .get ("viewer " , {})
386- .get ("login " , "No Name" )
447+ .get ("organization " , {})
448+ .get ("repositories " , {} )
387449 )
450+ contrib_repos = {}
451+ else :
452+ self ._name = raw_results .get ("data" , {}).get ("viewer" , {}).get ("name" , None )
453+ if self ._name is None :
454+ self ._name = (
455+ raw_results .get ("data" , {})
456+ .get ("viewer" , {})
457+ .get ("login" , "No Name" )
458+ )
388459
389- contrib_repos = (
390- raw_results .get ("data" , {})
391- .get ("viewer" , {})
392- .get ("repositoriesContributedTo" , {})
393- )
394- owned_repos = (
395- raw_results .get ("data" , {}).get ("viewer" , {}).get ("repositories" , {})
396- )
460+ contrib_repos = (
461+ raw_results .get ("data" , {})
462+ .get ("viewer" , {})
463+ .get ("repositoriesContributedTo" , {})
464+ )
465+ owned_repos = (
466+ raw_results .get ("data" , {}).get ("viewer" , {}).get ("repositories" , {})
467+ )
397468
398469 repos = owned_repos .get ("nodes" , [])
399470 if not self ._ignore_forked_repos :
@@ -424,7 +495,16 @@ async def get_stats(self) -> None:
424495 "color" : lang .get ("node" , {}).get ("color" ),
425496 }
426497
427- if owned_repos .get ("pageInfo" , {}).get (
498+ if self .org_name :
499+ if owned_repos .get ("pageInfo" , {}).get (
500+ "hasNextPage" , False
501+ ):
502+ next_owned = owned_repos .get ("pageInfo" , {}).get (
503+ "endCursor" , next_owned
504+ )
505+ else :
506+ break
507+ elif owned_repos .get ("pageInfo" , {}).get (
428508 "hasNextPage" , False
429509 ) or contrib_repos .get ("pageInfo" , {}).get ("hasNextPage" , False ):
430510 next_owned = owned_repos .get ("pageInfo" , {}).get (
@@ -515,6 +595,8 @@ async def total_contributions(self) -> int:
515595 """
516596 if self ._total_contributions is not None :
517597 return self ._total_contributions
598+ if self .org_name :
599+ return 0
518600
519601 # Check cache first
520602 cache_key = f"total_contributions_{ self .username } "
0 commit comments