-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.py
115 lines (95 loc) · 3.83 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# pylint: disable=missing-module-docstring
import os
import sys
import argparse
from dotenv import load_dotenv
from rich.progress import track
from rich import print as cprint
from requests.exceptions import RequestException, Timeout
from utils import github, GithubAPIError
gh: github
def multi_invite(org: str, a_users: list):
"""
Invite multiple users to a GitHub organization.
Args:
org (str): The name of the GitHub organization.
users (list): A list of usernames to invite.
Returns:
None
"""
successful_invites = 0
failed_invites = 0
already_members = 0
cprint(f"[magenta] Inviting {len(a_users)} user/s ..")
for user in track(a_users, description="Inviting users"):
try:
uid = gh.get_user_id(user)
if uid is None:
cprint(f"[red]: User {user} does not exist")
failed_invites += 1
continue
# Check if user is already a member of the organization
if gh.is_user_member_of_org(org, uid):
cprint(f"[yellow]: User {user} is already a member of the organization")
already_members += 1
continue
cprint(f"[green]: Sending invite to {user}")
inv = gh.invite_user_org(org, uid)
if inv.status_code == 201:
cprint(f"[green]: Invite sent successfully to {user}")
successful_invites += 1
elif inv.status_code == 422: # 422 Unprocessable Entity
error_response = inv.json()
if any(error['code'] == 'unprocessable' for error in error_response.get('errors', [])):
cprint(f"[yellow]: User {user} is already invited")
already_members += 1
else:
cprint(f"[red]: Could not invite {user}")
cprint(f"[gray]: Error details: {error_response}")
failed_invites += 1
else:
cprint(f"[red]: Could not invite {user}")
cprint(f"[gray]: Error details: {inv.json()}")
failed_invites += 1
except GithubAPIError as e:
cprint(f"[red]: GitHub API error while processing {user}: {str(e)}")
if e.status_code:
cprint(f"[gray]: Status code: {e.status_code}")
if e.response:
cprint(f"[gray]: Response details: {e.response}")
failed_invites += 1
except Exception as e:
cprint(f"[red]: Unexpected error while processing {user}: {str(e)}")
failed_invites += 1
# Print summary
cprint("\n[bold]Invitation Summary:")
cprint(f"[green]✓ Successfully invited: {successful_invites}")
cprint(f"[yellow]⚠ Already members/invited: {already_members}")
cprint(f"[red]✗ Failed invites: {failed_invites}")
if __name__ == "__main__":
# Load environment variables
if os.path.exists(".env"):
load_dotenv(".env")
# Parse arguments
parser = argparse.ArgumentParser(
prog="GitHub Organization Inviter",
epilog="v0.0.1"
)
parser.add_argument("--users_file", dest="users_file",
help="invite multiple users", required=True)
parser.add_argument(
"--org", dest="org", help="The organization to invite the user to.", required=True)
args = parser.parse_args()
auth = os.environ["GITHUB_ACCESS_TOKEN"]
gh = github(auth)
if not args.org:
cprint("[red]: requires org name")
sys.exit(1)
users = []
if args.users_file:
usr_file = args.users_file
if os.path.exists(usr_file):
with open(usr_file, 'r', encoding="utf-8") as f:
users = f.readlines()
users = [u.strip() for u in users]
multi_invite(args.org, a_users=users)