Refactoring

This commit is contained in:
Tim Schubert 2018-03-28 17:20:30 +02:00
parent 3f82036c3d
commit 34b1bd617e
2 changed files with 117 additions and 129 deletions

View file

@ -19,9 +19,8 @@ class Deadline(yaml.YAMLObject):
self.time = time self.time = time
self.ref = ref self.ref = ref
def tag(self, project): def trigger(self, project):
"""Create protected tag on ref for all deadlines that have been """Create protected tag on ref"""
reached"""
try: try:
project.tags.create({ project.tags.create({
@ -31,42 +30,28 @@ class Deadline(yaml.YAMLObject):
except gitlab.exceptions.GitlabHttpError as e: except gitlab.exceptions.GitlabHttpError as e:
log.warn(e) log.warn(e)
def test(self):
return self.time <= datetime.datetime.now()
class Course(yaml.YAMLObject): class Course(yaml.YAMLObject):
"""A course""" """A course"""
yaml_tag = 'Course' yaml_tag = 'Course'
def setup_gitlab_group(self, groups): def __init__(self, name, base, ldap, deadlines):
try:
found = groups.list(search=self.name)
return found[0]
except gitlab.exceptions.GitlabHttpError as e:
log.info(e)
if e.response_code == 404:
gl.groups.create({})
path = self.name.replace(' ', '_').lower()
group = gl.groups.create({
'name': self.name,
'path': path
})
for repo in self.repos:
group.repos.create({
'name': repo,
'namespace_id': group.path,
'visibility': 'internal'
})
return group
else:
raise e
def __init__(self, name, deadlines, repos):
self.name = name self.name = name
self.repos = repos self.base = base
self.ldap = ldap
self.deadlines = deadlines self.deadlines = deadlines
def projects(self, groups): def create_group(self, gl):
return groups.list(search=self.name)[0].projects.list() path = self.name.replace(' ', '_').lower()
self.group = gl.groups.create({
'name': self.name,
'path': path
})
return self.group
class Student(): class Student():
@ -78,83 +63,87 @@ class Student():
self.name = name self.name = name
self.group = group self.group = group
def setup_project(self, base, course):
"""Create user projects as forks from course/solutions in namespace of
course and add user as developer (NOT master) user should not be able
to modify protected TAG or force-push on protected branch users can
later invite other users into their projects"""
fork = course.group.projects.list(name=self.user)
if len(fork) == 0:
fork = base.forks.create({
'name': self.user,
'namespace': base.namspace,
'visibility': 'private'
})
fork.members.create({
'user_id': self.user,
'access_level': gitlab.DEVELOPER_ACCESS
})
return fork
def setup_ldap_dummy(self, users, provider, basedn):
# TODO call from creation of student object()
"""Creates a dummy user for users that do not exist in gitlab
but in LDAP and have not logged in yet"""
users = users.list(search=self.user)
if len(users) == 0:
dummy = users.create({
'email': self.email,
'username': self.name,
'name': self.user,
'provider': provider,
'skip_confirmation': True,
'extern_uid': 'uid=%s,%s' % (self.user, basedn),
'password': secrets.token_urlsafe(nbytes=32)
})
return dummy
else:
return users[0]
def from_csv(csvfile): def from_csv(csvfile):
reader = csv.DictReader(csvfile, delimiter=';', quotechar='"') reader = csv.DictReader(csvfile, delimiter=';', quotechar='"')
for line in reader: for line in reader:
student = Student(line['Nutzernamen'], yield Student(line['Nutzernamen'], line['E-Mail'], line['Vorname']
line['E-Mail'], + ' ' + line['Nachname'], line['Gruppe'])
line['Vorname'] + ' ' + line['Nachname'],
line['Gruppe']) def create_user(self, gl, ldap):
yield student """Creates a dummy user for users that do not exist in gitlab
but in LDAP and have not logged in yet"""
return gl.users.create({
'email': self.email,
'username': self.name,
'name': self.user,
'provider': ldap['provider'],
'skip_confirmation': True,
'extern_uid': 'uid=%s,%s' % (self.user, ldap['basedn']),
'password': secrets.token_urlsafe(nbytes=32)
})
def create_students(gl, conf, args): def fork_project(gl, group, base, user):
with open(args.students[0], 'r') as csvfile: """Create user projects as forks from course/solutions in namespace of
for student in Student.from_csv(csvfile): course and add user as developer (NOT master) user should not be able
student.setup_ldap_dummy(gl.users, conf['ldap']['provider'], conf['ldap']['basedn']) to modify protected TAG or force-push on protected branch users can
student.setup_project('solutions', args['course'][0]) #TODO later invite other users into their projects"""
print(student)
# fork course base project (e.g. solutions)
fork = base.forks.create({
'name': user['name'],
'namespace': group.namspace,
'visibility': 'private'
})
# add student as member of project
fork.members.create({
'user_id': user,
'access_level': gitlab.DEVELOPER_ACCESS
})
return fork
def create_courses(gl, conf, args): def create_project(group, name):
for course in conf['courses']: return group.projects.create({
course.setup_gitlab_group(gl.groups) 'name': name,
print(course) 'namespace_id': group.path,
'visibility': 'internal'
})
def create_deadlines(gl, conf, args): def deadlines(gl, course, args):
for course in conf['courses']: """Checks deadlines for course and triggers deadline if it is reached"""
for deadline in course.deadlines:
pass for deadline in course.deadlines:
#if deadline.time <= datetime.datetime.now(): if deadline.test():
# deadline has approached deadline.trigger(course)
# TODO setup cronjob?
# deadline.tag(project)
def sync(gl, courses, args):
"""Sync groups and students from Stud.IP to Gitlab and create student
projects
one-way sync!!!
"""
for course in courses:
course.create_group(gl)
create_project(course.group)
with open(args.students[0]) as csvfile:
for student in Student.from_csv(csvfile):
student.create_user(gl, course.ldap)
def parseconf(conf):
"""Reads courses from config file"""
with open(args.config, 'r') as conf:
return yaml.safe_load(conf)
if __name__ == '__main__': if __name__ == '__main__':
@ -163,21 +152,23 @@ if __name__ == '__main__':
gl.auth() gl.auth()
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--config', type=str, nargs=1, help='path to config file', default='config.yml') parser.add_argument(
'--config', type=str, nargs=1, help='path to config file',
default='config.yml')
subparsers = parser.add_subparsers(title='subcommands')
course_parser = parser.add_subparsers('courses') sync_parser = subparsers.add_parser(
course_parser.set_defaults(func=create_courses) 'sync',
description='students and courses from Stud.IP and LDAP')
sync_parser.set_defaults(func=sync)
sync_parser.add_argument('--students', nargs=1,
description='Students CSV file')
student_parser = parser.add_subparsers('students') deadline_parser = subparsers.add_parser('deadlines',
student_parser.add_argument('students', desc='Exported CSV file from Stud.IP', nargs=1, type=str) description='trigger deadlines')
student_parser.add_argument('course', desc='Course for CSV file', nargs=1, type=str) deadline_parser.set_defaults(func=deadlines)
student_parser.set_defaults(func=create_students)
deadline_parser = parser.add_subparsers('deadlines')
deadline_parser.set_defaults(func=create_deadlines)
args = parser.parse_args() args = parser.parse_args()
conf = parseconf(args.conf)
with open(args.config, 'r') as conf: args.func(gl, conf, args)
conf = yaml.safe_load(conf)
args.func(gl, conf, args)

View file

@ -1,23 +1,20 @@
---
!!Course
name: Programmieren 1
base: solutions
ldap: ldap:
basedn: "ou=people,dc=tu-bs,dc=de" basedn: "ou=people,dc=tu-bs,dc=de"
dummy_user: provider: main
provider: main deadlines:
skip_confirmation: true
courses:
- -
--- !Course !!Deadline
name: Programmieren 1 tag: Exercise 1
repos: [solutions, exercises] time: 2018-04-01t00:00.00
deadlines: ref: master
-
--- !Deadline -
tag: Exercise 1 !!Deadline
time: 2018-04-01t00:00.00 tag: Exercise 2
ref: master time: 2018-04-15t15:00.00
ref: master
-
--- !Deadline
tag: Exercise 2
time: 2018-04-15t15:00.00
ref: master