Created
July 10, 2025 16:39
-
-
Save wjkennedy/8f47cc1856c2106dbd03c655a2d5e66f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| import configparser | |
| import time | |
| from collections import defaultdict | |
| # Load config | |
| config = configparser.ConfigParser() | |
| config.read("config/config.properties") | |
| JIRA_SERVER = config.get("jira", "server") | |
| JIRA_USER = config.get("jira", "username") | |
| JIRA_PASS = config.get("jira", "password") | |
| AUTH = (JIRA_USER, JIRA_PASS) | |
| HEADERS = {"Accept": "application/json"} | |
| # Paginated GET helper | |
| def fetch_paginated(url, params=None): | |
| results = [] | |
| start_at = 0 | |
| max_results = 100 | |
| while True: | |
| page_params = {"startAt": start_at, "maxResults": max_results} | |
| if params: | |
| page_params.update(params) | |
| response = requests.get(url, headers=HEADERS, auth=AUTH, params=page_params) | |
| response.raise_for_status() | |
| data = response.json() | |
| items = data.get("values") or data.get("users") or data.get("issues", []) | |
| results.extend(items) | |
| if start_at + max_results >= data.get("total", len(items)): | |
| break | |
| start_at += max_results | |
| time.sleep(0.1) | |
| return results | |
| # Step 1: Get all active users | |
| def get_all_active_users(): | |
| url = f"{JIRA_SERVER}/rest/api/2/user/search" | |
| users = fetch_paginated(url, params={"username": "", "active": "true"}) | |
| return {u["name"]: u.get("emailAddress", "N/A") for u in users if "atlassian" not in u.get("name", "")} | |
| # Step 2: Get all activity in last 90 days | |
| def get_activity_users(): | |
| url = f"{JIRA_SERVER}/rest/api/2/search" | |
| jql = "updated >= -90d" | |
| fields = "creator,reporter,assignee,comment" | |
| issues = fetch_paginated(url, params={"jql": jql, "fields": fields}) | |
| active_users = set() | |
| for issue in issues: | |
| fields_data = issue.get("fields", {}) | |
| for key in ["creator", "reporter", "assignee"]: | |
| if fields_data.get(key) and fields_data[key].get("name"): | |
| active_users.add(fields_data[key]["name"]) | |
| comments = fields_data.get("comment", {}).get("comments", []) | |
| for c in comments: | |
| author = c.get("author", {}).get("name") | |
| if author: | |
| active_users.add(author) | |
| return active_users | |
| # Main | |
| if __name__ == "__main__": | |
| print("Collecting active users...") | |
| all_users = get_all_active_users() | |
| print(f"Total active users: {len(all_users)}") | |
| print("Collecting users with meaningful activity...") | |
| active_users = get_activity_users() | |
| print(f"Users with recent activity: {len(active_users)}") | |
| inactive_users = {name: email for name, email in all_users.items() if name not in active_users} | |
| print(f"Inactive users (no meaningful activity in last 90 days): {len(inactive_users)}") | |
| print("\n--- Inactive Users ---") | |
| for name, email in inactive_users.items(): | |
| print(f"{email} ({name})") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment