made it into a package

parent 7cf1f479
from gitlab_class_helper.gitlab_class_helper import GitlabClassHelper
import os
import requests
import git
import simplejson
from typing import List
class GitlabClassHelper:
def __init__(self, url: str, access_token: str):
self.path = url
self.headers = {'Authorization': 'Bearer {}'.format(access_token)}
self.check_connection()
self.group_id = None
def check_connection(self):
url = self.path + '/projects'
resp = requests.get(url, self.headers)
if resp.status_code == 401:
raise requests.HTTPError('Personal access token is invalid. %s' % resp.text)
elif resp.ok:
try:
resp.json()
print('Initialized connection to gitlab instance.')
print('Personal access token works.')
except simplejson.errors.JSONDecodeError:
raise requests.HTTPError('Bad request. Possible the url is wrong.')
else:
raise requests.HTTPError('Bad request. %s' % resp.text)
def create_class(self, group_name: str, id_of_parent_group: int) -> int:
"""
Create a new group with group_name as a subgroup of that parent with id id_of_parent_group
returns the new groups id
"""
group_path = ''.join(e if e.isalnum() else '-' for e in group_name)
url = self.path + '/groups?name=%s&path=%s&parent_id=%d&visibility=private' % (group_name, group_path, id_of_parent_group)
resp = requests.post(url, headers=self.headers)
if resp.ok:
idx = resp.json()['id']
self.group_id = idx
web_url = resp.json()['web_url']
print('Created the "%s" group in gitlab.' % group_name)
print('web_url to the group: %s' % web_url)
print('Id of the group: %d' % idx)
print('Working in this group now.')
return idx
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def create_assignment_repositories(self, repositories: List[str], group_id: int = None):
"""
Create repositories in working group or in the group with group_id if supplied.
"""
use_group_id, group_name = self.check_group_id(group_id)
for repo in set(repositories):
self.create_repo(repo, use_group_id, group_name)
def create_repo(self, repo_name: str, group_id: int, group_name: str):
"""
Create a repository in the group with id
"""
url = '/projects?name=%s&namespace_id=%d' % (repo_name, group_id)
resp = requests.post(url, headers=self.headers)
if resp.ok:
print('Created project "%s" in "%s".' % (repo_name, group_name))
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def get_group_name(self, group_id: int) -> str:
"""
Get the name of a group with id.
"""
url = self.path + '/groups/%d' % group_id
resp = requests.get(url, headers=self.headers)
if resp.ok:
return resp.json()['name']
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def add_students_to_repositories(self, repositories: List[str], user_ids: List[int], group_id: int = None):
"""
Give developer access rights to user in repository.
"""
use_group_id, _ = self.check_group_id(group_id)
for repo, user_id in zip(repositories, user_ids):
repo_id = self.get_repo_id(repo, use_group_id)
self.add_user_to_repo(repo_id, user_id, repo)
def check_group_id(self, group_id):
if not group_id and not self.group_id:
raise AttributeError('group_id must be supplied if not working in a group')
use_group_id = group_id if group_id else self.group_id
group_name = self.get_group_name(use_group_id)
print('Working in group: %d - %s' % (use_group_id, group_name))
return use_group_id, group_name
def get_repo_id(self, repo_name: str, group_id: int) -> int:
"""
Get repository id from name
"""
url = self.path + '/groups/%d/projects?search=%s' % (group_id, repo_name)
resp = requests.get(url, headers=self.headers)
if resp.ok:
if len(resp.json()) == 1:
return resp.json()[0]['id']
else:
raise NameError('%d projects found in group: %d when searching on %s' % (len(resp.json()), group_id, repo_name))
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def add_user_to_repo(self, repo_id: int, user_id: int, repo_name: str):
"""
Add user to given repository
"""
url = '/projects/%d/members?user_id=%d&access_level=30' % (repo_id, user_id)
resp = requests.post(url, headers=self.headers)
if resp.ok:
print('Added "%d" to the project "%s".' % (user_id, repo_name))
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def push_git_repo_to_repositories(self, local_path: str, repositories: List[str], group_id: int = None):
"""
Push local repository to list of remote repositories
"""
use_group_id, _ = self.check_group_id(group_id)
for repo in repositories:
repo_id = self.get_repo_id(repo, use_group_id)
self.push_git_repository_content_to_project(local_path, repo_id)
print('Pushed git repo "%s" to "%s"' % (local_path, repo))
def push_git_repository_content_to_project(self, path_to_git_repository: str, project_id: int):
"""
Push the local git repository located at "path_to_git_repository" to the project.
"""
repo = git.Repo(path_to_git_repository)
ssh_url_to_git_repo = self.get_project_ssh_url(project_id)
repo.git.push(ssh_url_to_git_repo, 'master')
def get_project_ssh_url(self, project_id: int) -> str:
"""
Fetch project ssh url
"""
url = self.path + "/projects/%d" % project_id
resp = requests.get(url, headers=self.headers)
if resp.ok:
return resp.json()['ssh_url_to_repo']
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def enter_class(self, group_name: str, id_of_parent_group: int) -> int:
"""
Entering group_name as a subgroup of that parent as the new working group
returns the new groups id
"""
url = self.path + '/groups/%d/subgroups?search=%s' % (id_of_parent_group, group_name)
resp = requests.get(url, headers=self.headers)
if resp.ok:
if len(resp.json()) == 1:
idx = resp.json()[0]['id']
self.group_id = idx
web_url = resp.json()['web_url']
print('Entering the "%s" group in gitlab.' % group_name)
print('web_url to the group: %s' % web_url)
print('Id of the group: %d' % idx)
print('Working in this group now.')
return idx
else:
raise NameError('%d groups found in group: %d when searching on %s' % (len(resp.json()), id_of_parent_group, group_name))
else:
raise requests.HTTPError('%s for url: %s' % (resp.json()['message'], url))
def clone_repositories(self, repositories: List[str], local_path_to_fetch_to: str, group_id: int = None):
"""
Clone all repositories in "repositories" to the local path "local_path_to_fetch_to"
"""
use_group_id, _ = self.check_group_id(group_id)
for repo in repositories:
repo_id = self.get_repo_id(repo, use_group_id)
self.clone_repo(local_path_to_fetch_to, repo_id)
print('Cloned the repository "%s" to "%s"' % (repo, local_path_to_fetch_to))
def clone_repo(self, local_folder: str, project_id: int):
"""
Clone the project into the local folder
"""
ssh_url_to_git_repo = self.get_project_ssh_url(project_id)
git.Repo.clone_from(ssh_url_to_git_repo, local_folder)
def push_repositories(self, repositories: List[str], local_path: str, group_id: int = None):
"""
Push repositories to remotes.
"""
use_group_id, _ = self.check_group_id(group_id)
for repo in repositories:
repo_id = self.get_repo_id(repo, use_group_id)
path_to_repo = os.path.join(local_path, repo)
self.push_git_repository_content_to_project(path_to_repo, repo_id)
print('Pushed the repository "%s" to "%s"' % (path_to_repo, repo))
......@@ -12,31 +12,31 @@ $ python
Python 3.x.x ...
>>> import config
>>> import pandas as pd
>>> from gitlab_class_helper import *
>>> start_gitlab_class_helper("source.coderefinery.org", config.public_access_token)
>>> from gitlab_class_helper import GitlabClassHelper
>>> class_helper = GitlabClassHelper("source.coderefinery.org", config.public_access_token)
Initialized connection to gitlab instance.
Personal access token works.
>>> create_gitlab_class(
>>> class_helper.create_class(
group_name = "test-rmurv2",
id_of_parent_group = x)
Created the "test-rmurv2" group in gitlab.
Full path to the group: xxxxxxxxxx.
Id of the group: 123.
>>> list_of_repo_names = pd.read_csv("assignment1.csv")
>>> create_assignment_repositories(
>>> class_helper.create_assignment_repositories(
repositories = list_of_repo_names['repository'],
group_id = 123)
Working in group: 123 - "test-rmurv2".
Created project "hw1-adam" in "test-rmurv2".
Created project "hw1-birger" in "test-rmurv2".
>>> add_students_to_repositories(
>>> class_helper.add_students_to_repositories(
repositories = list_of_repo_names['repository'],
user_ids = list_of_repo_names['userid'],
group_id = 123)
Working in group: 123 - "test-rmurv2".
Added "adam_id" to the project "hw1-adam".
Added "birger_id" to the project "hw1-birger".
>>> push_git_repo_to_repositories(
>>> class_helper.push_git_repo_to_repositories(
local_path = "hw1",
repositories = list_of_repo_names['repository'],
group = 123)
......@@ -51,25 +51,25 @@ $ python
Python 3.x.x ...
>>> import config
>>> import pandas as pd
>>> from gitlab_class_helper import *
>>> start_gitlab_class_helper("source.coderefinery.org", config.public_access_token)
>>> from gitlab_class_helper import GitlabClassHelper
>>> class_helper = GitlabClassHelper("source.coderefinery.org", config.public_access_token)
Initialized connection to gitlab instance.
Personal access token works.
>>> enter_gitlab_class(
>>> class_helper.enter_gitlab_class(
group_name = "test-rmurv2",
id_of_parent_group = x)
Entered the "test-rmurv2" group in gitlab.
Full path to the group: xxxxxxxxxx.
Id of the group: 123.
>>> list_of_repo_names = pd.read_csv("assignment1.csv")
>>> clone_repositories(
>>> class_helper.clone_repositories(
repositories = list_of_repo_names['repositories'],
local_path_to_fetch_to = "assignment1/studentresponses/")
Working in group: 123 - "test-rmurv2".
Cloned the repository "hw1-adam" to "assignment1/studentresponses/hw1-adam".
Cloned the repository "hw1-birger" to "assignment1/studentresponses/hw1-birger".
>>> # Grade assignments / provide feedback.
>>> push_repositories(
>>> class_helper.push_repositories(
repositories = list_of_repo_names['repositories'],
local_path_to_fetch_to = "assignment1/studentresponses/")
Working in group: 123 - "test-rmurv2".
......@@ -89,30 +89,30 @@ $ python
Python 3.x.x ...
>>> import config
>>> import pandas as pd
>>> from gitlab_class_helper import *
>>> start_gitlab_class_helper("source.coderefinery.org", config.public_access_token)
>>> from gitlab_class_helper import GitlabClassHelper
>>> class_helper = GitlabClassHelper("source.coderefinery.org", config.public_access_token)
Initialized connection to gitlab instance.
Personal access token works.
>>> enter_gitlab_class(
>>> class_helper.enter_gitlab_class(
group_name = "test-rmurv2",
id_of_parent_group = x)
Entered the "test-rmurv2" group in gitlab.
Full path to the group: xxxxxxxxxx.
Id of the group: 123.
>>> list_of_repo_names = pd.read_csv("assignment2.csv")
>>> create_assignment_repositories(
>>> class_helper.create_assignment_repositories(
repositories = list_of_repo_names['repository'],
group_id = 123)
Working in group: 123 - "test-rmurv2".
Created project "hw2-group" in "test-rmurv2".
>>> add_students_to_repositories(
>>> class_helper.add_students_to_repositories(
repositories = list_of_repo_names['repository'],
user_ids = list_of_repo_names['userid'],
group_id = 123)
Working in group: 123 - "test-rmurv2".
Added "adam_id" to the project "hw2-group".
Added "birger_id" to the project "hw2-group".
>>> push_git_repo_to_repositories(
>>> class_helper.push_git_repo_to_repositories(
local_path = "hw2",
repositories = list_of_repo_names['repository'],
group = 123)
......
from setuptools import setup
setup(name='gitlab_class_helper',
version='0.1',
description='A package to create assignments for students on gitlab',
url='',
author='Henrik Dyrberg Egemose',
author_email='hes1990@gmail.com',
packages=['gitlab_class_helper'],
install_requires=[
'requests',
'gitpython',
'simplejson',
],
zip_safe=False)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment