Skip to content

Commit 2d0e59e

Browse files
committed
ADDED: first functional version with clone functionality
1 parent d3bcceb commit 2d0e59e

14 files changed

Lines changed: 227 additions & 144 deletions

.run/main.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<option name="ADD_CONTENT_ROOTS" value="true" />
1515
<option name="ADD_SOURCE_ROOTS" value="true" />
1616
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/main.py" />
17-
<option name="PARAMETERS" value="AleixMT" />
17+
<option name="PARAMETERS" value="AleixMT --exclude-gitlab" />
1818
<option name="SHOW_COMMAND_LINE" value="false" />
1919
<option name="EMULATE_TERMINAL" value="false" />
2020
<option name="MODULE_MODE" value="false" />

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
PyGithub
2-
argparse
2+
argparse
3+
gitpython

src/defines/ProviderType.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55

66
class ProviderType(Enum):
77
GITHUB = 1
8-
GITLAB = 2
8+
GITLAB = 2

src/demos.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,31 @@
33

44
from src.service.GitHubService import GitHubService
55
from src.service.ProviderService import ProviderService
6-
from src.service.TokenService import get_github_token
6+
from src.service.TokenService import get_github_official_token
77

88

99
def get_my_gh_organization_names():
10-
gh: ProviderService = GitHubService(get_github_token())
10+
gh: ProviderService = GitHubService(get_github_official_token())
1111
print(gh.get_user_organization_names("AleixMT"))
1212

1313

1414
def get_my_gh_owned_repo_names():
15-
gh: ProviderService = GitHubService(get_github_token())
15+
gh: ProviderService = GitHubService(get_github_official_token())
1616
print(gh.get_user_owned_repo_names("AleixMT"))
1717

1818

1919
def get_my_gh_collaboration_repo_names():
20-
gh: ProviderService = GitHubService(get_github_token())
20+
gh: ProviderService = GitHubService(get_github_official_token())
2121
print(gh.get_user_collaboration_repo_names("AleixMT"))
2222

2323

2424
def get_my_gh_organization_repo_names():
25-
gh: ProviderService = GitHubService(get_github_token())
25+
gh: ProviderService = GitHubService(get_github_official_token())
2626
print(gh.get_organization_repo_names("AleixMT"))
2727

2828

2929
def get_my_gh_organizations_repo_names():
30-
gh: ProviderService = GitHubService(get_github_token())
30+
gh: ProviderService = GitHubService(get_github_official_token())
3131
for org_name in gh.get_user_organization_names("AleixMT"):
3232
print("GH organization name: " + org_name)
3333
print("Repositories:")

src/main.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
from pathlib import Path
43

54
from src.defines.FlattenLevel import FlattenLevel
65
from src.defines.RenameStrategy import RenameStrategy
76
from src.model.Repository import Repository
87
from src.service.GitHubService import GitHubService, build_github_official_provider
9-
from src.service.ProviderService import ProviderService, build_provider
8+
from src.service.ProviderService import ProviderService, build_provider, build_custom_provider
109
from src.service.RepositoryService import compute_path
11-
from src.service.TokenService import get_github_token
10+
from src.service.TokenService import get_github_official_token, get_custom_provider_token, get_gitlab_official_token
1211
from src.defines.ProviderType import ProviderType
1312
from src.service.GitLabService import build_gitlab_official_provider, GitLabService
1413
from src.service.ArgumentParserService import build_argument_parser, parse_arguments
@@ -36,64 +35,65 @@ def build_model(args):
3635
if args.custom_providers:
3736
for custom_provider in args.custom_providers:
3837
if args.exclude_github:
39-
providers.append(build_provider(custom_provider, ProviderType.GITLAB))
38+
providers.append(build_custom_provider(ProviderType.GITLAB, custom_provider))
4039
if args.exclude_gitlab:
41-
providers.append(build_provider(custom_provider, ProviderType.GITHUB))
40+
providers.append(build_custom_provider(ProviderType.GITHUB, custom_provider))
4241
if not args.exclude_gitlab and not args.exclude_github:
43-
providers.append(build_provider(custom_provider, ProviderType.GITLAB))
44-
providers.append(build_provider(custom_provider, ProviderType.GITHUB))
42+
providers.append(build_custom_provider(ProviderType.GITLAB, custom_provider))
43+
providers.append(build_custom_provider(ProviderType.GITHUB, custom_provider))
4544

4645
model = {}
4746
for username in args.usernames:
4847
for provider in providers:
4948
provider_service = None
50-
if provider.provider == ProviderType.GITLAB:
49+
if provider.provider is ProviderType.GITLAB:
5150
provider_service = GitLabService(provider.token, provider.url)
52-
elif provider.provider == ProviderType.GITHUB:
51+
elif provider.provider is ProviderType.GITHUB:
5352
provider_service = GitHubService(provider.token, provider.url)
5453

5554
organizations = [username]
56-
organizations.extend(provider_service.get_user_organization_names(username))
55+
names = provider_service.get_user_organization_names(username)
56+
organizations.extend(names)
5757
for organization in organizations:
5858
repos = provider_service.get_organization_repo_names(organization)
5959
for repo in repos:
6060
new_repo = Repository(args.backup_name, username, provider, organization, repo,
6161
provider.url + "/" + organization + "/" + repo)
62-
computed_path = compute_path(repo, FlattenLevel.ROOT.name in args.flatten_directories,
62+
compute_path(new_repo, FlattenLevel.ROOT.name in args.flatten_directories,
6363
FlattenLevel.USER.name in args.flatten_directories,
6464
FlattenLevel.PROVIDER.name in args.flatten_directories,
6565
FlattenLevel.ORGANIZATION.name in args.flatten_directories)
66-
new_repo.path = computed_path
66+
computed_path = new_repo.path
6767
if computed_path not in model:
68-
model[computed_path] = [new_repo]
68+
model[computed_path] = new_repo
6969
else:
7070
if args.rename_strategy == RenameStrategy.IGNORE:
7171
pass
7272
elif args.rename_strategy == RenameStrategy.SHORTEST:
7373
new_repo = Repository(args.backup_name, username, provider, organization, repo,
74-
provider.url + "/" + organization + "/" + repo)
74+
provider.url + "/" + organization + "/" + repo, computed_path)
7575
repo_name_level = FlattenLevel.USER
7676
while computed_path in model:
7777
repo_name_level = FlattenLevel(repo_name_level.value - 1)
78-
computed_path = compute_path(new_repo, FlattenLevel.ROOT.name in args.flatten_directories,
78+
compute_path(new_repo, FlattenLevel.ROOT.name in args.flatten_directories,
7979
FlattenLevel.USER.name in args.flatten_directories,
8080
FlattenLevel.PROVIDER.name in args.flatten_directories,
8181
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
8282
FlattenLevel(repo_name_level.value - 1))
83-
new_repo.path = computed_path
84-
model[computed_path] = [new_repo]
83+
computed_path = new_repo.path
84+
model[computed_path] = new_repo
8585
elif args.rename_strategy == RenameStrategy.SYSTEMATIC:
8686
repo1 = model.pop(computed_path)
87-
repo1.path = compute_path(repo1, FlattenLevel.ROOT.name in args.flatten_directories,
87+
compute_path(repo1, FlattenLevel.ROOT.name in args.flatten_directories,
8888
FlattenLevel.USER.name in args.flatten_directories,
8989
FlattenLevel.PROVIDER.name in args.flatten_directories,
9090
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
9191
FlattenLevel.ROOT)
92-
model[repo1.path] = [repo1]
92+
model[repo1.path] = repo1
9393

9494
new_repo = Repository(args.backup_name, username, provider, organization, repo,
9595
provider.url + "/" + organization + "/" + repo)
96-
new_repo.path = computed_path(repo, FlattenLevel.ROOT.name in args.flatten_directories,
96+
compute_path(new_repo, FlattenLevel.ROOT.name in args.flatten_directories,
9797
FlattenLevel.USER.name in args.flatten_directories,
9898
FlattenLevel.PROVIDER.name in args.flatten_directories,
9999
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
@@ -103,20 +103,36 @@ def build_model(args):
103103
pass
104104
# TODO
105105

106-
print(model)
106+
return model
107+
108+
109+
def clone_repos(model, backup_folder):
110+
for key, value in model.items():
111+
provider_service = None
112+
if value.provider.provider is ProviderType.GITLAB:
113+
provider_service = GitLabService(value.provider.token, value.provider.url)
114+
elif value.provider.provider is ProviderType.GITHUB:
115+
provider_service = GitHubService(value.provider.token, value.provider.url)
116+
print(value.link + " " + backup_folder + "/" + key.__str__())
117+
provider_service.clone_repo(value.link, backup_folder / key)
118+
107119

108120
def main():
109121
parser = build_argument_parser()
110122
args = parse_arguments(parser)
111123
if args.is_verbose:
112124
print_summary(args)
113125
model = build_model(args)
126+
clone_repos(model, args.backup_folder)
114127

115128

116129
if __name__ == "__main__":
117130
# Generate same date string for all entities
131+
import sys
132+
import os
133+
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
118134

119-
gh: ProviderService = GitHubService(get_github_token())
120-
print(gh.get_user_collaboration_repo_names("AleixMT"))
135+
#gh: ProviderService = GitHubService(get_github_official_token())
136+
#print(gh.get_user_organization_names("AleixMT"))
121137

122138
main()

src/model/Provider.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77

88
class Provider:
9-
def __init__(self, url: str, provider: ProviderType, token: str):
10-
self.url = url
9+
def __init__(self, provider: ProviderType, url: str, token: str):
1110
self.provider = provider
11+
self.url = url
1212
self.token = token
1313

1414

src/service/ArgumentParserService.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
33
import os
4+
import re
45
from datetime import datetime
56

6-
from src.service.FileService import is_file_directory_writable, is_file_writable
7+
from src.service.IOService import is_file_directory_writable, is_file_writable
78
import argparse
89

910
from src.defines.CollisionAction import CollisionAction
@@ -180,7 +181,7 @@ def parse_arguments(parser: argparse.ArgumentParser):
180181

181182
# Supply default backup directory
182183
if not args.backup_folder:
183-
args.backup_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "backup")
184+
args.backup_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "backup")
184185

185186
# Check existence and access of backup directory
186187
if not os.path.exists(args.backup_folder):
@@ -215,6 +216,10 @@ def parse_arguments(parser: argparse.ArgumentParser):
215216
and not args.rename_strategy:
216217
args.rename_strategy = RenameStrategy.SHORTEST_SYSTEMATIC
217218

219+
# Default to empty list
220+
if not args.flatten_directories:
221+
args.flatten_directories = []
222+
218223
if not args.rename_strategy:
219224
args.rename_strategy = RenameStrategy.SHORTEST_SYSTEMATIC
220225

@@ -263,3 +268,23 @@ def parse_arguments(parser: argparse.ArgumentParser):
263268
if args.exclude_gitlab:
264269
custom_providers.append(build_provider(custom_provider, ProviderType.GITHUB))
265270
return args
271+
272+
273+
def infer_name(input_string):
274+
# Regular expressions
275+
ip_regex = r'^((https?://)?((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$'
276+
dns_regex = r'^((https?://)?([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+)$'
277+
278+
# Check if the string is an IP or an IP with "https://"
279+
if re.match(ip_regex, input_string):
280+
# Extract the IP address without "https://"
281+
ip_match = re.search(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', input_string)
282+
return ip_match.group()
283+
284+
# Check if the string is a DNS name (including single-word hostnames)
285+
elif re.match(dns_regex, input_string):
286+
# Extract the DNS name without "https://"
287+
dns_match = re.search(r'([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$', input_string)
288+
return dns_match.group()
289+
290+
raise ValueError("Invalid Input: " + input_string)

src/service/FileService.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/service/GitHubService.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
from typing import Optional, List
22

3+
from src.service.ArgumentParserService import infer_name
34
from src.service.ProviderService import ProviderService, build_provider
45
from github import Github
56
from github import Auth
7+
from git import Repo # TODO separate in its own file
8+
69

710
from src.defines.ProviderType import ProviderType
11+
from src.service.TokenService import get_github_official_token
812

913

1014
class GitHubService(ProviderService):
1115
"""Service for interacting with GitHub."""
1216

1317
def __init__(self, access_token, url: Optional[str] = None):
1418
if url:
15-
self.g = Github(base_url=url, auth=Auth.Token(access_token))
19+
if infer_name(url).__eq__("github.com"):
20+
self.g = Github(auth=Auth.Token(access_token))
21+
else:
22+
self.g = Github(base_url=url, auth=Auth.Token(access_token))
1623
else:
1724
self.g = Github(auth=Auth.Token(access_token))
1825

@@ -56,6 +63,9 @@ def get_organization_repos(self, organization):
5663
def get_organization_repo_names(self, organization) -> List[str]:
5764
return [repo.name for repo in self.get_user_owned_repos(organization)]
5865

66+
def clone_repo(self, url, path):
67+
Repo.clone_from(url, path)
68+
5969

6070
def build_github_official_provider():
61-
return build_provider('https://github.com/', ProviderType.GITHUB)
71+
return build_provider(ProviderType.GITHUB, 'https://github.com', get_github_official_token())

src/service/GitLabService.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from src.service.ProviderService import ProviderService, build_provider
44
from src.defines.ProviderType import ProviderType
5+
from src.service.TokenService import get_gitlab_official_token
56

67

78
class GitLabService(ProviderService):
@@ -30,4 +31,4 @@ def get_organization_repo_names(self, organization) -> List[str]:
3031

3132

3233
def build_gitlab_official_provider():
33-
return build_provider('https://gitlab.com/', ProviderType.GITLAB)
34+
return build_provider(ProviderType.GITLAB, 'https://gitlab.com/', get_gitlab_official_token())

0 commit comments

Comments
 (0)