You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.9 KiB
106 lines
3.9 KiB
# -*- coding: utf-8 -*-
|
|
import gitlab
|
|
|
|
|
|
class GitlabWrapperException(Exception):
|
|
pass
|
|
|
|
|
|
class GitlabWrapperFilesExists(GitlabWrapperException):
|
|
pass
|
|
|
|
|
|
class GitlabWrapper:
|
|
API_VERSION = '4'
|
|
|
|
def __init__(self, url, token, ssl_verify=True):
|
|
self.url = url
|
|
self.token = token
|
|
self.gl = gitlab.Gitlab(
|
|
url=self.url, private_token=self.token, api_version=self.API_VERSION, ssl_verify=ssl_verify)
|
|
|
|
def get_user(self, email):
|
|
exists_users = self.gl.users.list(search=email)
|
|
if exists_users:
|
|
return exists_users[0]
|
|
|
|
def create_user(self, email, name):
|
|
username = email[:email.find('@')].replace('.', '_')
|
|
# TODO can contain only letters, digits, '_', '-' and '.'.
|
|
# TODO Cannot start with '-' or end in '.', '.git' or '.atom'."
|
|
exists_users = self.gl.users.list(username=username)
|
|
if len(exists_users):
|
|
username = username + '_{}'.format(len(exists_users) + 1)
|
|
user_data = dict(
|
|
email=email,
|
|
username=username,
|
|
name=name,
|
|
reset_password=True,
|
|
)
|
|
new_user = self.gl.users.create(user_data)
|
|
return new_user
|
|
|
|
def get_or_create_user(self, email, name):
|
|
user = self.get_user(email)
|
|
if user is None:
|
|
user = self.create_user(email, name)
|
|
return user
|
|
|
|
def get_user_project(self, user, project_name):
|
|
try:
|
|
exists_project = self.gl.projects.get('{}/{}'.format(user.username, project_name))
|
|
return exists_project
|
|
except gitlab.GitlabGetError:
|
|
return None
|
|
|
|
def create_user_project(self, user, project_name):
|
|
user.projects.create(data={'name': project_name})
|
|
# делаем еще запрос, для получения проекта со всеми аттрибутами
|
|
new_project = self.gl.projects.get('{}/{}'.format(user.username, project_name))
|
|
return new_project
|
|
|
|
def get_or_create_user_project(self, user, project_name):
|
|
project = self.get_user_project(user, project_name)
|
|
if project is None:
|
|
project = self.create_user_project(user, project_name)
|
|
return project
|
|
|
|
def make_user_project_master(self, user, project):
|
|
try:
|
|
project.members.create(data=dict(
|
|
user_id=user.id,
|
|
access_level=40,
|
|
))
|
|
except gitlab.GitlabCreateError:
|
|
pass
|
|
|
|
def copy_files_to_repository(self, base_project, files_path, target_project, autor):
|
|
commit_actions = []
|
|
items = base_project.repository_tree(path=files_path, recursive=True)
|
|
for item in items:
|
|
# item = {'name': '__init__.py', 'path': 'module_01/lesson_01/__init__.py', 'type': 'blob',
|
|
# 'id': '633f866158ac742cf754a2c43edcb07e3a094f3c', 'mode': '100644'}
|
|
if item['type'] == 'blob':
|
|
file_sha = item['id']
|
|
file_info = base_project.repository_blob(sha=file_sha)
|
|
# file_info = {'content': 'IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KCg==', 'size': 25,
|
|
# 'sha': '633f866158ac742cf754a2c43edcb07e3a094f3c', 'encoding': 'base64'}
|
|
action = dict(
|
|
action='create',
|
|
file_path=item['path'],
|
|
content=file_info['content'],
|
|
encoding='base64',
|
|
)
|
|
commit_actions.append(action)
|
|
commit_data = {
|
|
'branch': 'master',
|
|
'commit_message': 'Add {}'.format(files_path),
|
|
'actions': commit_actions
|
|
}
|
|
try:
|
|
commit = target_project.commits.create(commit_data, sudo=autor)
|
|
return commit
|
|
except gitlab.GitlabCreateError as exc:
|
|
if exc.response_code == 400:
|
|
raise GitlabWrapperFilesExists()
|
|
raise
|
|
|