-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpatchpirate.py
More file actions
136 lines (114 loc) · 5.12 KB
/
Copy pathpatchpirate.py
File metadata and controls
136 lines (114 loc) · 5.12 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import requests
from halo import Halo
from colorama import Fore, init
from datetime import datetime
import hashlib
# Initialize colorama with auto reset
init(autoreset=True)
# Initialize loading indicator
working_indicator = Halo(text=f'Searching user commits...', spinner='pong')
# program banner
banner = r"""
______ _ ______ _
(_____ \ _ | | (_____ (_) _
_____) )____ _| |_ ____| |__ _____) ) ____ _____ _| |_ _____
| ____(____ (_ _) ___) _ \| ____/ |/ ___|____ (_ _) ___ |
| | / ___ | | |( (___| | | | | | | | / ___ | | |_| ____|
|_| \_____| \__)____)_| |_|_| |_|_| \_____| \__)_____)
BY: ┳┓ ┏┓┓ ┏┓ ┏┓• ┏┓┓
┣┫┏┓┃┫┃┏ ┫┏┓┃┃┓┓┏ ┫┃
┻┛┛ ┗┛┛┗┗┛┛┗┣┛┗┛┗┗┛┗ Version: 1.1.0
-----------------------------------------------------------------
"""
# Display program banner at top
print(f"{Fore.RED}{banner}")
# Optionally use a personal access token for higher rate limits
GITHUB_TOKEN = input(f"{Fore.YELLOW}Enter GitHub Personal Access Token (or press Enter to skip): ").strip()
HEADERS = {'Authorization': f'token {GITHUB_TOKEN}'} if GITHUB_TOKEN else {}
# Fetch all commits authored by the user across their repositories
def get_user_commits(username):
commits = []
repos = []
page = 1
while True:
url = f"https://api.github.com/users/{username}/repos?page={page}&per_page=100"
response = requests.get(url, headers=HEADERS)
if response.status_code == 403:
handle_rate_limit(response)
elif response.status_code != 200:
raise Exception(f"Error fetching repos: {response.status_code}")
data = response.json()
if not data:
break
repos.extend(data)
page += 1
print(f"{Fore.BLUE}Found {len(repos)} repositories for user {Fore.RED}{username}{Fore.BLUE}.")
working_indicator.start()
for repo in repos:
repo_name = repo['name']
owner = repo['owner']['login']
page = 1
while True:
url = f"https://api.github.com/repos/{owner}/{repo_name}/commits?author={username}&page={page}&per_page=100"
response = requests.get(url, headers=HEADERS)
if response.status_code == 403:
handle_rate_limit(response)
elif response.status_code != 200:
break
data = response.json()
if not data:
break
for commit in data:
commits.append({
'repo': repo_name,
'message': commit['commit']['message'],
'url': commit['html_url'],
'date': commit['commit']['author']['date'],
'sha': commit['sha'][:7],
'email': commit['commit']['author']['email']
})
page += 1
working_indicator.stop()
return commits
# Handle GitHub rate limiting errors
def handle_rate_limit(response):
reset_timestamp = int(response.headers.get('X-RateLimit-Reset', 0))
reset_time = datetime.fromtimestamp(reset_timestamp).strftime('%Y-%m-%d %H:%M:%S')
remaining = response.headers.get('X-RateLimit-Remaining', '0')
print(f"\n{Fore.RED}GitHub API rate limit exceeded.")
print(f"{Fore.YELLOW}Remaining requests: {remaining}")
print(f"{Fore.YELLOW}Rate limit resets at: {Fore.CYAN}{reset_time}")
raise Exception("Rate limit hit. Please wait for cooldown or use a personal access token.")
def generate_gravatar_url(email):
# Normalize the email address
email = email.strip().lower()
# Calculate MD5 hash
email_hash = hashlib.md5(email.encode('utf-8')).hexdigest()
# Return the Gravatar URL
return f"https://www.gravatar.com/{email_hash} {Fore.BLUE}({Fore.LIGHTBLACK_EX}{email}{Fore.BLUE})"
if __name__ == "__main__":
username = input(f"{Fore.GREEN}Enter GitHub username: ").strip()
email_addresses = set()
obfuscated = ""
try:
user_commits = get_user_commits(username)
for commit in user_commits:
email = commit['email']
if email:
if email.endswith("noreply.github.com"):
obfuscated = email
else:
email_addresses.add(email)
print(f"{Fore.BLUE}Total commits found: {Fore.RED}{len(user_commits)}")
print("---------------------------------------------------------------------")
print(f"Obfucated noreply address: {Fore.GREEN}{obfuscated}")
print("---------------------------------------------------------------------")
print(f"{Fore.RED}Email Addresses:\n")
for email in email_addresses:
print(f"{Fore.GREEN}{email}")
print("---------------------------------------------------------------------")
print(f"{Fore.RED}Gravitars:\n")
for email in email_addresses:
print(f"{Fore.GREEN}{generate_gravatar_url(email)}")
except Exception as e:
print(f"An error occurred: {e}")