diff --git a/script/validators/source_validator.py b/script/validators/source_validator.py index 1e8a785..37074ed 100644 --- a/script/validators/source_validator.py +++ b/script/validators/source_validator.py @@ -64,6 +64,9 @@ EXCLUDE_DIRECTORIES = [ # Docker files os.path.join(OTTERTUNE_DIR, 'docker'), + + # Django manage.py extensions + os.path.join(OTTERTUNE_DIR, "server/website/website/management"), ] # Files that should NOT be checked diff --git a/server/website/website/management/commands/createuser.py b/server/website/website/management/commands/createuser.py new file mode 100644 index 0000000..278fdf0 --- /dev/null +++ b/server/website/website/management/commands/createuser.py @@ -0,0 +1,52 @@ +# +# OtterTune - createuser.py +# +# Copyright (c) 2017-18, Carnegie Mellon University Database Group +# +from django.contrib.auth.models import User +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'Create a new user.' + + def add_arguments(self, parser): + parser.add_argument( + 'username', + metavar='USERNAME', + help='Specifies the login for the user.') + parser.add_argument( + 'password', + metavar='PASSWORD', + help='Specifies the password for the user.') + parser.add_argument( + '--email', + metavar='EMAIL', + default=None, + help='Specifies the email for the user.') + parser.add_argument( + '--superuser', + action='store_true', + help='Creates a superuser.') + + def handle(self, *args, **options): + username = options['username'] + if User.objects.filter(username=username).exists(): + self.stdout.write(self.style.NOTICE( + "ERROR: User '{}' already exists.".format(username))) + else: + password = options['password'] + email = options['email'] + superuser = options['superuser'] + + if superuser: + email = email or '{}@noemail.com'.format(username) + create_user = User.objects.create_superuser + else: + create_user = User.objects.create_user + + create_user(username=username, password=password, email=email) + + self.stdout.write(self.style.SUCCESS("Successfully created {} '{}'{}.".format( + 'superuser' if superuser else 'user', username, + " ('{}')".format(email) if email else ''))) diff --git a/server/website/website/management/commands/deleteuser.py b/server/website/website/management/commands/deleteuser.py new file mode 100644 index 0000000..f682e59 --- /dev/null +++ b/server/website/website/management/commands/deleteuser.py @@ -0,0 +1,29 @@ +# +# OtterTune - deleteuser.py +# +# Copyright (c) 2017-18, Carnegie Mellon University Database Group +# +from django.contrib.auth.models import User +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'Delete an existing user.' + + def add_arguments(self, parser): + parser.add_argument( + 'username', + metavar='USERNAME', + # required=True, + help='Specifies the login of the user to delete.') + + def handle(self, *args, **options): + username = options['username'] + try: + user = User.objects.get(username=username) + user.delete() + self.stdout.write(self.style.SUCCESS( + "Successfully deleted user '{}'.".format(username))) + except User.DoesNotExist: + self.stdout.write(self.style.NOTICE( + "ERROR: User '{}' does not exist.".format(username))) diff --git a/server/website/website/management/commands/getuploadcode.py b/server/website/website/management/commands/getuploadcode.py new file mode 100644 index 0000000..1ba923f --- /dev/null +++ b/server/website/website/management/commands/getuploadcode.py @@ -0,0 +1,40 @@ +# +# OtterTune - getuploadcode.py +# +# Copyright (c) 2017-18, Carnegie Mellon University Database Group +# +from django.core.management.base import BaseCommand + +from website.models import Session + + +class Command(BaseCommand): + help = 'Get the upload code for a session.' + + def add_arguments(self, parser): + parser.add_argument( + 'username', + metavar='USERNAME', + help='Specifies the username of the session owner.') + parser.add_argument( + 'projectname', + metavar='PROJECTNAME', + help='Specifies the name of the project that the session belongs to.') + parser.add_argument( + 'sessionname', + metavar='SESSIONNAME', + help='Specifies the name of the session.') + + def handle(self, *args, **options): + username = options['username'] + projectname = options['projectname'] + sessionname = options['sessionname'] + session = Session.objects.filter(user__username=username, + project__name=projectname, + name=sessionname).first() + if session: + self.stdout.write(self.style.NOTICE(session.upload_code)) + else: + self.stdout.write(self.style.NOTICE( + "ERROR: Session '{}' for user '{}' under project '{}' does not exist.".format( + sessionname, username, projectname))) diff --git a/server/website/website/management/commands/listusers.py b/server/website/website/management/commands/listusers.py new file mode 100644 index 0000000..52b7b26 --- /dev/null +++ b/server/website/website/management/commands/listusers.py @@ -0,0 +1,46 @@ +# +# OtterTune - listusers.py +# +# Copyright (c) 2017-18, Carnegie Mellon University Database Group +# +from django.contrib.auth.models import User +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'List all users.' + default_fields = ('username', 'email', 'is_superuser') + item_fmt = '{{{i}: <{w}}}'.format + col_space = 3 + + def add_arguments(self, parser): + parser.add_argument( + 'fields', + nargs='*', + default='DEFAULT', + choices=[f.name for f in User._meta.get_fields()] + ['DEFAULT'], + metavar='FIELDS', + help='Fields from the User model to display. (default: {})'.format( + list(self.default_fields))) + + def handle(self, *args, **options): + fields = options['fields'] + if fields == 'DEFAULT': + fields = self.default_fields + + users = User.objects.values_list(*fields) + self.stdout.write(self.style.NOTICE( + '\nFound {} existing users.\n'.format(len(users)))) + if users: + fmt = '' + for i, field in enumerate(fields): + w = max(len(field), max(len(str(u[i])) for u in users)) + self.col_space + fmt += self.item_fmt(i=i, w=w) + fmt = (fmt + '\n').format + h = fmt(*fields) + out = h + ('-' * (len(h) + 1)) + '\n' + for user_info in users: + out += fmt(*(str(ui) for ui in user_info)) + out += '\n' + + self.stdout.write(out) diff --git a/server/website/website/management/commands/setuploadcode.py b/server/website/website/management/commands/setuploadcode.py new file mode 100644 index 0000000..2cff710 --- /dev/null +++ b/server/website/website/management/commands/setuploadcode.py @@ -0,0 +1,49 @@ +# +# OtterTune - setuploadcode.py +# +# Copyright (c) 2017-18, Carnegie Mellon University Database Group +# +from django.core.management.base import BaseCommand + +from website.models import Session +from website.utils import MediaUtil + + +class Command(BaseCommand): + help = 'Set the upload code for a session.' + + def add_arguments(self, parser): + parser.add_argument( + 'username', + metavar='USERNAME', + help='Specifies the username of the session owner.') + parser.add_argument( + 'projectname', + metavar='PROJECTNAME', + help='Specifies the name of the project that the session belongs to.') + parser.add_argument( + 'sessionname', + metavar='SESSIONNAME', + help='Specifies the name of the session.') + parser.add_argument( + '--upload-code', + metavar='UPLOADCODE', + default=None, + help='Specifies the value to set the upload code to.') + + def handle(self, *args, **options): + username = options['username'] + projectname = options['projectname'] + sessionname = options['sessionname'] + session = Session.objects.filter(user__username=username, + project__name=projectname, + name=sessionname).first() + if session: + upload_code = options['upload_code'] or MediaUtil.upload_code_generator() + session.upload_code = upload_code + session.save() + self.stdout.write(self.style.NOTICE(upload_code)) + else: + self.stdout.write(self.style.NOTICE( + "ERROR: Session '{}' for user '{}' under project '{}' does not exist.".format( + sessionname, username, projectname)))