Skip to content

Commit 9e2406e

Browse files
committed
per org
1 parent a2dcd1c commit 9e2406e

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

tools/last_user_activity.py

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,35 @@
88
import asyncio
99
import aiohttp
1010
from rich import print
11-
from datetime import datetime, timezone
11+
from datetime import datetime, timezone, timedelta
1212
import humanize
1313
from itertools import count
1414
import diskcache
1515
import pathlib
1616
from typing import Optional, List, Dict
1717
import argparse
1818

19-
orgs = [
19+
default_orgs = [
2020
"binder-examples",
2121
"binderhub-ci-repos",
2222
"ipython",
2323
"jupyter",
24+
"jupyter-attic",
2425
"jupyter-book",
2526
"jupyter-governance",
2627
"jupyter-incubator",
28+
"jupyter-resources",
2729
"jupyter-server",
30+
"jupyter-standard",
2831
"jupyter-standards",
2932
"jupyter-widgets",
30-
"jupyterhub",
31-
"jupyterlab",
3233
"jupyter-xeus",
3334
"jupytercon",
35+
"jupyterhub",
36+
"jupyterlab",
3437
"voila-dashboards",
3538
"voila-gallery",
39+
"pickleshare",
3640
]
3741

3842
token = os.getenv("GH_TOKEN")
@@ -221,7 +225,7 @@ def clear_cache() -> None:
221225
print(f"[red]Error clearing cache: {str(e)}[/red]")
222226

223227

224-
async def main(debug: bool):
228+
async def main(orgs, debug: bool, timelimit_days: int):
225229
"""Main execution function."""
226230
# Show cache status
227231
print(f"[blue]Cache directory: {CACHE_DIR} (size: {get_cache_size()})[/blue]")
@@ -278,23 +282,33 @@ async def main(debug: bool):
278282
all_members[username],
279283
)
280284
)
281-
282-
for username, last_activity, user_orgs in sorted(
283-
user_activities,
284-
key=lambda x: (x[1], x[0])
285-
if x[1] is not None
286-
else (datetime.fromtimestamp(0).replace(tzinfo=timezone.utc), x[0]),
287-
reverse=True,
288-
):
289-
last_activity_ago = (
290-
humanize.naturaltime(datetime.now(last_activity.tzinfo) - last_activity)
291-
if last_activity
292-
else "[red]never[/red]"
293-
)
294-
orgs_str = ", ".join(user_orgs)
295-
print(
296-
f"{username:<20}: Last activity {last_activity_ago} in orgs: {orgs_str}"
297-
)
285+
for org in orgs:
286+
print(f"[bold]{org}[/bold]")
287+
n_active = 0
288+
n_inactive = 0
289+
for username, last_activity, user_orgs in sorted(
290+
user_activities,
291+
key=lambda x: (x[1], x[0])
292+
if x[1] is not None
293+
else (datetime.fromtimestamp(0).replace(tzinfo=timezone.utc), x[0]),
294+
reverse=True,
295+
):
296+
if org not in user_orgs:
297+
continue
298+
if last_activity is not None and last_activity > (datetime.now().replace(tzinfo=timezone.utc) - timedelta(days=timelimit_days)):
299+
n_active += 1
300+
continue
301+
n_inactive += 1
302+
last_activity_ago = (
303+
humanize.naturaltime(datetime.now(last_activity.tzinfo) - last_activity)
304+
if last_activity
305+
else "[red]never[/red]"
306+
)
307+
orgs_str = ", ".join(user_orgs)
308+
print(
309+
f" {username:<20}: Last activity {last_activity_ago}"
310+
)
311+
print(f" Found [red]{n_inactive} inactive[/red] and [green]{n_active} active[/green] users in {org} with last activity more recent than {timelimit_days} days.")
298312

299313

300314
if __name__ == "__main__":
@@ -303,9 +317,24 @@ async def main(debug: bool):
303317
"--clear-cache", action="store_true", help="Clear the cache before running"
304318
)
305319
parser.add_argument("--debug", action="store_true", help="Show debug information")
320+
321+
322+
parser.add_argument(
323+
"--timelimit-days",
324+
type=int,
325+
default=0,
326+
help="Time limit in days for the last activity (default: 30)",
327+
)
328+
parser.add_argument(
329+
"--orgs",
330+
nargs="+",
331+
default=default_orgs,
332+
help="GitHub organizations to track (default: all)",
333+
)
306334
args = parser.parse_args()
307335

336+
308337
if args.clear_cache:
309338
clear_cache()
310339

311-
asyncio.run(main(args.debug))
340+
asyncio.run(main(args.orgs, args.debug, args.timelimit_days))

0 commit comments

Comments
 (0)