Move package into src directory

This commit is contained in:
Tim Schubert 2018-08-20 14:54:41 +02:00
parent 92d44c7928
commit 22707b03c1
4 changed files with 0 additions and 0 deletions

View file

View file

@ -0,0 +1,83 @@
from .students import Student, create_user, get_students
from gitlab.exceptions import GitlabCreateError, GitlabGetError
def create_users(gl, args):
"""Creates Gitlab users from exported students list
"""
with open(args.students, encoding='iso8859') as students_csv:
for student in Student.from_csv(students_csv):
try:
create_user(gl, student, args.ldap_base, args.ldap_provider)
except GitlabCreateError:
log.warn('Failed to create user: %s' % student.user)
def projects(gl, args):
"""Creates the projects for all course participants
"""
groups = gl.groups.list(search=args.course)
if len(groups) == 0 and groups[0].name == args.course:
log.warn('This group does not exist')
else:
group = groups[0]
with open(args.deploy_key, 'r') as key, open(args.students, encoding='iso8859') as students_csv:
key = key.read()
setup_course(gl, group, students_csv, key)
def deadline(gl, args):
"""Checks deadlines for course and triggers deadline if it is reached"""
deadline_name = args.tag_name
try:
reference = gl.projects.get(args.reference, lazy=True)
for fork in reference.forks.list():
project = gl.projects.get(fork.id, lazy=False)
try:
create_tag(project, deadline_name, 'master')
except GitlabCreateError as e:
print(e.error_message)
except GitlabGetError as e:
print(e.error_message)
def plagiates(gl, args):
"""Runs the plagiarism checker (JPlag) for the solutions with a certain tag
"""
tag = args.tag_name
reference = gl.projects.get(args.reference, lazy=True)
try:
os.mkdir('solutions')
except os.FileExistsError as e:
print(e)
os.chdir('solutions')
for fork in reference.forks.list():
project = gl.projects.get(fork.id, lazy=True)
try:
subprocess.run(
['git', 'clone', '--branch', tag, project.ssh_url_to_repo, project.path_with_namespace])
os.chdir('..')
except:
print(e.error_message)
subprocess.run(
['java', '-jar', args.jplag_jar, '-s', 'solutions', '-p', 'java', '-r', 'results', '-bc', args.reference, '-l', 'java17'])
def course(gl, args):
"""Creates the group for the course
"""
try:
group = gl.groups.create({
'name': args.course,
'path': args.course,
'visibility': 'internal',
})
log.info('Created group %s' % args.course)
except GitlabCreateError as e:
log.warning('Failed to create group %s. %s' % (args.course, e.error_message))

View file

@ -0,0 +1,125 @@
from gitlab.exceptions import GitlabError, GitlabCreateError
def create_tag(project, tag, ref):
"""Creates protected tag on ref
The tag is used by the abgabesystem to mark the state of a solution at the
deadline
"""
print('Project %s. Creating tag %s' % (project.path, tag))
project.tags.create({
'tag_name': tag,
'ref': ref
})
def fork_reference(gl, reference, namespace, deploy_key):
"""Create fork of solutions for student.
"""
fork = reference.forks.create({
'namespace': namespace.id
})
project = gl.projects.get(fork.id)
project.visibility = 'private'
project.container_registry_enabled = False
project.lfs_enabled = False
deploy_key = project.keys.create({
'title': "Deploy Key",
'key': deploy_key
})
project.keys.enable(deploy_key.id)
project.save()
return project
def create_project(gl, group, user, reference, deploy_key):
"""Creates a namespace (subgroup) and forks the project with
the reference solutions into that namespace
"""
subgroup = None
try:
subgroup = gl.groups.create({
'name': user.username,
'path': user.username,
'parent_id': group.id
})
except GitlabError as e:
subgroups = group.subgroups.list(search=user.username)
if len(subgroups) > 0 and subgroup[0].name == user.username:
subgroup = subgroups[0]
subgroup = gl.groups.get(subgroup.id, lazy=True)
else:
raise(e)
try:
subgroup.members.create({
'user_id': user.id,
'access_level': gitlab.DEVELOPER_ACCESS,
})
except GitlabError:
log.warning('Failed to add student %s to its own group' % user.username)
try:
fork_reference(gl, reference, subgroup, deploy_key)
except GitlabCreateError as e:
log.warning(e.error_message)
def setup_course(gl, group, students_csv, deploy_key):
"""Sets up the internal structure for the group for use with the course
"""
solution = None
reference_project = None
try:
solution = gl.groups.create({
'name': 'solutions',
'path': 'solutions',
'parent_id': group.id,
'visibility': 'internal',
})
except GitlabCreateError as e:
log.info('Failed to create solutions group. %s' % e.error_message)
solutions = group.subgroups.list(search='solutions')
if len(solutions) > 0 and solutions[0].name == 'solutions':
solution = gl.groups.get(solutions[0].id, lazy=True)
else:
raise(GitlabCreateError(error_message='Failed to setup solutions subgroup'))
try:
reference_project = gl.projects.create({
'name': 'solutions',
'namespace_id': solution.id,
'visibility': 'internal',
})
reference_project.commits.create({
'branch': 'master',
'commit_message': 'Initial commit',
'actions': [
{
'action': 'create',
'file_path': 'README.md',
'content': 'Example solutions go here',
},
]
})
except GitlabCreateError as e:
log.info('Failed to setup group structure. %s' % e.error_message)
projects = solution.projects.list(search='solutions')
if len(projects) > 0 and projects[0].name == 'solutions':
reference_project = gl.projects.get(projects[0].id)
else:
raise(GitlabCreateError(error_message='Failed to setup reference solutions'))
if solution is None or reference_project is None:
raise(GitlabCreateError(error_message='Failed to setup course'))
for user in get_students(gl, students_csv):
create_project(gl, solution, user, reference_project, deploy_key)

View file

@ -0,0 +1,54 @@
import csv
class Student():
"""A Gitlab user
Students are read from the CSV file that was exported from Stud.IP.
For each user, a dummy LDAP user is created in Gitlab.
Upon the first login Gitlab fetches the complete user using LDAP.
"""
def __init__(self, user, mail, name, group):
self.user = user
self.email = mail
self.name = name
self.group = group
def from_csv(csvfile):
"""Creates an iterable containing the users"""
reader = csv.DictReader(csvfile, delimiter=';', quotechar='"')
for line in reader:
yield Student(line['Nutzernamen'], line['E-Mail'], line['Vorname']
+ ' ' + line['Nachname'], line['Gruppe'])
def get_students(gl, students_csv):
"""Returns already existing GitLab users for students from provided CSV file that have an account.
"""
for student in Student.from_csv(students_csv):
users = gl.users.list(search=student.user)
if len(users) > 0:
yield users[0]
def create_user(gl, student, ldap_base, ldap_provider):
"""Creates a GitLab user account student.
Requires admin privileges.
"""
user = gl.users.create({
'email': student.email,
'username': student.user,
'name': student.name,
'provider': ldap_provider,
'skip_confirmation': True,
'extern_uid': 'uid=%s,%s' % (student.user, ldap_base),
'password': secrets.token_urlsafe(nbytes=32)
})
user.customattributes.set('group', student.group)
return user