diff --git a/.gitignore b/.gitignore index a70aeeb..9972c6c 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,10 @@ coverage.xml local_settings.py db.sqlite3 db.sqlite3-journal +migrations/ +*/migrations/ +**/**/migrations +**/migrations # Flask stuff: instance/ diff --git a/CLI/student.py b/CLI/student.py index daec0d5..5d6ad51 100644 --- a/CLI/student.py +++ b/CLI/student.py @@ -43,6 +43,11 @@ def putDB(data, url): print("PUT:" + str(r.status_code)) return(r.json()) +def patchDB(data, url): + r = requests.patch(url = url, data=data, auth=('raffukhondaker','hackgroup1')) + print("PATH:" + str(r.status_code)) + return(r.json()) + def delDB(url): r = requests.delete(url = url, auth=('raffukhondaker','hackgroup1')) print("DELETE:" + str(r.status_code)) @@ -129,17 +134,9 @@ class Student: os.chdir(cdir) self.repo = 'https://github.com/' + self.git + '/' + self.username + '.git' data={ - 'user':self.user, - 'git':self.git, - 'ion_user':self.username, - 'added_to':self.snew, - 'url':self.url, - 'classes':self.sclass, - 'grade':self.grade, - 'completed':self.completed, 'repo':self.repo } - print(putDB(data, self.url)) + print(patchDB(data, self.url)) print("Synced to " + self.username) def getClasses(self): @@ -163,7 +160,7 @@ class Student: zero = datetime.timedelta(0,0) #check due ddate is in span range is now past date (- timdelta) if(diff < span and diff > zero): - print((now-due)) + print(a + " due in:" + str(now-due)) except Exception as e: print(e) @@ -279,17 +276,10 @@ class Student: #update teacher instance in db, classes field data={ 'user':self.user, - 'git':self.git, - 'ion_user':self.username, - 'student_id':self.student_id, 'added_to':self.snew, - 'url':self.url, - 'classes':self.sclass, - 'grade':self.grade, - 'completed':self.completed } print(self.url) - print(putDB(data, self.url)) + print(patchDB(data, self.url)) return data def submit(self, path): diff --git a/CLI/teacher.py b/CLI/teacher.py index fa82ca8..79673aa 100644 --- a/CLI/teacher.py +++ b/CLI/teacher.py @@ -9,7 +9,18 @@ import time import pyperclip from distutils.dir_util import copy_tree from datetime import datetime +from django.conf import settings +import django +from Website.config.settings import DATABASES, INSTALLED_APPS +INSTALLED_APPS.remove('users.apps.UsersConfig') +INSTALLED_APPS.remove('api') +INSTALLED_APPS.remove('skoolos.apps.SkoolosConfig') +INSTALLED_APPS.append('Website.api') +settings.configure(DATABASES=DATABASES, INSTALLED_APPS=INSTALLED_APPS) +django.setup() + +from Website.api.models import * #git clone student directory ==> <student-id>/classes/assignments #get teacher info from api @@ -33,6 +44,10 @@ def getDB(url): r = requests.get(url = url, auth=('raffukhondaker','hackgroup1')) print("GET:" + str(r.status_code)) return(r.json()) +def patchDB(data, url): + r = requests.patch(url = url, data=data, auth=('raffukhondaker','hackgroup1')) + print("PATH:" + str(r.status_code)) + return(r.json()) def postDB(data, url): r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1')) @@ -69,25 +84,10 @@ class Teacher: self.git=data['git'] self.username=data['ion_user'] self.url= "http://127.0.0.1:8000/api/teachers/" + self.username + "/" - self.email = data['email'] #classes in id form (Example: 4,5) - cid=data['classes'].split(",") - try: - cid.remove('') - except: - pass - try: - cid.remove("") - except: - pass - classes=[] - for c in cid: - url = "http://127.0.0.1:8000/api/classes/" + str(c) + "/" - classes.append(getDB(url)) - - self.classes = classes - self.sclass=str(data['classes']) + #array + self.classes=data['classes'] if(os.path.isdir(self.username + "/Students")): print("Synced to " + self.username) else: @@ -168,6 +168,7 @@ class Teacher: #add to instance #upate self.classes self.classes.append(data) + patchDB(data, self.url) if(len(self.sclass)==0): self.sclass = data['name'] else: diff --git a/Website/api/maker.py b/Website/api/maker.py index 0f0b07f..18afd33 100644 --- a/Website/api/maker.py +++ b/Website/api/maker.py @@ -1,3 +1,7 @@ +from django.contrib.auth.models import Group + +g, created = Group.objects.get_or_create(name='teachers') + # from datetime import datetime # # f1 = DefFiles( diff --git a/Website/api/migrations/0001_initial.py b/Website/api/migrations/0001_initial.py deleted file mode 100644 index 428a21e..0000000 --- a/Website/api/migrations/0001_initial.py +++ /dev/null @@ -1,75 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 23:00 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Class', - fields=[ - ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('description', models.CharField(default='Class Description', max_length=500)), - ('repo', models.URLField(blank=True, default='')), - ('path', models.CharField(default='', max_length=100)), - ('assignments', models.TextField(blank=True, default='')), - ('default_file', models.CharField(blank=True, default='', max_length=100)), - ('confirmed', models.TextField(blank=True, default='')), - ('unconfirmed', models.TextField(blank=True, default='')), - ], - ), - migrations.CreateModel( - name='DefFiles', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ('path', models.CharField(max_length=100)), - ('assignment', models.CharField(default='', max_length=100)), - ('classes', models.CharField(max_length=100)), - ('teacher', models.CharField(max_length=100)), - ], - ), - migrations.CreateModel( - name='Teacher', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('git', models.CharField(blank=True, default='', max_length=100)), - ('classes', models.ManyToManyField(to='api.Class')), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Student', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('grade', models.IntegerField(blank=True, default=0)), - ('git', models.CharField(blank=True, default='', max_length=100)), - ('repo', models.URLField(blank=True, default='')), - ('classes', models.CharField(blank=True, default='', max_length=100)), - ('added_to', models.CharField(blank=True, default='', max_length=100)), - ('completed', models.TextField(blank=True, default='')), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Assignment', - fields=[ - ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('due_date', models.DateTimeField()), - ('files', models.CharField(blank=True, default='', max_length=100)), - ('path', models.CharField(max_length=100)), - ('classes', models.CharField(max_length=100)), - ('teacher', models.CharField(max_length=100)), - ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='assignments', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/Website/api/migrations/0002_auto_20200615_0046.py b/Website/api/migrations/0002_auto_20200615_0046.py deleted file mode 100644 index 94bb36e..0000000 --- a/Website/api/migrations/0002_auto_20200615_0046.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-15 00:46 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='class', - name='confirmed', - ), - migrations.AddField( - model_name='class', - name='confirmed', - field=models.ManyToManyField(blank=True, related_name='confirmed', to='api.Student'), - ), - migrations.RemoveField( - model_name='class', - name='unconfirmed', - ), - migrations.AddField( - model_name='class', - name='unconfirmed', - field=models.ManyToManyField(blank=True, related_name='unconfirmed', to='api.Student'), - ), - ] diff --git a/Website/api/migrations/0003_auto_20200615_0233.py b/Website/api/migrations/0003_auto_20200615_0233.py deleted file mode 100644 index 031aa1a..0000000 --- a/Website/api/migrations/0003_auto_20200615_0233.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-15 02:33 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0002_auto_20200615_0046'), - ] - - operations = [ - migrations.AlterField( - model_name='teacher', - name='classes', - field=models.ManyToManyField(blank=True, related_name='teacher', to='api.Class'), - ), - ] diff --git a/Website/api/migrations/0004_auto_20200615_0255.py b/Website/api/migrations/0004_auto_20200615_0255.py deleted file mode 100644 index e126c18..0000000 --- a/Website/api/migrations/0004_auto_20200615_0255.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-15 02:55 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0003_auto_20200615_0233'), - ] - - operations = [ - migrations.RemoveField( - model_name='teacher', - name='classes', - ), - migrations.AddField( - model_name='class', - name='teachers', - field=models.ManyToManyField(blank=True, related_name='teachers', to='api.Teacher'), - ), - ] diff --git a/Website/api/migrations/0005_auto_20200615_0048.py b/Website/api/migrations/0005_auto_20200615_0048.py deleted file mode 100644 index 1a60cfd..0000000 --- a/Website/api/migrations/0005_auto_20200615_0048.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-15 00:48 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0004_auto_20200614_2107'), - ] - - operations = [ - migrations.RemoveField( - model_name='student', - name='id', - ), - migrations.AddField( - model_name='student', - name='ion_user', - field=models.CharField(default='2022rkhondak', max_length=100, primary_key=True, serialize=False), - preserve_default=False, - ), - ] diff --git a/Website/api/models.py b/Website/api/models.py index e7f4f6d..6f612c3 100644 --- a/Website/api/models.py +++ b/Website/api/models.py @@ -1,10 +1,12 @@ from django.db import models from django.contrib.auth.models import User +import secrets class Student(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) + ion_user = models.CharField(max_length=100) grade = models.IntegerField(default=0, blank=True) git=models.CharField(default="", max_length=100, blank=True) repo=models.URLField(default="", blank=True) @@ -18,49 +20,6 @@ class Student(models.Model): def __str__(self): return f"{self.user.username}'s Profile" -class Class(models.Model): - name = models.CharField(primary_key=True, max_length=100) - description = models.CharField(default="Class Description", max_length=500) - repo=models.URLField(default="", blank=True) - path=models.CharField(max_length=100, default="") - assignments=models.TextField(default="", blank=True) - default_file=models.CharField(max_length=100, default="", blank=True) - confirmed=models.ManyToManyField(Student, blank=True, related_name='confirmed') - unconfirmed=models.ManyToManyField(Student, blank=True, related_name='unconfirmed') - - # assignments = models.ManyToManyField(Assignment, default="") - # default_file = models.ManyToManyField(DefFiles) - def save(self, *args, **kwargs): - return super(Class, self).save(*args, **kwargs) - - def __str__(self): - return self.name - -class Teacher(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE) - classes=models.ManyToManyField(Class, blank=True, related_name='classes') - git=models.CharField(max_length=100, default="", blank=True) - - - def __str__(self): - return f"{self.user.username}'s Profile" - - def save(self, *args, **kwargs): - super(Teacher, self).save(*args, **kwargs) - -class Student(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE) - ion_user=models.CharField(primary_key=True, max_length=100) - grade = models.IntegerField(default=0, blank=True) - git=models.CharField(default="", max_length=100, blank=True) - repo=models.URLField(default="", blank=True) - classes=models.CharField(max_length=100, default="", blank=True) - added_to=models.CharField(max_length=100, default="", blank=True) - completed=models.TextField(default="", blank=True) - - - - class Assignment(models.Model): owner = models.ForeignKey('auth.User', related_name='assignments', on_delete=models.CASCADE) @@ -74,6 +33,55 @@ class Assignment(models.Model): def __str__(self): return '%s' % (self.name) +class Class(models.Model): + owner = models.ForeignKey('auth.User', related_name='classes', on_delete=models.CASCADE) + teacher = models.CharField(max_length=100) + name = models.CharField(primary_key=True, max_length=100) + id = models.CharField(max_length=8, blank=True, null=True) + description = models.CharField(default="Class Description", max_length=500) + repo=models.URLField(default="", blank=True) + path=models.CharField(max_length=100, default="") + assignments=models.ManyToManyField(Assignment, blank=True) + default_file=models.CharField(max_length=100, default="", blank=True) + confirmed=models.ManyToManyField(Student, blank=True, related_name='confirmed') + unconfirmed=models.ManyToManyField(Student, blank=True, related_name='unconfirmed') + + # assignments = models.ManyToManyField(Assignment, default="") + # default_file = models.ManyToManyField(DefFiles) + def save(self, *args, **kwargs): + id = self.id + if not id: + id = secrets.token_urlsafe()[:8].lower() + while Class.objects.filter(id=id).exclude(pk=self.pk).exists(): + id = sercrets.token_urlsafe()[:8].lower() + self.id = id + return super(Class, self).save(*args, **kwargs) + + def __str__(self): + return self.name + +class Teacher(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + classes=models.ManyToManyField(Class, blank=True, related_name='classes') + git=models.CharField(max_length=100, default="", blank=True) + ion_user=models.CharField(primary_key=True, max_length=100) + + def __str__(self): + return f"{self.user.username}'s Profile" + + def save(self, *args, **kwargs): + super(Teacher, self).save(*args, **kwargs) + +# class Student(models.Model): +# user = models.OneToOneField(User, on_delete=models.CASCADE) +# ion_user=models.CharField(primary_key=True, max_length=100) +# grade = models.IntegerField(default=0, blank=True) +# git=models.CharField(default="", max_length=100, blank=True) +# repo=models.URLField(default="", blank=True) +# classes=models.CharField(max_length=100, default="", blank=True) +# added_to=models.CharField(max_length=100, default="", blank=True) +# completed=models.TextField(default="", blank=True) + class DefFiles(models.Model): name=models.CharField(max_length=100) diff --git a/Website/api/serializers.py b/Website/api/serializers.py index 238d6c1..5d87c60 100644 --- a/Website/api/serializers.py +++ b/Website/api/serializers.py @@ -1,5 +1,5 @@ from django.contrib.auth.models import User, Group -from .models import Student, Teacher, Classes, Assignment, DefFiles +from .models import Student, Teacher, Class, Assignment, DefFiles from rest_framework import serializers, permissions from django.contrib.auth.models import User from .permissions import IsOwnerOrReadOnly,isTeacher @@ -15,40 +15,38 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): # class DefFilesSerializer(serializers.HyperlinkedModelSerializer): # class Meta: # model = DefFiles -# fields = ['name', 'path','assignment','classes', "teacher",'url', 'id'] +# fields = ['name', 'path','assignment','Class', "teacher",'url', 'id'] class AssignmentSerializer(serializers.HyperlinkedModelSerializer): - #permissions_classes = [permissions.IsAuthenticatedOrReadOnly] + #permissions_Class = [permissions.IsAuthenticatedOrReadOnly] # files = DefFilesSerializer(many=True, read_only=True,allow_null=True) owner = serializers.ReadOnlyField(source='owner.username') class Meta: model = Assignment - # fields = ['url','name', 'due_date', 'path' , "classes","teacher",'owner'] - fields = ['name', 'due_date', 'path' , "classes","teacher",'owner'] + # fields = ['url','name', 'due_date', 'path' , "Class","teacher",'owner'] + fields = ['name', 'due_date', 'path' , "Class","teacher",'owner'] -class ClassesSerializer(serializers.HyperlinkedModelSerializer): +class ClassSerializer(serializers.HyperlinkedModelSerializer): # assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True) # default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True) - owner = serializers.ReadOnlyField(source='owner.username') + #owner = serializers.ReadOnlyField(source='owner.username') class Meta: - model = Classes + model = Class # fields = ['url','name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner'] - fields = ['name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner'] + fields = ['name', 'repo','path','assignments',"teacher","default_file", 'confirmed', 'unconfirmed','owner'] class StudentSerializer(serializers.HyperlinkedModelSerializer): - # classes = ClassesSerializer(many=True, read_only=True,allow_null=True) + # Class = ClassSerializer(many=True, read_only=True,allow_null=True) class Meta: model = Student - # fields = ['url','first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner'] + # fields = ['url','first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','Class','added_to','completed', 'repo','owner'] fields = ['url','grade', 'ion_user','git','user','classes','added_to','completed', 'repo'] class TeacherSerializer(serializers.ModelSerializer): - # classes = ClassesSerializer(many=True, read_only=True,allow_null=True) - owner = serializers.ReadOnlyField(source='owner.username') + #classes = ClassSerializer(many=True, read_only=True,allow_null=True) + #owner = serializers.ReadOnlyField(source='owner.username') class Meta: model = Teacher - # fields = ['url','first_name', 'last_name','git','ion_user', 'email','classes','owner'] - fields = ['first_name', 'last_name','git','ion_user', 'email','classes','owner'] - - + # fields = ['url','first_name', 'last_name','git','ion_user', 'email','Class','owner'] + fields = ['git','ion_user','classes','user'] diff --git a/Website/api/views.py b/Website/api/views.py index 11af2b1..fb95e11 100644 --- a/Website/api/views.py +++ b/Website/api/views.py @@ -8,7 +8,7 @@ from .permissions import isTeacher, IsOwnerOrReadOnly from django.shortcuts import render, redirect from rest_framework.parsers import JSONParser from rest_framework.response import Response - +from django.contrib.auth.models import Group class UserViewSet(viewsets.ModelViewSet): @@ -26,7 +26,7 @@ class StudentViewSet(viewsets.ModelViewSet): permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly] def perform_create(self, serializer): - serializer.save(owner=self.request.user) + serializer.save(user=self.request.user) class TeacherViewSet(viewsets.ModelViewSet): """ @@ -37,7 +37,7 @@ class TeacherViewSet(viewsets.ModelViewSet): permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly] def perform_create(self, serializer): - serializer.save(owner=self.request.user) + serializer.save(user=self.request.user) class ClassViewSet(viewsets.ModelViewSet): """ @@ -47,12 +47,12 @@ class ClassViewSet(viewsets.ModelViewSet): serializer_class = ClassSerializer permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly] - def perform_create(self, serializer): - if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser): - serializer.save(owner=self.request.user) - else: - print("UNAUTHORIZED POST") - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + # def perform_create(self, serializer): + # if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser): + # serializer.save(owner=self.request.user) + # else: + # print("UNAUTHORIZED POST") + # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class AssignmentViewSet(viewsets.ModelViewSet): diff --git a/Website/skoolos/templates/skoolos/home.html b/Website/skoolos/templates/skoolos/home.html index 621c328..d6e5432 100644 --- a/Website/skoolos/templates/skoolos/home.html +++ b/Website/skoolos/templates/skoolos/home.html @@ -3,7 +3,7 @@ <div class="content-section"> {% for class in classes %} <div class="card-columns"> - <a class="card" href="#" style="text-decoration: none;"> + <a class="card" href="/class/{{ class.pk }}" style="text-decoration: none;"> <div class="card-body"> <h5 class="card-title">{{ class.name }}</h5> <p class="card-text">{{ class.description }}</p> diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index a8ffe34..182fea5 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -5,5 +5,6 @@ from . import views # Additionally, we include login URLs for the browsable API. urlpatterns = [ path('', views.home, name='home'), - path('profile/', views.profile, name='profile') + path('profile/', views.profile, name='profile'), + path("class/<int:id>", views.classDetail, name="class"), ] diff --git a/Website/skoolos/views.py b/Website/skoolos/views.py index b654c11..2748b71 100644 --- a/Website/skoolos/views.py +++ b/Website/skoolos/views.py @@ -1,7 +1,8 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required +from django.views.generic import ListView -from api.models import Student, Teacher +from api.models import Student, Teacher, Class, Assignment # Create your views here. @@ -24,3 +25,7 @@ def home (request): @login_required() def profile (request): pass + +def classDetail (request, id): + classObj = Class.objects.get(id=id) + return redirect('/') diff --git a/Website/users/migrations/0001_initial.py b/Website/users/migrations/0001_initial.py deleted file mode 100644 index 1c06dee..0000000 --- a/Website/users/migrations/0001_initial.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 19:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Token', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('username', models.TextField()), - ('email', models.TextField()), - ('first_name', models.TextField()), - ('last_name', models.TextField()), - ('isStudent', models.BooleanField()), - ('token', models.CharField(max_length=255)), - ], - ), - ] diff --git a/Website/users/migrations/0002_auto_20200614_2044.py b/Website/users/migrations/0002_auto_20200614_2044.py deleted file mode 100644 index 2f6941c..0000000 --- a/Website/users/migrations/0002_auto_20200614_2044.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 20:44 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='token', - name='isStudent', - field=models.BooleanField(default=True), - ), - ] diff --git a/Website/users/migrations/0003_token_grade.py b/Website/users/migrations/0003_token_grade.py deleted file mode 100644 index 4b0788c..0000000 --- a/Website/users/migrations/0003_token_grade.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 21:07 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0002_auto_20200614_2044'), - ] - - operations = [ - migrations.AddField( - model_name='token', - name='grade', - field=models.IntegerField(default=9), - ), - ] diff --git a/Website/users/migrations/__init__.py b/Website/users/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Website/users/views.py b/Website/users/views.py index 3aed887..ce417d8 100644 --- a/Website/users/views.py +++ b/Website/users/views.py @@ -8,6 +8,7 @@ from django.contrib import messages from .models import Token from api.models import Student, Teacher +from django.contrib.auth.models import Group from .forms import UserCreationForm @@ -97,15 +98,18 @@ def create_account (request): last_name=last_name, password=password) user.save() - token.delete() + g, created = Group.objects.get_or_create(name='teachers') if isStudent: - profile = Student(owner=user, git=git, grade=grade, ion_user=username) + profile = Student(user=user, git=git, grade=grade, ion_user=username) else: - profile = Teacher(owner=user, git=git, ion_user=username) + profile = Teacher(user=user, git=git, ion_user=username) + group = Group.objects.get(name='teachers') + user.groups.add(group) + profile.save() - + token.delete() print (user) messages.success(request, "Your SkoolOS account has successfully been created") return redirect(f'/login/?username={username}') diff --git a/skoolos.py b/skoolos.py index 1cfb9e3..501429e 100644 --- a/skoolos.py +++ b/skoolos.py @@ -12,6 +12,7 @@ from werkzeug.urls import url_decode import pprint from PyInquirer import prompt, print_json import json +import datetime import os import argparse import webbrowser @@ -39,7 +40,7 @@ def main(): URL = "http://127.0.0.1:8000/api/" r = requests.get(url = URL) except: - print("Stop any processes running on http://127.0.0.1:8000/ before continuing") + print("Run Django server on http://127.0.0.1:8000/ before continuing") sys.exit(0) input("Welcome to SkoolOS. Press any key to create an account") @@ -65,66 +66,91 @@ def studentCLI(user, password): from CLI import student data = getUser(user, password) student = student.Student(data) - choices = ['1) View Class','2) Exit SkoolOS'] - questions = [ + carray = student.sclass.split(",") + if(len(carray) == 1 and carray[0] == ""): + print("No classes") + return + + carray.append("Exit SkoolOS") + courses = [ { 'type': 'list', - 'name': 'choice', - 'choices':choices, + 'name': 'course', + 'choices':carray, 'message': 'Select class: ', }, ] - choice = prompt(questions) - choice = int(choice['choice'].split(")")[0]) - if(choice == 1): - carray = student.sclass.split(",") - if(len(carray) == 1 and carray[0] == ""): - print("No classes") - return - courses = [ - { - 'type': 'list', - 'name': 'course', - 'choices':carray, - 'message': 'Select class: ', - }, - ] - course = prompt(courses) - if(choice == 2): + course = prompt(courses) + if course == "Exit SkoolOS": student.exitCLI() - + else: + student.viewClass(course) + student.getAssignments(course, datetime.datetime.now()) def teacherCLI(user, password): from CLI import teacher data = getUser(user, password) teacher = teacher.Teacher(data) - choices = ['1) View Class','2) Exit SkoolOS'] - questions = [ + # 1. make a class + # 2. add studeents to an existing class + # 3. Get progress logs on a student + # 2. make an assignment for a class + # 3. view student submissions for an assignment + carray = teacher.sclass.split(",") + carray.remove("") + carray.append("Exit SkoolOS") + carray.append("Make New Class") + courses = [ { 'type': 'list', - 'name': 'choice', - 'choices':choices, + 'name': 'course', + 'choices':carray, 'message': 'Select class: ', }, ] - choice = prompt(questions) - choice = int(choice['choice'].split(")")[0]) - if(choice == 1): - carray = student.sclass.split(",") - if(len(carray) == 1 and carray[0] == ""): - print("No classes") - return - courses = [ + course = prompt(courses) + if course == "Exit SkoolOS": + teacher.exitCLI() + if course == "Make New Class": + questions = [ + { + 'type': 'input', + 'name': 'cname', + 'message': 'Class Name: ', + }, + ] + cname = prompt(questions) + teacher.makeClass(cname) + soption = ["1) Add individual student", "2) Add list of students through path", "3) Exit"] + questions = [ + { + 'type': 'list', + 'choices':soption, + 'name': 'students', + 'message': 'Add list of students (input path): ', + }, + ] + choice = prompt(questions).split(")") + if("1" == choice): + s = input("Student name: ") + teacher.addStudent(s, cname) + if("2" == choice): + p = input("Relativee Path: ") + if(os.path.exists(p)): + print(p + " does not exist.") + + else: + print("Class: " + cname) + options = ['1) Add student', "2) Add assignment", "3) View student information"] + questions = [ { 'type': 'list', 'name': 'course', - 'choices':carray, - 'message': 'Select class: ', + 'choices':options, + 'message': 'Select option: ', }, ] - course = prompt(courses) - if(choice == 2): - student.exitCLI() + option = prompt(questions) def getUser(ion_user, password): URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/" @@ -141,6 +167,10 @@ def getUser(ion_user, password): else: return None print(r.status_code) +def patchDB(data, url): + r = requests.patch(url = url, data=data, auth=('raffukhondaker','hackgroup1')) + print("PATH:" + str(r.status_code)) + return(r.json()) def getDB(url): r = requests.get(url = url, auth=('raffukhondaker','hackgroup1')) diff --git a/snew.py b/snew.py new file mode 100644 index 0000000..3edb6f4 --- /dev/null +++ b/snew.py @@ -0,0 +1,100 @@ +import sys +from urllib.parse import urlparse +import requests +from requests_oauthlib import OAuth2Session +from selenium import webdriver +import os.path +import time +import http.server +import socketserver +from threading import Thread +from werkzeug.urls import url_decode +import pprint +from PyInquirer import prompt, print_json +import json +import os +import argparse +import webbrowser +import subprocess + +from django.conf import settings +import django + +from Website.config.settings import DATABASES, INSTALLED_APPS +INSTALLED_APPS.remove('users.apps.UsersConfig') +INSTALLED_APPS.remove('api') +INSTALLED_APPS.remove('skoolos.apps.SkoolosConfig') +INSTALLED_APPS.append('Website.api') +settings.configure(DATABASES=DATABASES, INSTALLED_APPS=INSTALLED_APPS) +django.setup() + +from Website.api.models import * + +def command(command): + ar = [] + command = command.split(" ") + for c in command: + ar.append(c) + process = subprocess.Popen(ar, stdout=subprocess.PIPE,stderr=subprocess.PIPE) + p=process.poll() + output = process.communicate()[0] + print(output.decode('utf-8')) + return output.decode('utf-8') + +class Students: + def __init__(self, username): + self.student = Student.objects.get(ion_user = username) + #ion id: student.user + if(os.path.isdir(self.student.user) == False): + if(self.student.repo == ""): + user= self.student.git + pwd= input("Enter Github password: ") + #curl -i -u USER:PASSWORD -d '{"name":"REPO"}' https://api.github.com/user/repos + url= "curl -i -u " + user + ":" + pwd + " -d '" + '{"name":"' + self.username + '"}' + "' " + "https://api.github.com/user/repos" + print(url) + os.system(url) + cdir = os.getcwd() + command('git clone https://github.com/' + self.git + '/' + self.username + '.git') + os.chdir(self.username) + command('git checkout master') + command('touch README.md') + command('git add README.md') + command('git commit -m "Hello"') + command('git push -u origin master') + os.chdir(cdir) + self.repo = 'https://github.com/' + self.git + '/' + self.username + '.git' + data={ + 'user':self.user, + 'git':self.git, + 'ion_user':self.username, + 'added_to':self.snew, + 'url':self.url, + 'classes':self.sclass, + 'grade':self.grade, + 'completed':self.completed, + 'repo':self.repo + } + print(putDB(data, self.url)) + print("Synced to " + self.username) + + +# c = { +# 'name':'Math5' +# } + +# c = Class.objects.get(name='Math5') +data = requests.get(url = "http://localhost:8000/api/classes/Math5", auth=('raffukhondaker','hackgroup1')).json() + +r = requests.post(url = "http://localhost:8000/api/classes/", data={'name':'English11', 'teacher':'eharris1', 'owner':2}, auth=('raffukhondaker','hackgroup1')) + +print("POST:" + str(r.status_code)) +# print(r.json()) +# print(c.name) +# c = { +# 'classes':c +# } +# print(c) +r = requests.patch(url = "http://localhost:8000/api/teachers/eharris1/", data={'classes':['English11']}, auth=('raffukhondaker','hackgroup1')) +print(r.json()) + +