-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
108 lines (85 loc) · 3.63 KB
/
main.py
File metadata and controls
108 lines (85 loc) · 3.63 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
import os
import requests
import subprocess
import questionary
from colorama import init, Fore, Style
init(autoreset=True)
# your GitHub username and token (ensure it has repo access)
USERNAME = ''
GITHUB_TOKEN=""
API_URL = f'https://api.github.com/user/repos?type=owner&per_page=100'
headers = {
'Authorization': f'token {GITHUB_TOKEN}'
}
def get_repositories(repo_type='both', include_forks=False):
repos = []
page = 1
while True:
print(f"{Fore.CYAN}Fetching page {page} of repositories...")
response = requests.get(f'{API_URL}&page={page}', headers=headers)
print(f"{Fore.YELLOW}Response status code: {response.status_code}")
if response.status_code == 200:
data = response.json()
print(f"{Fore.GREEN}Fetched {len(data)} repositories on page {page}")
if not data:
break
for repo in data:
# filtering before appending
if not repo['fork'] or include_forks:
if repo_type == 'both' or (repo_type == 'public' and not repo['private']) or (repo_type == 'private' and repo['private']):
repos.append(repo)
page += 1
else:
print(f"{Fore.RED}Error fetching repositories: {response.status_code}")
break
return repos
def is_empty_repo(repo_url):
response = requests.get(f'{repo_url}/contents', headers=headers)
return response.status_code == 200 and len(response.json()) == 0
def clone_repositories(repos):
for repo in repos:
repo_name = repo['name']
repo_url = repo['clone_url'].replace("https://", f"https://{GITHUB_TOKEN}@")
print(f"{Fore.WHITE}Found repo: {repo['full_name']} (Private: {repo['private']})")
if not os.path.exists(repo_name):
print(f"{Fore.GREEN}Cloning repository: {repo_name}...")
if is_empty_repo(repo_url):
print(f"{Fore.YELLOW}Skipping empty repository: {repo_name}")
else:
try:
subprocess.run(['git', 'clone', repo_url], check=True)
print(f"{Fore.GREEN}Successfully cloned: {repo_name}")
except subprocess.CalledProcessError as e:
print(f"{Fore.RED}Failed to clone {repo_name}: {e}")
else:
print(f"{Fore.YELLOW}Repository '{repo_name}' already exists, skipping.")
def main():
include_forks_input = questionary.confirm(
"Do you want to clone forked repositories as well?",
default=False
).ask()
repo_type_input = questionary.select(
"Which type of repositories do you want to clone?",
choices=['public', 'private', 'both'],
default='both'
).ask()
print(f"{Fore.CYAN}Fetching your repositories...")
repos = get_repositories(repo_type_input, include_forks_input)
if repos:
print(f"{Fore.GREEN}Total repositories to clone: {len(repos)}\n")
print(f"{Fore.CYAN}Here are the repositories available for cloning:")
for idx, repo in enumerate(repos, start=1):
repo_type = "Private" if repo['private'] else "Public"
print(f"{Fore.WHITE}{idx}. {repo['full_name']} ({repo_type})")
proceed = questionary.confirm(
"Do you want to proceed with cloning these repositories?",
default=True
).ask()
if proceed:
clone_repositories(repos)
else:
print(f"{Fore.YELLOW}Cloning aborted.")
else:
print(f"{Fore.RED}No repositories to clone.")
if __name__ == "__main__":
main()