Skip to content

Commit d3bcceb

Browse files
committed
UPDATED: building model
1 parent dc0d3d6 commit d3bcceb

File tree

12 files changed

+227
-66
lines changed

12 files changed

+227
-66
lines changed

.run/demos.run.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="demos" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
3+
<module name="github-backup" />
4+
<option name="ENV_FILES" value="" />
5+
<option name="INTERPRETER_OPTIONS" value="" />
6+
<option name="PARENT_ENVS" value="true" />
7+
<envs>
8+
<env name="PYTHONUNBUFFERED" value="1" />
9+
</envs>
10+
<option name="SDK_HOME" value="" />
11+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src" />
12+
<option name="IS_MODULE_SDK" value="true" />
13+
<option name="ADD_CONTENT_ROOTS" value="true" />
14+
<option name="ADD_SOURCE_ROOTS" value="true" />
15+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/demos.py" />
16+
<option name="PARAMETERS" value="" />
17+
<option name="SHOW_COMMAND_LINE" value="false" />
18+
<option name="EMULATE_TERMINAL" value="false" />
19+
<option name="MODULE_MODE" value="false" />
20+
<option name="REDIRECT_INPUT" value="false" />
21+
<option name="INPUT_FILE" value="" />
22+
<method v="2" />
23+
</configuration>
24+
</component>

.run/main.run.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="main" type="PythonConfigurationType" factoryName="Python">
3+
<module name="github-backup" />
4+
<option name="ENV_FILES" value="" />
5+
<option name="INTERPRETER_OPTIONS" value="" />
6+
<option name="PARENT_ENVS" value="true" />
7+
<envs>
8+
<env name="PYTHONUNBUFFERED" value="1" />
9+
</envs>
10+
<option name="SDK_HOME" value="" />
11+
<option name="SDK_NAME" value="Python 3.8 (github-backup)" />
12+
<option name="WORKING_DIRECTORY" value="" />
13+
<option name="IS_MODULE_SDK" value="false" />
14+
<option name="ADD_CONTENT_ROOTS" value="true" />
15+
<option name="ADD_SOURCE_ROOTS" value="true" />
16+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/main.py" />
17+
<option name="PARAMETERS" value="AleixMT" />
18+
<option name="SHOW_COMMAND_LINE" value="false" />
19+
<option name="EMULATE_TERMINAL" value="false" />
20+
<option name="MODULE_MODE" value="false" />
21+
<option name="REDIRECT_INPUT" value="false" />
22+
<option name="INPUT_FILE" value="" />
23+
<method v="2" />
24+
</configuration>
25+
</component>

src/defines/FlattenLevel.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ class FlattenLevel(Enum):
77
ROOT = 1
88
USER = 2
99
PROVIDER = 3
10-
ORGANIZATION = 4
10+
ORGANIZATION = 4
11+
REPO = 5

src/main.py

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,109 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
from pathlib import Path
34

5+
from src.defines.FlattenLevel import FlattenLevel
6+
from src.defines.RenameStrategy import RenameStrategy
7+
from src.model.Repository import Repository
48
from src.service.GitHubService import GitHubService, build_github_official_provider
59
from src.service.ProviderService import ProviderService, build_provider
10+
from src.service.RepositoryService import compute_path
611
from src.service.TokenService import get_github_token
712
from src.defines.ProviderType import ProviderType
8-
from src.service.GitLabService import build_gitlab_official_provider
13+
from src.service.GitLabService import build_gitlab_official_provider, GitLabService
914
from src.service.ArgumentParserService import build_argument_parser, parse_arguments
1015
from src.service.UnparserService import print_summary
1116

17+
'''
18+
/backup/owner/provider/organization/repo
19+
'''
20+
1221

1322
def build_model(args):
23+
providers = []
1424

15-
model = {args.backup_name: {}}
25+
if args.custom_providers:
26+
providers.extend(args.custom_providers)
1627

17-
for username in args.usernames:
18-
model[args.backup_name][username] = {}
19-
if not args.exclude_enterprise:
28+
if not args.exclude_enterprise:
29+
if args.exclude_github:
30+
providers.append(build_gitlab_official_provider())
31+
if args.exclude_gitlab:
32+
providers.append(build_github_official_provider())
33+
if not args.exclude_gitlab and not args.exclude_github:
34+
providers.append(build_gitlab_official_provider())
35+
providers.append(build_github_official_provider())
36+
if args.custom_providers:
37+
for custom_provider in args.custom_providers:
2038
if args.exclude_github:
21-
model[args.backup_name][username]["GitLab"] = build_gitlab_official_provider()
39+
providers.append(build_provider(custom_provider, ProviderType.GITLAB))
2240
if args.exclude_gitlab:
23-
model[args.backup_name][username]["GitHub"] = build_github_official_provider()
41+
providers.append(build_provider(custom_provider, ProviderType.GITHUB))
2442
if not args.exclude_gitlab and not args.exclude_github:
25-
model[args.backup_name][username]["GitLab"] = build_gitlab_official_provider()
26-
model[args.backup_name][username]["GitHub"] = build_github_official_provider()
27-
if args.custom_providers:
28-
for custom_provider in args.custom_providers:
29-
if args.exclude_github:
30-
model[args.backup_name][username][custom_provider] = build_provider(custom_provider, ProviderType.GITLAB)
31-
if args.exclude_gitlab:
32-
model[args.backup_name][username][custom_provider] = build_provider(custom_provider, ProviderType.GITHUB)
33-
if not args.exclude_gitlab and not args.exclude_github:
34-
model[args.backup_name][username][custom_provider] = build_provider(custom_provider, ProviderType.GITLAB)
35-
model[args.backup_name][username][custom_provider] = build_provider(custom_provider, ProviderType.GITHUB)
43+
providers.append(build_provider(custom_provider, ProviderType.GITLAB))
44+
providers.append(build_provider(custom_provider, ProviderType.GITHUB))
45+
46+
model = {}
47+
for username in args.usernames:
48+
for provider in providers:
49+
provider_service = None
50+
if provider.provider == ProviderType.GITLAB:
51+
provider_service = GitLabService(provider.token, provider.url)
52+
elif provider.provider == ProviderType.GITHUB:
53+
provider_service = GitHubService(provider.token, provider.url)
3654

55+
organizations = [username]
56+
organizations.extend(provider_service.get_user_organization_names(username))
57+
for organization in organizations:
58+
repos = provider_service.get_organization_repo_names(organization)
59+
for repo in repos:
60+
new_repo = Repository(args.backup_name, username, provider, organization, repo,
61+
provider.url + "/" + organization + "/" + repo)
62+
computed_path = compute_path(repo, FlattenLevel.ROOT.name in args.flatten_directories,
63+
FlattenLevel.USER.name in args.flatten_directories,
64+
FlattenLevel.PROVIDER.name in args.flatten_directories,
65+
FlattenLevel.ORGANIZATION.name in args.flatten_directories)
66+
new_repo.path = computed_path
67+
if computed_path not in model:
68+
model[computed_path] = [new_repo]
69+
else:
70+
if args.rename_strategy == RenameStrategy.IGNORE:
71+
pass
72+
elif args.rename_strategy == RenameStrategy.SHORTEST:
73+
new_repo = Repository(args.backup_name, username, provider, organization, repo,
74+
provider.url + "/" + organization + "/" + repo)
75+
repo_name_level = FlattenLevel.USER
76+
while computed_path in model:
77+
repo_name_level = FlattenLevel(repo_name_level.value - 1)
78+
computed_path = compute_path(new_repo, FlattenLevel.ROOT.name in args.flatten_directories,
79+
FlattenLevel.USER.name in args.flatten_directories,
80+
FlattenLevel.PROVIDER.name in args.flatten_directories,
81+
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
82+
FlattenLevel(repo_name_level.value - 1))
83+
new_repo.path = computed_path
84+
model[computed_path] = [new_repo]
85+
elif args.rename_strategy == RenameStrategy.SYSTEMATIC:
86+
repo1 = model.pop(computed_path)
87+
repo1.path = compute_path(repo1, FlattenLevel.ROOT.name in args.flatten_directories,
88+
FlattenLevel.USER.name in args.flatten_directories,
89+
FlattenLevel.PROVIDER.name in args.flatten_directories,
90+
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
91+
FlattenLevel.ROOT)
92+
model[repo1.path] = [repo1]
3793

94+
new_repo = Repository(args.backup_name, username, provider, organization, repo,
95+
provider.url + "/" + organization + "/" + repo)
96+
new_repo.path = computed_path(repo, FlattenLevel.ROOT.name in args.flatten_directories,
97+
FlattenLevel.USER.name in args.flatten_directories,
98+
FlattenLevel.PROVIDER.name in args.flatten_directories,
99+
FlattenLevel.ORGANIZATION.name in args.flatten_directories,
100+
FlattenLevel.ROOT)
101+
model[new_repo.path] = new_repo
102+
elif args.rename_strategy == RenameStrategy.SHORTEST_SYSTEMATIC:
103+
pass
104+
# TODO
105+
106+
print(model)
38107

39108
def main():
40109
parser = build_argument_parser()
@@ -44,8 +113,6 @@ def main():
44113
model = build_model(args)
45114

46115

47-
48-
49116
if __name__ == "__main__":
50117
# Generate same date string for all entities
51118

src/model/Provider.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from enum import Enum
4+
5+
from src.defines.ProviderType import ProviderType
6+
7+
8+
class Provider:
9+
def __init__(self, url: str, provider: ProviderType, token: str):
10+
self.url = url
11+
self.provider = provider
12+
self.token = token
13+
14+

src/model/Repository.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,23 @@
11
from pathlib import Path
22

3-
from src.defines.defines import ProviderType
3+
from src.model.Provider import Provider
44

55

66
class Repository:
7-
def __init__(self, backup: str, owner: str, provider: ProviderType, organization: str, name: str, link: str):
7+
def __init__(self, backup: str, owner: str, provider: Provider, organization: str, name: str, link: str,
8+
path: Path = Path()):
89
self.backup = backup
910
self.owner = owner
1011
self.provider = provider
1112
self.organization = organization
1213
self.name = name
1314
self.link = link
14-
self.path = Path()
15+
self.path = path
1516

1617
def __str__(self):
1718
return (f"Repository(provider='{self.provider}', organization='{self.organization}', "
1819
f"name='{self.name}', repo_link='{self.link}', path='{self.path}')")
1920

20-
'''
21-
/backup/owner/provider/organization/repo
22-
'''
23-
def compute_path(self, ignore_backup: bool = False, ignore_owner: bool = False, ignore_provider: bool = False,
24-
ignore_organization: bool = False):
25-
self.path = Path()
26-
if not ignore_backup:
27-
self.path = self.path / self.backup
28-
if not ignore_owner:
29-
self.path = self.path / self.owner
30-
if not ignore_provider:
31-
self.path = self.path / self.provider.name
32-
if not ignore_organization:
33-
self.path = self.path / self.organization
34-
self.path = self.path / self.name
21+
3522

3623

src/service/ArgumentParserService.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import os
44
from datetime import datetime
55

6-
from FileService import is_file_directory_writable, is_file_writable
6+
from src.service.FileService import is_file_directory_writable, is_file_writable
77
import argparse
88

99
from src.defines.CollisionAction import CollisionAction
1010
from src.defines.FlattenLevel import FlattenLevel
11+
from src.defines.ProviderType import ProviderType
1112
from src.defines.RenameStrategy import RenameStrategy
13+
from src.service.ProviderService import build_provider
1214

1315

1416
# TODO: prioritize argument to give priority
@@ -66,50 +68,50 @@ def build_argument_parser():
6668
help="Hierarchy levels of the backup that will not be present in the hierarchical structure"
6769
" of the folder "
6870
"structure of the backup. Implies -y except when "
69-
"flattening all directory level:" +
70-
FlattenLevel.ROOT.name + ": Flattens root folder in the backup." +
71-
FlattenLevel.USER.name + ": Flattens user folders in the backup" +
72-
FlattenLevel.PROVIDER.name + ": Flattens provider folder in the backup." +
71+
"flattening all directory level:\n" +
72+
FlattenLevel.ROOT.name + ": Flattens root folder in the backup.\n" +
73+
FlattenLevel.USER.name + ": Flattens user folders in the backup.\n" +
74+
FlattenLevel.PROVIDER.name + ": Flattens provider folder in the backup.\n" +
7375
FlattenLevel.ORGANIZATION.name + ": Flattens organization folder in the backup.",
7476
type=str,
7577
nargs="+",
7678
dest="flatten_directories",
77-
choices=[name for name in FlattenLevel])
79+
choices=[level.name for level in FlattenLevel])
7880
parser.add_argument("-R", "--rename", "--rename-strategy",
7981
help="Strategy to rename the path to clone a repositories that has same path as "
80-
"another:" +
82+
"another:\n" +
8183
RenameStrategy.SHORTEST.name + ": Use the shortest systematic name that avoids same path"
82-
"for the repo where the same path is detected." +
84+
"for the repo where the same path is detected.\n" +
8385
RenameStrategy.SHORTEST_SYSTEMATIC.name + ": Use the shortest systematic name that avoids "
84-
"same path for both repos that produce the "
85-
"same path." +
86+
"same path for all repos that produce the "
87+
"same path.\n" +
8688
RenameStrategy.SYSTEMATIC.name + ": Use the full systematic name for all repos with "
87-
"the same path." +
89+
"the same path.\n" +
8890
RenameStrategy.IGNORE.name + ": If a repo is found with the same clone path as another, do"
8991
" not clone the repo where the "
9092
"path coincidence is detected.",
9193
type=str,
9294
nargs='?',
9395
dest="rename_strategy",
94-
choices=[name for name in RenameStrategy])
96+
choices=[strategy.name for strategy in RenameStrategy])
9597
parser.add_argument("-S", "--collision", "--collision-strategy", "--collision-action",
9698
help="Strategy to follow when finding a repo already cloned in the path that another repo is "
97-
"supposed to be cloned" +
99+
"supposed to be cloned.\n" +
98100
CollisionAction.FULL_UPDATE.name + ": If the new repo to be cloned is different than the "
99101
"one already cloned, remove the one already cloned and"
100102
"clone the new one in its place, if not, update the "
101-
"repo already cloned." +
103+
"repo already cloned.\n" +
102104
CollisionAction.UPDATE.name + ": Ignore the new repo to be cloned and updates the repo "
103-
"already cloned." +
105+
"already cloned.\n" +
104106
CollisionAction.IGNORE.name + ": Ignore the new repo to be cloned and do nothing."
105-
"." +
107+
".\n" +
106108
CollisionAction.REMOVE.name + ": Remove the repo already cloned and clone the new one in "
107109
"the same path.",
108110
type=str,
109111
nargs='?',
110112
dest="collision_strategy",
111113
default=CollisionAction.FULL_UPDATE,
112-
choices=[name for name in CollisionAction])
114+
choices=[action.name for action in CollisionAction])
113115
parser.add_argument("-j", "--json", "--generate-json", "--produce-json",
114116
help="Generates a JSON report of the backup folders and repos.",
115117
# type=bool,
@@ -257,7 +259,7 @@ def parse_arguments(parser: argparse.ArgumentParser):
257259
custom_providers = []
258260
for custom_provider in args.custom_providers:
259261
if args.exclude_github:
260-
custom_providers.append({'url': custom_provider, 'provider': ProviderType.GITLAB})
262+
custom_providers.append(build_provider(custom_provider, ProviderType.GITLAB))
261263
if args.exclude_gitlab:
262-
custom_providers.append({'url': custom_provider, 'provider': ProviderType.GITHUB})
264+
custom_providers.append(build_provider(custom_provider, ProviderType.GITHUB))
263265
return args

src/service/GitHubService.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional, List
22

3-
from ProviderService import ProviderService, build_provider
3+
from src.service.ProviderService import ProviderService, build_provider
44
from github import Github
55
from github import Auth
66

src/service/GitLabService.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
from typing import List
1+
from typing import List, Optional
22

3-
from ProviderService import ProviderService, build_provider
3+
from src.service.ProviderService import ProviderService, build_provider
44
from src.defines.ProviderType import ProviderType
55

66

77
class GitLabService(ProviderService):
88
"""Service for interacting with GitLab."""
99

10-
def __init__(self, access_token):
10+
def __init__(self, access_token, url: Optional[str] = None):
1111
self.access_token = access_token
12-
# Assume some GitLab API client initialization here
12+
if url:
13+
pass
14+
#self.g = Github(base_url=url, auth=Auth.Token(access_token))
15+
else:
16+
pass
17+
#self.g = Github(auth=Auth.Token(access_token))
1318

1419
def get_user_organization_names(self, username) -> List[str]:
1520
pass

0 commit comments

Comments
 (0)