NikGapps 3.29__py3-none-any.whl → 3.31__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. NikGapps/build/Build.py +8 -8
  2. NikGapps/build/NikGappsManager.py +2 -2
  3. NikGapps/build/Release.py +6 -6
  4. NikGapps/build_config.py +11 -11
  5. NikGapps/cache.py +12 -12
  6. NikGapps/config/NikGappsConfig.py +15 -15
  7. NikGapps/copy_repos.py +2 -2
  8. NikGapps/helper/Assets.py +8 -8
  9. NikGapps/helper/Package.py +2 -6
  10. NikGapps/helper/compression/CompOps.py +6 -6
  11. NikGapps/helper/compression/Export.py +10 -10
  12. NikGapps/helper/git/TestGit.py +1 -1
  13. NikGapps/helper/overlay/ApkMetaInfo.py +1 -1
  14. NikGapps/helper/overlay/Manifest.py +1 -1
  15. NikGapps/helper/overlay/Overlay.py +1 -1
  16. NikGapps/helper/upload/CmdUpload.py +7 -7
  17. NikGapps/helper/upload/GoFileUpload.py +7 -7
  18. NikGapps/main.py +9 -9
  19. NikGapps/overlay_control.py +11 -10
  20. NikGapps/test.py +1 -20
  21. {NikGapps-3.29.dist-info → NikGapps-3.31.dist-info}/METADATA +4 -3
  22. NikGapps-3.31.dist-info/RECORD +65 -0
  23. NikGapps/build/NikGappsPackages.py +0 -916
  24. NikGapps/helper/B64.py +0 -34
  25. NikGapps/helper/C.py +0 -16
  26. NikGapps/helper/Cmd.py +0 -296
  27. NikGapps/helper/FileOp.py +0 -235
  28. NikGapps/helper/Json.py +0 -34
  29. NikGapps/helper/P.py +0 -23
  30. NikGapps/helper/Statics.py +0 -166
  31. NikGapps/helper/SystemStat.py +0 -103
  32. NikGapps/helper/T.py +0 -82
  33. NikGapps/helper/XmlOp.py +0 -40
  34. NikGapps/helper/compression/Modes.py +0 -4
  35. NikGapps/helper/compression/Tar.py +0 -25
  36. NikGapps/helper/compression/Zip.py +0 -97
  37. NikGapps/helper/compression/Zsh.py +0 -17
  38. NikGapps/helper/git/Git.py +0 -228
  39. NikGapps/helper/git/GitOperations.py +0 -118
  40. NikGapps/helper/git/GitStatics.py +0 -14
  41. NikGapps/helper/git/GithubManager.py +0 -21
  42. NikGapps/helper/git/GitlabManager.py +0 -265
  43. NikGapps/helper/upload/Upload.py +0 -125
  44. NikGapps/helper/web/Requests.py +0 -139
  45. NikGapps/helper/web/TelegramApi.py +0 -126
  46. NikGapps/helper/web/__init__.py +0 -0
  47. NikGapps-3.29.dist-info/RECORD +0 -89
  48. {NikGapps-3.29.dist-info → NikGapps-3.31.dist-info}/LICENSE +0 -0
  49. {NikGapps-3.29.dist-info → NikGapps-3.31.dist-info}/WHEEL +0 -0
  50. {NikGapps-3.29.dist-info → NikGapps-3.31.dist-info}/entry_points.txt +0 -0
  51. {NikGapps-3.29.dist-info → NikGapps-3.31.dist-info}/top_level.txt +0 -0
@@ -1,228 +0,0 @@
1
- import re
2
-
3
- import git.exc
4
- from git import Repo, Commit
5
- from shutil import copyfile
6
- from .. import Config
7
- from ..FileOp import FileOp
8
- from ..Assets import Assets
9
- import os
10
- import time
11
- import datetime
12
- from datetime import datetime
13
- import pytz
14
- from .GitStatics import GitStatics
15
- from ..P import P
16
- from ..T import T
17
-
18
-
19
- class Git:
20
-
21
- def __init__(self, working_tree_dir):
22
- os.environ["GIT_CLONE_PROTECTION_ACTIVE"] = 'false'
23
- self.enable_push = Config.GIT_PUSH
24
- self.working_tree_dir = working_tree_dir
25
- self.repo_name = None
26
- if FileOp.dir_exists(self.working_tree_dir):
27
- self.repo = Repo(working_tree_dir)
28
-
29
- def clone_repo(self, repo_url, branch="main", fresh_clone=True, commit_depth=1):
30
- try:
31
- t = T()
32
- if fresh_clone:
33
- # for fresh clone, we must clean the directory and clone again
34
- if FileOp.dir_exists(self.working_tree_dir):
35
- print(f"{self.working_tree_dir} already exists, deleting for a fresh clone!")
36
- FileOp.remove_dir(self.working_tree_dir)
37
- if commit_depth == 0:
38
- P.green(f"git clone -b {branch} {repo_url}")
39
- self.repo = git.Repo.clone_from(repo_url, self.working_tree_dir, branch=branch)
40
- else:
41
- P.green(f"git clone -b {branch} --depth={commit_depth} {repo_url}")
42
- self.repo = git.Repo.clone_from(repo_url, self.working_tree_dir, branch=branch, depth=commit_depth)
43
-
44
- else:
45
- # if it is not a fresh clone, we only clone when directory doesn't exist
46
- if not FileOp.dir_exists(self.working_tree_dir):
47
- print(f"{self.working_tree_dir} doesn't exists, fresh clone is enforced!")
48
- P.yellow(f"git clone -b {branch} --depth={commit_depth} {repo_url}")
49
- self.repo = git.Repo.clone_from(repo_url, self.working_tree_dir, branch=branch, depth=commit_depth)
50
- t.taken(f"Time taken to clone -b {branch} {repo_url}")
51
- self.update_repo_name(repo_url)
52
- assert self.repo.__class__ is Repo # clone an existing repository
53
- assert Repo.init(self.working_tree_dir).__class__ is Repo
54
- return True
55
- except Exception as e:
56
- print("Exception caught while cloning the repo: " + str(e))
57
- return False
58
-
59
- # this will return commits 21-30 from the commit list as traversed backwards master
60
- # ten_commits_past_twenty = list(repo.iter_commits('master', max_count=10, skip=20))
61
- # assert len(ten_commits_past_twenty) == 10
62
- # assert fifty_first_commits[20:30] == ten_commits_past_twenty
63
- # repo = git.Repo.clone_from(repo_url, working_tree_dir, branch='master')
64
- def get_latest_commit_date(self, branch=None, filter_key=None):
65
- tz_london = pytz.timezone('Europe/London')
66
- try:
67
- if branch is not None:
68
- commits = list(self.repo.iter_commits(branch, max_count=50))
69
- else:
70
- commits = list(self.repo.iter_commits('master', max_count=50))
71
- except git.exc.GitCommandError:
72
- if branch == "master":
73
- branch = "main"
74
- commits = list(self.repo.iter_commits(branch, max_count=50))
75
-
76
- for commit in commits:
77
- commit: Commit
78
- # if filter_key = 10, it will look for commits that starts with 10
79
- # failing will continue looking for latest available commit that starts with 10
80
- if filter_key is not None and not str(commit.message).startswith(filter_key + ":"):
81
- continue
82
- time_in_string = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(commit.committed_date)))
83
- time_in_object = datetime.strptime(time_in_string, '%Y-%m-%d %H:%M:%S')
84
- london_time_in_object = time_in_object.astimezone(tz_london)
85
- london_time_in_string = london_time_in_object.strftime('%Y-%m-%d %H:%M:%S')
86
- commit_datetime = datetime.strptime(london_time_in_string, '%Y-%m-%d %H:%M:%S')
87
- return commit_datetime
88
- return None
89
-
90
- def update_repo_name(self, git_url):
91
- git_pattern = re.compile(r'git@[^:]+:[^/]+/(.+)\.git')
92
- https_pattern = re.compile(r'https?://[^/]+/[^/]+/(.+)\.git')
93
- match = git_pattern.match(git_url) or https_pattern.match(git_url)
94
- if match:
95
- self.repo_name = match.group(1)
96
- else:
97
- raise ValueError("Invalid Git URL")
98
-
99
- def get_file_commit_date(self, file_path, str_format="%y%m%d%H%M", skip_containing=None):
100
- commits_touching_path = list(self.repo.iter_commits(paths=file_path))
101
- if commits_touching_path:
102
- for commit in commits_touching_path:
103
- if skip_containing is not None and str(skip_containing).lower() in commit.message.lower():
104
- P.blue(f"Skipping commit ({commit.hexsha[:7]}): "
105
- f"{commit.message} as it contains '{skip_containing}'")
106
- continue
107
- P.green(f"Commit ({commit.hexsha[:7]}): {commit.message} found for {file_path}")
108
- return commit.committed_datetime.strftime(str_format)
109
- else:
110
- return None
111
-
112
- def get_changed_files(self):
113
- files_list = []
114
- files = self.repo.git.diff(None, name_only=True)
115
- if files != "":
116
- for f in files.split('\n'):
117
- files_list.append(f)
118
- if self.repo.untracked_files.__len__() > 0:
119
- for f in self.repo.untracked_files:
120
- files_list.append(f)
121
- return files_list
122
-
123
- def due_changes(self):
124
- files = self.repo.git.diff(None, name_only=True)
125
- if files != "":
126
- if files.split('\n').__len__() > 0:
127
- return True
128
- if self.repo.untracked_files.__len__() > 0:
129
- return True
130
- return False
131
-
132
- def git_push(self, commit_message, push_untracked_files=False, debug=False, rebase=False, pull_first=False,
133
- post_buffer=None):
134
- if not self.enable_push:
135
- print("Git push is disabled, skipping push!")
136
- return False
137
- try:
138
- origin = self.repo.remote(name='origin')
139
- if post_buffer is not None:
140
- self.repo.git.config('http.postBuffer', post_buffer)
141
- if self.repo.is_dirty(untracked_files=True):
142
- self.repo.git.add(u=True)
143
- if push_untracked_files:
144
- self.repo.git.add(A=True)
145
- if commit_message is None:
146
- commit_message = "Auto Commit"
147
- self.repo.index.commit(commit_message)
148
- if pull_first:
149
- origin.fetch(self.repo.active_branch.name)
150
- origin.pull(self.repo.active_branch.name)
151
- if rebase:
152
- origin.fetch(self.repo.active_branch.name)
153
- try:
154
- self.repo.git.pull('--rebase')
155
- except git.GitCommandError as e:
156
- print(f"Error during rebase: {e}")
157
- return False
158
- if debug:
159
- remotes = self.repo.remotes
160
- for remote in remotes:
161
- print(f"Remote name: {remote.name}")
162
- for url in remote.urls:
163
- print(f"URL: {url}")
164
- P.blue(self.repo.git.status())
165
- push_info = origin.push(self.repo.active_branch.name)
166
- for info in push_info:
167
- if info.flags & (git.PushInfo.REMOTE_REJECTED | git.PushInfo.ERROR):
168
- print(f"Push failed for ref {info.local_ref}: {info.summary}")
169
- if info.summary.__contains__("remote rejected") and info.summary.__contains__(
170
- "is at") and info.summary.__contains__("but expected"):
171
- print("Remote rejected, trying to pull!")
172
- origin.fetch(self.repo.active_branch.name)
173
- origin.pull(self.repo.active_branch.name)
174
- # rebase if this fails.
175
- push_info = origin.push(self.repo.active_branch.name)
176
- for nested_info in push_info:
177
- if nested_info.flags & (git.PushInfo.REMOTE_REJECTED | git.PushInfo.ERROR):
178
- print(f"Push failed for ref {nested_info.local_ref}: {nested_info.summary}")
179
- return False
180
- return False
181
-
182
- print("Pushed to origin:", commit_message)
183
- return True
184
-
185
- except git.exc.GitCommandError as e:
186
- if "failed to push some refs" in e.stderr: # Check for the specific error
187
- self.repo.git.pull("origin", "main") # Pull changes from remote
188
- self.repo.git.push() # Retry the push
189
- else:
190
- print(f"Git error: {e}")
191
- raise e
192
-
193
- except Exception as e:
194
- print(f"Unexpected error: {e}")
195
- return False
196
-
197
- def update_changelog(self):
198
- source_file = Assets.changelog
199
- dest_file = GitStatics.website_repo_dir + os.path.sep + "_data" + os.path.sep + "changelogs.yaml"
200
- copyfile(source_file, dest_file)
201
- if self.due_changes():
202
- print("Updating the changelog to the website")
203
- self.git_push("Update Changelog")
204
- else:
205
- print("There is no changelog to update!")
206
-
207
- def update_config_changes(self, message):
208
- if self.due_changes():
209
- print(message)
210
- self.git_push(message, push_untracked_files=True)
211
- else:
212
- print("There is nothing to update!")
213
-
214
- def update_repo_changes(self, message):
215
- if self.due_changes():
216
- P.green(message)
217
- self.git_push(message, push_untracked_files=True)
218
- else:
219
- P.red("There is nothing to update!")
220
-
221
- def get_status(self, path):
222
- changed = [item.a_path for item in self.repo.index.diff(None)]
223
- if path in self.repo.untracked_files:
224
- return 'untracked'
225
- elif path in changed:
226
- return 'modified'
227
- else:
228
- return 'don''t care'
@@ -1,118 +0,0 @@
1
- import json
2
- from ..FileOp import FileOp
3
- from .Git import Git
4
- from .GitStatics import GitStatics
5
- from ..Statics import Statics
6
-
7
-
8
- class GitOperations:
9
-
10
- @staticmethod
11
- def setup_tracker_repo(fresh_clone=True):
12
- return GitOperations.setup_repo(GitStatics.tracker_repo_dir, GitStatics.tracker_repo_url, "main", fresh_clone)
13
-
14
- @staticmethod
15
- def setup_repo(repo_dir, repo_url, branch="main", fresh_clone=True, commit_depth=50):
16
- print()
17
- print("Repo Dir: " + repo_dir)
18
- repo = Git(repo_dir)
19
- result = repo.clone_repo(repo_url, branch=branch, fresh_clone=fresh_clone, commit_depth=commit_depth)
20
- return repo if result else None
21
-
22
- @staticmethod
23
- def clone_overlay_repo(android_version, fresh_clone=False, branch="main", source=False, enable_push=False):
24
- if float(android_version) > 12:
25
- overlay_source_dir = (Statics.pwd + Statics.dir_sep + f"overlays_{android_version}"
26
- + ("_source" if source else ""))
27
- overlay_source_repo = (("git@gitlab.com:nikgapps/" if enable_push else "https://gitlab.com/nikgapps/")
28
- + f"overlays_{android_version}"
29
- + ("_source" if source else "") + ".git")
30
- return GitOperations.setup_repo(overlay_source_dir, overlay_source_repo, branch, fresh_clone)
31
- else:
32
- print(f"Cloning Overlay repo not needed for android {android_version}")
33
- return None
34
-
35
- @staticmethod
36
- def clone_apk_repo(android_version, arch="arm64", fresh_clone=False, branch="main",
37
- cached=False, use_ssh_clone=False):
38
- arch = "" if arch == "arm64" else "_" + arch
39
- cache = "_cached" if cached else ""
40
- apk_source_directory = Statics.pwd + Statics.dir_sep + str(android_version) + arch + cache
41
- apk_source_repo = (GitStatics.apk_source_repo_ssh if use_ssh_clone else GitStatics.apk_source_repo) + str(
42
- android_version) + arch + cache + ".git"
43
- return GitOperations.setup_repo(apk_source_directory, apk_source_repo, branch, fresh_clone, commit_depth=1)
44
-
45
- # Following method is new method of cloning the apk source from Gitlab - based on release type
46
- @staticmethod
47
- def clone_apk_source(android_version, arch="arm64", release_type="stable", fresh_clone=False, cached=False,
48
- use_ssh_clone=False):
49
- url = f"{android_version}{('_' + arch if arch != 'arm64' else '')}_{release_type}"
50
- url = url + ("_cached" if cached else "")
51
- return GitOperations.clone_apk_url(url, fresh_clone, use_ssh_clone)
52
-
53
- @staticmethod
54
- def clone_apk_url(url, fresh_clone=False, use_ssh_clone=False):
55
- apk_source_directory = Statics.pwd + Statics.dir_sep + url
56
- apk_source_repo = ((GitStatics.apk_source_repo_ssh if use_ssh_clone else GitStatics.apk_source_repo) + url
57
- + ".git")
58
- return GitOperations.setup_repo(apk_source_directory, apk_source_repo, branch="main", fresh_clone=fresh_clone,
59
- commit_depth=1)
60
-
61
- @staticmethod
62
- def get_last_commit_date(branch, repo_dir=Statics.cwd, repo_url=None, android_version=None, use_ssh_clone=False):
63
- last_commit_datetime = None
64
- if android_version is not None:
65
- repository = GitOperations.clone_apk_repo(android_version, branch=branch, use_ssh_clone=use_ssh_clone)
66
- else:
67
- repository = Git(repo_dir)
68
- if repo_url is not None:
69
- repository.clone_repo(repo_url=repo_url, fresh_clone=False, branch=branch)
70
- if repository is not None:
71
- last_commit_datetime = repository.get_latest_commit_date(branch=branch)
72
- return last_commit_datetime
73
-
74
- @staticmethod
75
- def get_release_repo(release_type):
76
- release_repo = Git(GitStatics.release_history_dir)
77
- if not FileOp.dir_exists(GitStatics.release_history_dir):
78
- if release_type == "canary":
79
- GitStatics.release_repo_url = "git@github.com:nikgapps/canary-release.git"
80
- release_repo.clone_repo(GitStatics.release_repo_url, branch="master", commit_depth=50)
81
- if not FileOp.dir_exists(GitStatics.release_history_dir):
82
- print(GitStatics.release_history_dir + " doesn't exist!")
83
- return release_repo
84
-
85
- @staticmethod
86
- def get_website_repo_for_changelog(repo_dir=GitStatics.website_repo_dir, repo_url=GitStatics.website_repo_url,
87
- branch="main"):
88
- repo = Git(repo_dir)
89
- if repo_url is not None:
90
- repo.clone_repo(repo_url=repo_url, fresh_clone=False, branch=branch)
91
- if not FileOp.dir_exists(GitStatics.website_repo_dir):
92
- print(f"Repo {repo_dir} doesn't exist!")
93
- return repo
94
-
95
- @staticmethod
96
- def mark_a_release(android_version, release_type):
97
- tracker_repo = GitOperations.setup_tracker_repo(False)
98
- if tracker_repo is not None:
99
- release_tracker = tracker_repo.working_tree_dir + Statics.dir_sep + "release_tracker.json"
100
- decoded_hand = {}
101
- if FileOp.file_exists(release_tracker):
102
- with open(release_tracker, "r") as file:
103
- decoded_hand = json.load(file)
104
- if release_type not in decoded_hand:
105
- decoded_hand[release_type] = {}
106
- decoded_hand[release_type][android_version] = Statics.time
107
- else:
108
- decoded_hand[release_type] = {}
109
- decoded_hand[release_type][android_version] = Statics.time
110
- print(f"Marking a release with {decoded_hand}")
111
- with open(release_tracker, "w") as file:
112
- json.dump(decoded_hand, file, indent=2, sort_keys=True)
113
- if tracker_repo.due_changes():
114
- tracker_repo.git_push(
115
- f"Updated release_tracker.json with latest {release_type} release date: " + Statics.time,
116
- pull_first=True)
117
- else:
118
- print("No changes to commit!")
@@ -1,14 +0,0 @@
1
- from ..Statics import Statics
2
-
3
-
4
- class GitStatics:
5
- tracker_repo_url = "git@github.com:nikgapps/tracker.git"
6
- tracker_repo_dir = Statics.pwd + Statics.dir_sep + "tracker"
7
- apk_source_repo_ssh = f"git@gitlab.com:nikgapps/"
8
- apk_source_repo = f"https://gitlab.com/nikgapps/"
9
- release_repo_url = "git@github.com:nikgapps/release.git"
10
- release_history_dir = Statics.pwd + Statics.dir_sep + "release"
11
- website_repo_url = "git@github.com:nikgapps/nikgapps.github.io.git"
12
- website_repo_dir = Statics.pwd + Statics.dir_sep + "nikgapps.github.io"
13
- config_repo_dir = Statics.pwd + Statics.dir_sep + "config"
14
- config_repo_url = "git@github.com:nikgapps/config.git"
@@ -1,21 +0,0 @@
1
- from github import Github
2
-
3
-
4
- class GithubManager:
5
-
6
- def __init__(self, token):
7
- self.g = Github(token)
8
- self.user = self.g.get_user()
9
-
10
- def get_user(self):
11
- return self.g.get_user()
12
-
13
- def get_repos(self):
14
- return self.user.get_repos()
15
-
16
- def create_repo(self, repo_name):
17
- return self.user.create_repo(repo_name)
18
-
19
- @staticmethod
20
- def create_issue(repo, issue_title, issue_body):
21
- return repo.create_issue(title=issue_title, body=issue_body)
@@ -1,265 +0,0 @@
1
- import math
2
- import shutil
3
- import time
4
- from pathlib import Path
5
-
6
- import gitlab
7
-
8
- from NikGapps.helper.FileOp import FileOp
9
- from NikGapps.helper.P import P
10
- from NikGapps.helper.Statics import Statics
11
- from NikGapps.helper.git.GitOperations import GitOperations
12
-
13
-
14
- class GitLabManager:
15
- def __init__(self, gitlab_url='https://gitlab.com', private_token=None):
16
- self.token = private_token
17
- self.gl = gitlab.Gitlab(gitlab_url, private_token=private_token)
18
- self.gl.auth()
19
-
20
- def fetch_user_details(self, user_id):
21
- """Fetches user details for a specified user ID."""
22
- user = self.gl.users.get(user_id)
23
- return user
24
-
25
- def create_repository(self, project_name, provide_owner_access=False, user_id=8064473, visibility='public'):
26
- """Creates a new repository with the given project name."""
27
- project = self.gl.projects.create({'name': project_name, 'visibility': visibility})
28
- if provide_owner_access:
29
- self.provide_owner_access(project_id=project.id, user_id=user_id)
30
- self.create_and_commit_readme(project_id=project.id)
31
- return project
32
-
33
- def create_lfs_repository(self, project_name, provide_owner_access=False, user_id=8064473, visibility='public',
34
- extn_list=None):
35
- """Creates a new repository with the given project name and attributes."""
36
- if extn_list is None:
37
- extn_list = []
38
- project = self.gl.projects.create({'name': project_name, 'visibility': visibility})
39
- if provide_owner_access:
40
- self.provide_owner_access(project_id=project.id, user_id=user_id)
41
- self.create_and_commit_readme(project_id=project.id)
42
- gitattributes = ""
43
- for extn in extn_list:
44
- gitattributes += f"*.{extn} filter=lfs diff=lfs merge=lfs -text\n"
45
- self.create_and_commit_file(project_id=project.id, file_path=".gitattributes", content=gitattributes)
46
- return project
47
-
48
- def provide_owner_access(self, project_id, user_id):
49
- """Provides owner access to a repository for a particular user."""
50
- project = self.gl.projects.get(project_id)
51
- member = project.members.create({
52
- 'user_id': user_id,
53
- 'access_level': 50
54
- })
55
- P.green(f"Owner access provided to user with ID {user_id}.")
56
- return member
57
-
58
- def get_project(self, project_name):
59
- # Fetch all projects for the current user
60
- projects = self.gl.projects.list(owned=True, all=True)
61
-
62
- # Print details of each project
63
- for project in projects:
64
- if project.path == project_name:
65
- return project
66
- return None
67
-
68
- def create_and_commit_readme(self, project_id, branch_name="main", content="# Welcome to your new project"):
69
- """Creates a README.md file and commits it to the specified repository."""
70
- project = self.gl.projects.get(project_id)
71
- commit_data = {
72
- 'branch': branch_name,
73
- 'commit_message': 'Add README.md',
74
- 'actions': [
75
- {
76
- 'action': 'create',
77
- 'file_path': 'README.md',
78
- 'content': content
79
- }
80
- ]
81
- }
82
- commit = project.commits.create(commit_data)
83
- P.green(f"README.md created and committed to the repository {project.name}.")
84
- # print(commit)
85
- return commit
86
-
87
- def create_and_commit_file(self, project_id, branch_name="main", file_path="file.txt", content=""):
88
- """Creates a file and commits it to the specified repository."""
89
- project = self.gl.projects.get(project_id)
90
- commit_data = {
91
- 'branch': branch_name,
92
- 'commit_message': f'Add {file_path}',
93
- 'actions': [
94
- {
95
- 'action': 'create',
96
- 'file_path': file_path,
97
- 'content': content
98
- }
99
- ]
100
- }
101
- commit = project.commits.create(commit_data)
102
- P.green(f"{file_path} created and committed to the repository {project.name}.")
103
- # print(commit)
104
- return commit
105
-
106
- def create_gitlab_repository(self, project_name, visibility='public'):
107
- try:
108
- project = self.gl.projects.create({'name': project_name, 'visibility': visibility})
109
- return project.web_url
110
- except Exception as e:
111
- raise Exception(f"Failed to create GitLab repository: {e}")
112
-
113
- def get_repository_users_with_access_levels(self, project_id):
114
- access_levels = {
115
- 10: 'Guest',
116
- 20: 'Reporter',
117
- 30: 'Developer',
118
- 40: 'Maintainer',
119
- 50: 'Owner'
120
- }
121
-
122
- project = self.gl.projects.get(project_id)
123
- members = project.members.list(all=True)
124
- user_access_levels = [(member.username, member.access_level, access_levels.get(member.access_level, 'Unknown'))
125
- for member in
126
- members]
127
-
128
- return user_access_levels
129
-
130
- def list_projects_with_ids(self, print_details=False):
131
- namespace_name = "nikgapps"
132
- # Fetch all projects for the current user
133
- projects = self.gl.projects.list(owned=True, all=True)
134
-
135
- # Print details of each project
136
- for project in projects:
137
- if not print_details:
138
- return projects
139
- project_details = self.gl.projects.get(project.id, statistics=True)
140
- storage_size = math.ceil(project_details.statistics["storage_size"] / (1024 ** 2) * 100) / 100
141
- print(f'Project Name: {project.name}, Project ID: {project.id}, Namespace: {project.namespace["path"]}, '
142
- f'Storage Size: {storage_size} MB')
143
- return projects
144
-
145
- def find_project_allocated_size(self, repo_name):
146
- project = self.get_project(repo_name)
147
- project_details = self.gl.projects.get(project.id, statistics=True)
148
- return math.ceil(project_details.statistics["storage_size"] / (1024 ** 2) * 100) / 100
149
-
150
- def delete_project(self, project_id):
151
- try:
152
- project = self.gl.projects.get(project_id)
153
- project_name = project.name
154
- project_path = project.path
155
- project.delete()
156
- print(f"Project with id {project_id}, name {project_name} and path {project_path} deleted successfully.")
157
- except Exception as e:
158
- print(f"Failed to delete project {project_id}: {e}")
159
-
160
- def rename_repository(self, repo_name, new_repo_name=None):
161
- project = self.get_project(repo_name)
162
- if new_repo_name is None:
163
- new_repo_name = f"{repo_name}_{time.strftime('%Y%m%d')}"
164
- new_project = self.get_project(new_repo_name)
165
- if new_project is not None:
166
- P.red(f"Project {new_repo_name} already exists. Deleting...")
167
- self.delete_project(new_project.id)
168
- project.name = new_repo_name
169
- project.path = new_repo_name
170
- P.yellow(f"Repository {repo_name} renaming to {new_repo_name}.")
171
- project.save()
172
- P.green(f"Repository {repo_name} renamed to {new_repo_name}.")
173
- return project
174
-
175
- def reset_repository(self, repo_name, gitattributes=None, user_id=8064473, sleep_for=10, delete_only=False):
176
- try:
177
- print(f"Resetting repository {repo_name}...")
178
- project = self.get_project(repo_name)
179
- self.delete_project(project.id)
180
- if not delete_only:
181
- P.red(f"Waiting for {sleep_for} seconds for the project to be completely deleted...")
182
- time.sleep(sleep_for)
183
- project = self.create_repository(repo_name, provide_owner_access=True, user_id=user_id)
184
- if gitattributes is not None:
185
- commit = self.create_and_commit_file(project_id=project.id, file_path=".gitattributes",
186
- content=gitattributes)
187
- # print(commit)
188
- return project
189
- except Exception as e:
190
- print(f"Failed to reset repository: {e}")
191
- return None
192
-
193
- def reset_repository_storage(self, repo_name, user_id=8064473, sleep_for=10, storage_cap=7500, gitattributes=None,
194
- method="rename"):
195
- old_project = self.get_project(repo_name)
196
- project_details = self.gl.projects.get(old_project.id, statistics=True)
197
- storage_size = math.ceil(project_details.statistics["storage_size"] / (1024 ** 2) * 100) / 100
198
- if storage_size > storage_cap:
199
- print(f"Storage size of {storage_size} MB exceeds the limit of {storage_cap} MB "
200
- f"for project id {old_project.id}. Resetting...")
201
- old_repo_dir = Statics.pwd + Statics.dir_sep + f"{repo_name}_old"
202
- old_repo = GitOperations.setup_repo(repo_dir=f"{old_repo_dir}", repo_url=project_details.ssh_url_to_repo)
203
- match method.lower():
204
- case "rename":
205
- old_project = self.rename_repository(repo_name)
206
- new_project = self.create_repository(repo_name, provide_owner_access=True, user_id=user_id)
207
- case _:
208
- new_project = self.reset_repository(repo_name, user_id=user_id, sleep_for=sleep_for,
209
- gitattributes=gitattributes)
210
- new_repo_dir = Statics.pwd + Statics.dir_sep + f"{repo_name}_new"
211
- new_repo = GitOperations.setup_repo(repo_dir=f"{new_repo_dir}", repo_url=project_details.ssh_url_to_repo)
212
- for item in Path(old_repo.working_tree_dir).rglob('*'):
213
- if '.git' in item.parts:
214
- continue
215
- destination = Path(new_repo.working_tree_dir) / item.relative_to(Path(old_repo.working_tree_dir))
216
- if item.is_dir():
217
- destination.mkdir(parents=True, exist_ok=True)
218
- else:
219
- destination.parent.mkdir(parents=True, exist_ok=True)
220
- print(f"Copying {item} to {destination}")
221
- shutil.copy2(item, destination)
222
- new_repo.git_push("Initial Commit", push_untracked_files=True)
223
- project_details = self.gl.projects.get(new_project.id, statistics=True)
224
- storage_size = math.ceil(project_details.statistics["storage_size"] / (1024 ** 2) * 100) / 100
225
- print(f"Repository storage for project id {new_project.id} reset successfully. "
226
- f"New storage size: {storage_size} MB")
227
- FileOp.remove_dir(old_repo.working_tree_dir)
228
- FileOp.remove_dir(new_repo.working_tree_dir)
229
- match method.lower():
230
- case "rename":
231
- self.delete_project(old_project.id)
232
- else:
233
- print(f"Storage size of {storage_size} MB is within the limit of {storage_cap} MB. No action required.")
234
-
235
- def copy_repository(self, source_repo_name, target_repo_name, user_id=8064473, override_target=False):
236
- project = self.get_project(source_repo_name)
237
- if project is None:
238
- print(f"Project {source_repo_name} does not exist. Exiting...")
239
- return
240
- old_repo_dir = Statics.pwd + Statics.dir_sep + f"{source_repo_name}_old"
241
- old_repo = GitOperations.setup_repo(repo_dir=f"{old_repo_dir}", repo_url=project.ssh_url_to_repo)
242
- if override_target:
243
- target_project = self.get_project(target_repo_name)
244
- if target_project is not None:
245
- P.red(f"Project {target_repo_name} already exists. Deleting...")
246
- self.delete_project(target_project.id)
247
- if self.get_project(target_repo_name) is not None:
248
- print(f"Project {target_repo_name} already exists. Exiting...")
249
- return
250
- project = self.create_repository(target_repo_name, provide_owner_access=True, user_id=user_id)
251
- new_repo_dir = Statics.pwd + Statics.dir_sep + f"{target_repo_name}_new"
252
- new_repo = GitOperations.setup_repo(repo_dir=f"{new_repo_dir}", repo_url=project.ssh_url_to_repo)
253
- for item in Path(old_repo.working_tree_dir).rglob('*'):
254
- if '.git' in item.parts:
255
- continue
256
- destination = Path(new_repo.working_tree_dir) / item.relative_to(Path(old_repo.working_tree_dir))
257
- if item.is_dir():
258
- destination.mkdir(parents=True, exist_ok=True)
259
- else:
260
- destination.parent.mkdir(parents=True, exist_ok=True)
261
- print(f"Copying {item} to {destination}")
262
- shutil.copy2(item, destination)
263
- new_repo.git_push("Initial Commit", push_untracked_files=True)
264
- FileOp.remove_dir(old_repo.working_tree_dir)
265
- FileOp.remove_dir(new_repo.working_tree_dir)