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/BackgroundService/bgservice.py b/BackgroundService/bgservice.py deleted file mode 100644 index ed26c76..0000000 --- a/BackgroundService/bgservice.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import sys -import signal -import time -import event_processor - - -class SkoolOSDaemon: - """Constructor""" - def __init__(self, work_dir='/tmp'): - self.work_dir = work_dir - self.start_time = None - self.end_time = None - self.log_file = None - def __write_pid_file(self): - try: - dirName = "/tmp/skooloslogs" - # Create log Directory - os.mkdir(dirName) - except FileExistsError: - pass - pid = str(os.getpid()) - file_ = open('/tmp/skoolosdaemonpid', 'w') - file_.write(pid) - file_.close() - def readable_time(self, input_time): - return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time)) - def start(self): - self.__write_pid_file() - self.start_time = time.time() - self.log_file = open('/tmp/skooloslogs/' + str(self.start_time), 'w') - self.log_file.write("Start time: \n" + self.readable_time(self.start_time) + "\n\n") - sys.stdout = self.log_file - event_processor.watch_dir(self.work_dir) - def stop(self): - event_processor.stop_watching() - self.end_time = time.time() - self.log_file.write("Stop time: \n" + self.readable_time(self.end_time)) - self.log_file.write("Total work time: " + - time.strftime("%H:%M:%S", time.gmtime(self.end_time - self.start_time))) - - - - -logger = None - -def Main(): - def signal_handler(signum, frame): - logger.stop() - signal.signal(signal.SIGINT, signal_handler) - # signal.signal(signal.SIGTERM, signal_handler) - global logger - logger = SkoolOSDaemon("/tmp") - logger.start() - - -if __name__ == "__main__": - Main() diff --git a/BackgroundService/event_processor.py b/BackgroundService/event_processor.py deleted file mode 100644 index 55c5e15..0000000 --- a/BackgroundService/event_processor.py +++ /dev/null @@ -1,65 +0,0 @@ -import time -import pyinotify - - -def readable_time(input_time): - return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time)) - - -class EventProcessor(pyinotify.ProcessEvent): - _methods = ["IN_OPEN", - "IN_CREATE", - "IN_CLOSE_WRITE", - "IN_DELETE", - "IN_MOVED_TO", - "IN_MOVED_FROM", - ] - - -def __method_format(method): - return { - "IN_OPEN":"Opened a file", - "IN_CREATE":"Created a file", - "IN_CLOSE_WRITE":"Wrote to a file", - "IN_DELETE":"Deleted a file", - "IN_MOVED_TO":"Moved a file or directory in from elsewhere", - "IN_MOVED_FROM":"Moved a file or directory elsewhere", - }.get(method, "Unknown event") - - -def __process_generator(cls, method): - def _method_name(self, event): - description = "Event description: {}\n" \ - "Path name: {}\n" \ - "Event Name: {}\n" \ - "Timestamp: {}\n".format(__method_format(method), - event.pathname, - event.maskname, - readable_time(time.time()) - ) - if "IN_DELETE" in description: - description += "WARNING: Unexpected file deletion\n" - if "IN_MOVED_TO" in description: - description += "WARNING: Unexpected file add to work\n" - if "IN_MOVED_FROM" in description: - description += "WARNING: Unexpected file moved out of directory\n" - print(description) - _method_name.__name__ = "process_{}".format(method) - setattr(cls, _method_name.__name__, _method_name) - - -EVENT_NOTIFIER = None - - -def watch_dir(dir_to_watch): - global EVENT_NOTIFIER - for method in EventProcessor._methods: - __process_generator(EventProcessor, method) - watch_manager = pyinotify.WatchManager() - EVENT_NOTIFIER = pyinotify.ThreadedNotifier(watch_manager, EventProcessor()) - watch_manager.add_watch(dir_to_watch, pyinotify.ALL_EVENTS, rec=True) - EVENT_NOTIFIER.loop() - - -def stop_watching(): - EVENT_NOTIFIER.stop() diff --git a/BackgroundService/test.py b/BackgroundService/test.py deleted file mode 100644 index b797228..0000000 --- a/BackgroundService/test.py +++ /dev/null @@ -1,19 +0,0 @@ -from bgservice import SkoolOSDaemon as sod -import threading - -logger = sod() - - -if __name__ == "__main__": - line=1 - print(line) - line+=1 - logger.start() - print(line) - line+=1 - input("Enter any key when you are done modifyng the /tmp/ directory") - print(line) - line+=1 - logger.stop() - print(line) - line+=1 diff --git a/CLI/oauth/index.html b/CLI/oauth/index.html deleted file mode 100644 index 9ffd6ef..0000000 --- a/CLI/oauth/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - Sign into Ion - - - - - - -
- - - Sign in with Ion - -
- - \ No newline at end of file diff --git a/CLI/student.py b/CLI/student.py index 711c99e..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)) @@ -66,15 +71,12 @@ class Student: def __init__(self, data): # teacher info already stored in API # intitialze fields after GET request - self.first_name=data['first_name'] - self.last_name=data['last_name'] self.git=data['git'] self.username=data['ion_user'] self.url= "http://127.0.0.1:8000/api/students/" + self.username + "/" - self.email = data['email'] self.grade = data['grade'] - self.student_id=data['student_id'] self.completed = data['completed'] + self.user = data['user'] #classes in id form (Example: 4,5) #storing actual classes cid=data['classes'].split(",") @@ -132,20 +134,9 @@ class Student: os.chdir(cdir) self.repo = 'https://github.com/' + self.git + '/' + self.username + '.git' data={ - 'first_name':self.first_name, - 'last_name':self.last_name, - 'git':self.git, - 'ion_user':self.username, - 'student_id':self.student_id, - 'added_to':self.snew, - 'url':self.url, - 'classes':self.sclass, - 'email':self.email, - '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): @@ -169,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) @@ -284,20 +275,11 @@ class Student: #update teacher instance in db, classes field data={ - 'first_name':self.first_name, - 'last_name':self.last_name, - 'git':self.git, - 'ion_user':self.username, - 'student_id':self.student_id, + 'user':self.user, 'added_to':self.snew, - 'url':self.url, - 'classes':self.sclass, - 'email':self.email, - '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): @@ -327,15 +309,13 @@ class Student: command("git push -u origin " + self.username + " --tags") self.completed = self.completed + "," + parts[1] + "/" + parts[2] data={ - 'first_name':self.first_name, - 'last_name':self.last_name, + '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, - 'email':self.email, 'grade':self.grade, 'completed':self.completed } diff --git a/CLI/teacher.py b/CLI/teacher.py index d34ae79..8062406 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 ==> /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("PATCH:" + str(r.status_code)) + return(r.json()) def postDB(data, url): r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1')) @@ -66,30 +81,14 @@ class Teacher: def __init__(self, data): # teacher info already stored in API # intitialze fields after GET request - self.first_name=data['first_name'] - self.last_name=data['last_name'] 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'] + self.id = data['user'] #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: @@ -151,44 +150,31 @@ class Teacher: #make class from existing directory, add to git and api def addClass(self, path): + cname = path.split("/") + cname = cname[len(cname)-1] + for c in self.classes: + if c == cname: + print(cname + " already exists.") + return if (self.checkClass(path)): - cname = path.split("/") - cname = cname[len(cname)-1] cpath = self.username + "/" + cname data = { "name": cname, "repo": "", "path": cpath, "teacher": self.username, - "assignments": "", - "default_file": "", - "confirmed": "", - "unconfirmed": "" + "owner":self.id } #make class instance in db - data = postDB(data, 'http://127.0.0.1:8000/api/classes/') + postDB(data, 'http://127.0.0.1:8000/api/classes/') + self.classes.append(cname) #add to instance #upate self.classes - self.classes.append(data) - if(len(self.sclass)==0): - self.sclass = data['name'] - else: - self.sclass = self.sclass + "," + str(data['name']) - - #update teacher instance in db, classes field - teacher={ - 'first_name':self.first_name, - 'last_name':self.last_name, - 'git':self.git, - 'ion_user':self.username, - 'url':self.url, - 'classes':self.sclass, - 'email':self.email + data = { + 'classes':self.classes } - putDB(teacher, self.url) - - return teacher - + print(self.username) + print(patchDB(data, 'http://127.0.0.1:8000/api/teachers/' + self.username + "/")) #make a new class from scratch #subject: string, assignments: list @@ -224,8 +210,7 @@ class Teacher: # f.close() # os.chdir(cdir) - data = self.addClass(path) - return data + self.addClass(path) def deleteClass(self, path): if(os.path.exists(path) == False): @@ -240,25 +225,12 @@ class Teacher: print("DELETE: " + self.classes[i]['name']) for i in range(len(self.classes)): c = self.classes[i] - if(c['name'] == cname): + if(c == cname): del self.classes[i] - s="" - #recreate sclass field, using ids - for c in self.classes: - s = s + str(c['name']) + "," - print(s) - s = s[:-1] - print(s) - data={ - 'first_name':self.first_name, - 'last_name':self.last_name, - 'git':self.git, - 'ion_user':self.username, - 'url':self.url, - 'classes':s, - 'email':self.email - } - print(putDB(data, self.url)) + # data={ + # 'classes':self.classes, + # } + # print(patchDB(data, self.url)) delDB("http://127.0.0.1:8000/api/classes/" + cname + "/") break @@ -282,53 +254,37 @@ class Teacher: print(sname + " does not exist.") return False course = getDB("http://127.0.0.1:8000/api/classes/" + cname) - if(sname in course['unconfirmed']): - print (sname + " already requested.") - return True - if(sname in course['confirmed']): - print (sname + " alredy enrolled.") - return False + # if(sname in str(course['unconfirmed'])): + # print (sname + " already requested.") + # return True + # if(sname in str(course['confirmed'])): + # print (sname + " alredy enrolled.") + # return False - student = getDB("http://127.0.0.1:8000/api/students/" + sname) - try: - if(student['added_to']==""): - student['added_to']=course['name'] - else: - student['added_to']=student['added_to']+ "," + course['name'] - except: - print(sname + " does not exist.") - return False - print(student['added_to']) - s={ - 'first_name':student["first_name"], - 'last_name':student["last_name"], - 'git':student["git"], - 'ion_user':student["ion_user"], - 'student_id':student["student_id"], - 'added_to':student['added_to'], - 'classes':student["classes"], - 'email':student["email"], - 'grade':student["grade"], - 'completed':student["completed"], - 'repo':student["repo"] - } - student = putDB(s, student['url']) - - if(course['unconfirmed']==""): + # student = getDB("http://127.0.0.1:8000/api/students/" + sname) + # try: + # if(student['added_to']==""): + # student['added_to']=course['name'] + # else: + # student['added_to']=student['added_to']+ "," + course['name'] + # except: + # print(sname + " does not exist.") + # return False + # print(student['added_to']) + # data={ + # 'added_to':student['added_to'], + # } + # student = patchDB(data, "http://localhost:8000/api/students/" + student['ion_user'] + "/") + student = getDB( "http://localhost:8000/api/students/" + (sname)+ "/") + if(course['unconfirmed']==[]): course['unconfirmed']=student['ion_user'] else: - course['unconfirmed']=course['unconfirmed']+ "," + student['ion_user'] + course['unconfirmed']=course['unconfirmed'].append(student['ion_user']) cinfo = { - "name": course['name'], - "repo": "", - "path": self.username + "/" + course['name'], - "teacher": self.username, - "assignments": course['assignments'], - "default_file": "", - "confirmed": course["confirmed"], "unconfirmed": course['unconfirmed'] } - print(putDB(cinfo, course['url'])) + print(cinfo) + patchDB(cinfo, "http://localhost:8000/api/classes/" + course['name'] + "/") return True #Student should have confirmed on their endd, but class had not been updated yet @@ -390,16 +346,10 @@ class Teacher: course['unconfirmed']= course['unconfirmed'].replace(student['ion_user']+",", "") cinfo = { - "name": course['name'], - "repo": "", - "path": course['path'], - "teacher": self.username, - "assignments": course['assignments'], - "default_file": "", "confirmed": course["confirmed"], "unconfirmed": course['unconfirmed'] } - print(putDB(cinfo, course['url'])) + print(patchDB(cinfo, "http://localhost:8000/api/classes/" + course['name'] + "/")) return True #goes through list of studennts, tries to add, then request, return unconfirmed students @@ -417,10 +367,10 @@ class Teacher: parts = path.split("/") aname = parts[len(parts)-1] - if(os.path.isdir(path) == 0 or len(parts) < 3) or aname in self.sclass: + if(os.path.isdir(path) == 0 or len(parts) < 3) or aname in str(self.classes): print("Not valid path.") return False - if((parts[1] in self.sclass) == False): + if((parts[1] in str(self.classes)) == False): print("Not in valid class directory") return False #parts of assignment name (Essay1, APLit) @@ -445,7 +395,7 @@ class Teacher: return False course = getDB("http://127.0.0.1:8000/api/classes/" + course) - if(aname in course['assignments']): + if(aname in str(course['assignments'])): print("Assignment name already taken.") return False @@ -459,7 +409,7 @@ class Teacher: slist = os.listdir(os.getcwd() + "/" + self.username + "/Students/" + course['name']) cdir = os.getcwd() for st in slist: - if st in course['confirmed']: + if st in str(course['confirmed']): spath = os.path.join(os.getcwd() + "/" + self.username + "/Students/" + course['name'], st) if(os.path.exists(spath + "/" + aname) == False): os.mkdir(spath + "/" + aname) @@ -487,21 +437,14 @@ class Teacher: } postDB(ass, 'http://127.0.0.1:8000/api/assignments/') if(course['assignments'] == ""): - course['assignments'] = aname + course['assignments'] = ass else: - course['assignments'] = course['assignments'] + "," + aname + course['assignments'] = course['assignments'].append(ass) cinfo = { - "name": course['name'], - "repo": "", - "path": course['path'], - "teacher": "eharris1", "assignments": course['assignments'], - "default_file": "", - "confirmed": course["confirmed"], - "unconfirmed": course['unconfirmed'] } - putDB(cinfo, "http://127.0.0.1:8000/api/classes/" + course['name'] + "/") + patchDB(cinfo, "http://127.0.0.1:8000/api/classes/" + course['name'] + "/") return True else: print("Assignment already addedd") @@ -510,18 +453,22 @@ class Teacher: #try to avoid #copy modified assignments to student directories def updateAssignment(self, path, course, due): + parts = path.split("/") + aname = parts[len(parts)-1] if(os.path.isdir(path) == False): print(path + " is not an assignment.") return try: if(due != None or due == ""): datetime.strptime(due, '%Y-%m-%d %H:%M:%S.%f') + d = { + 'due_date':due, + } + patchDB(d, 'http://localhost:8000/api/assignments/' + aname + "/") + print("Due-date changed " + due) except: - print("Due-date format is incorrect") - return + print("Due-date is the same") input() - parts = path.split("/") - aname = parts[len(parts)-1] course = getDB("http://127.0.0.1:8000/api/classes/" + course) slist = os.listdir(os.getcwd() + "/" + self.username + "/Students/" + course['name']) cdir = os.getcwd() @@ -654,12 +601,12 @@ class Teacher: data = getTeacher("eharris1") t = Teacher(data) -# t.makeClass("APLit_eharris1") -#t.addAssignment("eharris1/APLit_eharris1/Lab3_APLit_eharris1", "APLit_eharris1", '2020-08-11 16:58:33.383124') +#t.addClass("eharris1/APLit_eharris1") +#t.addAssignment("eharris1/APLit_eharris1/Essay1_eharris1", "APLit_eharris1", '2020-08-11 16:58:33.383124') #ar = ['2022rkhondak','2022inafi','2023rumareti'] #extra = t.reqAddStudentList(ar, "APLit_eharris1") #print(extra) -# t.getStudents('2022rkhondak') +t.reqStudent('2022rkhondak', 'APLit_eharris1') # t.getChanges('2022rkhondak','APLit_eharris1', 10) ''' diff --git a/Website/api/admin.py b/Website/api/admin.py index 8446cf4..5f8cd8c 100644 --- a/Website/api/admin.py +++ b/Website/api/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from .models import ( DefFiles, Assignment, - Classes, + Class, Teacher, Student ) @@ -13,4 +13,4 @@ admin.site.register(Teacher) admin.site.register(Student) admin.site.register(DefFiles) admin.site.register(Assignment) -admin.site.register(Classes) +admin.site.register(Class) diff --git a/Website/api/maker.py b/Website/api/maker.py index fb383ed..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( @@ -30,7 +34,7 @@ # # #################################### # -# from api.models import Assignment, Student, Classes, Teacher, DefFiles +# from api.models import Assignment, Student, Class, Teacher, DefFiles # from datetime import datetime # # f1 = DefFiles( @@ -76,8 +80,8 @@ # A3.files.add(f4) # A3.save() # -# #classes -# math = Classes( +# #Class +# math = Class( # name='Math5', # # ) @@ -86,7 +90,7 @@ # math.assignments.add(A2) # math.save() # -# english = Classes( +# english = Class( # name='English', # ) # english.save() @@ -104,8 +108,8 @@ # repo="https://github.com/therealraffi/2022rkhondak.git", # ) # raffu.save() -# raffu.classes.add(math) -# raffu.classes.add(english) +# raffu.Class.add(math) +# raffu.Class.add(english) # raffu.save() # # #teachers @@ -115,7 +119,7 @@ # ion_user="eharris1" # ) # ng.save() -# ng.classes.add(math) +# ng.Class.add(math) # ng.save() # # chao = Teacher( @@ -124,5 +128,5 @@ # ion_user="AKBailey" # ) # chao.save() -# chao.classes.add(english) +# chao.Class.add(english) # chao.save() diff --git a/Website/api/migrations/0001_initial.py b/Website/api/migrations/0001_initial.py deleted file mode 100644 index 96b239b..0000000 --- a/Website/api/migrations/0001_initial.py +++ /dev/null @@ -1,75 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 19:14 - -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='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=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('first_name', models.CharField(max_length=100)), - ('last_name', models.CharField(max_length=100)), - ('classes', models.CharField(blank=True, default='', max_length=100)), - ('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('git', models.CharField(max_length=100)), - ('email', models.CharField(blank=True, default='', max_length=100)), - ('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')), - ('website', models.CharField(blank=True, default='https://google.com', max_length=150)), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Classes', - fields=[ - ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('repo', models.URLField(blank=True, default='')), - ('path', models.CharField(default='', max_length=100)), - ('teacher', 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='')), - ('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_20200614_2034.py b/Website/api/migrations/0002_auto_20200614_2034.py deleted file mode 100644 index f6c6f87..0000000 --- a/Website/api/migrations/0002_auto_20200614_2034.py +++ /dev/null @@ -1,52 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-14 20:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='student', - name='website', - ), - migrations.AddField( - model_name='student', - name='added_to', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AddField( - model_name='student', - name='classes', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AddField( - model_name='student', - name='completed', - field=models.TextField(blank=True, default=''), - ), - migrations.AddField( - model_name='student', - name='git', - field=models.CharField(blank=True, default='https://github.com/', max_length=100), - ), - migrations.AddField( - model_name='student', - name='grade', - field=models.IntegerField(blank=True, default=9), - ), - migrations.AddField( - model_name='student', - name='repo', - field=models.URLField(blank=True, default=''), - ), - migrations.AddField( - model_name='student', - name='student_id', - field=models.IntegerField(blank=True, default=0), - ), - ] diff --git a/Website/api/migrations/0003_auto_20200614_2044.py b/Website/api/migrations/0003_auto_20200614_2044.py deleted file mode 100644 index d5a7a69..0000000 --- a/Website/api/migrations/0003_auto_20200614_2044.py +++ /dev/null @@ -1,43 +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 = [ - ('api', '0002_auto_20200614_2034'), - ] - - operations = [ - migrations.RemoveField( - model_name='student', - name='student_id', - ), - migrations.RemoveField( - model_name='teacher', - name='created', - ), - migrations.RemoveField( - model_name='teacher', - name='email', - ), - migrations.RemoveField( - model_name='teacher', - name='first_name', - ), - migrations.RemoveField( - model_name='teacher', - name='last_name', - ), - migrations.AlterField( - model_name='student', - name='git', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='student', - name='grade', - field=models.IntegerField(blank=True), - ), - ] diff --git a/Website/api/migrations/0004_auto_20200614_2107.py b/Website/api/migrations/0004_auto_20200614_2107.py deleted file mode 100644 index 75e2a7c..0000000 --- a/Website/api/migrations/0004_auto_20200614_2107.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 = [ - ('api', '0003_auto_20200614_2044'), - ] - - operations = [ - migrations.AlterField( - model_name='student', - name='grade', - field=models.IntegerField(blank=True, default=0), - ), - ] diff --git a/Website/api/models.py b/Website/api/models.py index e8bb2b3..d5b5aee 100644 --- a/Website/api/models.py +++ b/Website/api/models.py @@ -1,12 +1,24 @@ from django.db import models from django.contrib.auth.models import User +import secrets -class DefFiles(models.Model): - name=models.CharField(max_length=100) - path=models.CharField(max_length=100) - assignment=models.CharField(max_length=100, default="") - classes=models.CharField(max_length=100) - teacher=models.CharField(max_length=100) + + +class Student(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + ion_user = models.CharField(max_length=100, primary_key=True) + 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) + + def save(self, *args, **kwargs): + super(Student, self).save(*args, **kwargs) + + def __str__(self): + return f"{self.user.username}'s Profile" class Assignment(models.Model): owner = models.ForeignKey('auth.User', related_name='assignments', on_delete=models.CASCADE) @@ -21,44 +33,59 @@ class Assignment(models.Model): def __str__(self): return '%s' % (self.name) -class Classes(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE) - +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="") - teacher=models.CharField(max_length=100, default="") - assignments=models.TextField(default="", blank=True) + assignments=models.ManyToManyField(Assignment, blank=True) default_file=models.CharField(max_length=100, default="", blank=True) - confirmed=models.TextField(default="", blank=True) - unconfirmed=models.TextField(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(Classes, self).save(*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(Classes, default="") - classes=models.CharField(max_length=100, default="", blank=True) + 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) - git=models.CharField(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) - 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 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) - def save(self, *args, **kwargs): - super(Student, self).save(*args, **kwargs) - def __str__(self): - return f"{self.user.username}'s Profile" +class DefFiles(models.Model): + name=models.CharField(max_length=100) + path=models.CharField(max_length=100) + assignment=models.CharField(max_length=100, default="") + classes=models.CharField(max_length=100) + teacher=models.CharField(max_length=100) diff --git a/Website/api/permissions.py b/Website/api/permissions.py index 2d64429..7e0591c 100644 --- a/Website/api/permissions.py +++ b/Website/api/permissions.py @@ -13,7 +13,7 @@ class IsOwnerOrReadOnly(permissions.BasePermission): return True # Write permissions are only allowed to the owner of the snippet. - return obj.owner == request.user or request.user.is_superuser + return obj.user == request.user or request.user.is_superuser class isTeacher(permissions.BasePermission): #only teachers can make classes and assignmenst diff --git a/Website/api/serializers.py b/Website/api/serializers.py index 2a05750..40521ac 100644 --- a/Website/api/serializers.py +++ b/Website/api/serializers.py @@ -1,12 +1,12 @@ 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 class UserSerializer(serializers.HyperlinkedModelSerializer): - students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all()) - teachers = serializers.PrimaryKeyRelatedField(many=True, queryset=Teacher.objects.all()) + # students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all()) + # teachers = serializers.PrimaryKeyRelatedField(many=True, queryset=Teacher.objects.all()) class Meta: model = User @@ -15,41 +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' ,"teacher",'owner'] -class ClassesSerializer(serializers.HyperlinkedModelSerializer): +class ClassSerializer(serializers.ModelSerializer): # 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) - owner = serializers.ReadOnlyField(source='owner.username') +class StudentSerializer(serializers.ModelSerializer): + # 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 = ['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/urls.py b/Website/api/urls.py index f130d15..6434309 100644 --- a/Website/api/urls.py +++ b/Website/api/urls.py @@ -9,8 +9,8 @@ urlpatterns = [ path('teachers//', views.TeacherDetail.as_view()), path('assignments/', views.AssignmentList.as_view()), path('assignments//', views.AssignmentDetail.as_view()), - path('classes/', views.ClassesList.as_view()), - path('classes//', views.ClassesDetail.as_view()), + path('classes/', views.ClassList.as_view()), + path('classes//', views.ClassDetail.as_view()), ] -urlpatterns = format_suffix_patterns(urlpatterns) \ No newline at end of file +urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/Website/api/views.py b/Website/api/views.py index 3876c0a..fb95e11 100644 --- a/Website/api/views.py +++ b/Website/api/views.py @@ -1,5 +1,5 @@ -from .models import Student, Teacher, Classes, Assignment, DefFiles -from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, UserSerializer +from .models import Student, Teacher, Class, Assignment, DefFiles +from .serializers import StudentSerializer, TeacherSerializer, ClassSerializer, AssignmentSerializer, UserSerializer from rest_framework import generics, viewsets, permissions, response, status from django.http import Http404 from rest_framework.views import APIView @@ -8,13 +8,13 @@ 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): queryset = User.objects.all() serializer_class = UserSerializer - permission_classes = [permissions.IsAuthenticated] + permission_Class = [permissions.IsAuthenticated] class StudentViewSet(viewsets.ModelViewSet): @@ -23,10 +23,10 @@ class StudentViewSet(viewsets.ModelViewSet): """ queryset = Student.objects.all() serializer_class = StudentSerializer - permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] + 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): """ @@ -34,25 +34,25 @@ class TeacherViewSet(viewsets.ModelViewSet): """ queryset = Teacher.objects.all() serializer_class = TeacherSerializer - permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] + permission_Class = [permissions.IsAuthenticated, IsOwnerOrReadOnly] def perform_create(self, serializer): - serializer.save(owner=self.request.user) + serializer.save(user=self.request.user) -class ClassesViewSet(viewsets.ModelViewSet): +class ClassViewSet(viewsets.ModelViewSet): """ API endpoint that allows users to be viewed or edited. """ - queryset = Classes.objects.all() - serializer_class = ClassesSerializer - permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] + queryset = Class.objects.all() + 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): @@ -61,7 +61,7 @@ class AssignmentViewSet(viewsets.ModelViewSet): """ queryset = Assignment.objects.all() serializer_class = AssignmentSerializer - permission_classes = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly] + permission_Class = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly] def perform_create(self, serializer): if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser): @@ -76,4 +76,4 @@ class AssignmentViewSet(viewsets.ModelViewSet): # """ # queryset = DefFiles.objects.all() # serializer_class = DefFilesSerializer -# permissions_classes = [permissions.IsAuthenticatedOrReadOnly] +# permissions_Class = [permissions.IsAuthenticatedOrReadOnly] diff --git a/Website/config/urls.py b/Website/config/urls.py index 420beb6..297739c 100644 --- a/Website/config/urls.py +++ b/Website/config/urls.py @@ -9,7 +9,7 @@ router = routers.DefaultRouter() router.register(r'students', api_views.StudentViewSet) router.register(r'teachers', api_views.TeacherViewSet) router.register(r'assignments', api_views.AssignmentViewSet) -router.register(r'classes', api_views.ClassesViewSet) +router.register(r'classes', api_views.ClassViewSet) # router.register(r'files', api_views.DefFilesViewSet) router.register(r'users', api_views.UserViewSet) diff --git a/Website/skoolos/forms.py b/Website/skoolos/forms.py new file mode 100644 index 0000000..6374f97 --- /dev/null +++ b/Website/skoolos/forms.py @@ -0,0 +1,28 @@ +from django import forms +from django.contrib.auth.models import User +from api.models import Student, Teacher +import re + +class UserUpdateForm(forms.ModelForm): + + username = forms.CharField(max_length=50, disabled=True) + first_name = forms.CharField(max_length=50, disabled=True) + last_name = forms.CharField(max_length=50, disabled=True) + email = forms.EmailField() + + def __init__(self, *args, **kwargs): + super(UserUpdateForm, self).__init__(*args, **kwargs) + + class Meta: + model = User + fields = ['username','first_name','last_name','email'] + +class StudentUpdateForm(forms.ModelForm): + class Meta: + model = Student + fields = ['git'] + +class TeacherUpdateForm(forms.ModelForm): + class Meta: + model = Teacher + fields = ['git'] diff --git a/Website/skoolos/static/skoolos/styles.css b/Website/skoolos/static/skoolos/styles.css index 8eb8163..0f86d92 100644 --- a/Website/skoolos/static/skoolos/styles.css +++ b/Website/skoolos/static/skoolos/styles.css @@ -13,22 +13,20 @@ body { color: #333333; margin-top: 5rem; font-family: 'Segoe UI'; + margin-left: 2.5rem; + margin-right: 2.5rem; } h1, h2, h3, h4, h5, h6 { color: #444444; } -ul { - margin: 0; -} - .bg-steel { background: #3cba54; } .site-header .navbar-nav .nav-link { - color: #cbd5db; + color: #e1e1e1; } .site-header .navbar-nav .nav-link:hover { @@ -69,7 +67,8 @@ a.article-title:hover { .article-metadata { padding-bottom: 1px; margin-bottom: 4px; - border-bottom: 1px solid #e3e3e3 + border-bottom: 1px solid #e3e3e3; + font-size: 1.5em; } .article-metadata a:hover { @@ -93,8 +92,3 @@ a.article-title:hover { .account-heading { font-size: 2.5rem; } - -.nounderline { - text-decoration: none !important; - color: black !important; -} diff --git a/Website/skoolos/static/skoolos/tj_trans.png b/Website/skoolos/static/skoolos/tj_trans.png new file mode 100644 index 0000000..873c249 Binary files /dev/null and b/Website/skoolos/static/skoolos/tj_trans.png differ diff --git a/Website/skoolos/templates/skoolos/base.html b/Website/skoolos/templates/skoolos/base.html index ce0d628..2ec152d 100644 --- a/Website/skoolos/templates/skoolos/base.html +++ b/Website/skoolos/templates/skoolos/base.html @@ -21,8 +21,8 @@ + {% if messages %} + {% for message in messages %} +
+ {{ message }} + +
+ {% endfor %} + {% endif %} {% block content %}{% endblock %} diff --git a/Website/skoolos/templates/skoolos/class_detail.html b/Website/skoolos/templates/skoolos/class_detail.html new file mode 100644 index 0000000..e6c02c5 --- /dev/null +++ b/Website/skoolos/templates/skoolos/class_detail.html @@ -0,0 +1,28 @@ +{% extends "skoolos/base.html" %} +{% block content %} +
+
+

Assignments:

+
+ {% for assignment in assignments %} + + {% endfor %} +
+ +
+

{{ class.name }}

+

Teachers:

+
    + {% for teacher in teachers %} +
  • {{ teacher.user.first_name }} {{ teacher.user.last_name }} ({{teacher.ion_user}})
  • + {% endfor %} +
+
+
+ +{% endblock content %} diff --git a/Website/skoolos/templates/skoolos/home.html b/Website/skoolos/templates/skoolos/home.html index 05a211e..6822cb6 100644 --- a/Website/skoolos/templates/skoolos/home.html +++ b/Website/skoolos/templates/skoolos/home.html @@ -1,3 +1,15 @@ {% extends "skoolos/base.html" %} {% block content %} +
+ {% for class in classes %} + + {% endfor %} +
{% endblock content %} diff --git a/Website/skoolos/templates/skoolos/profile_student.html b/Website/skoolos/templates/skoolos/profile_student.html new file mode 100644 index 0000000..3da2f41 --- /dev/null +++ b/Website/skoolos/templates/skoolos/profile_student.html @@ -0,0 +1,34 @@ +{% extends "skoolos/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+ + {{ user.first_name }} {{ user.last_name }} +

+ {{ user.email }} + GitHub +

+
+
+ Classes +
    + {% for class in classes %} +
  • {{ class.name }}
  • + {% endfor %} +
+
+ {% csrf_token %} +
+ Your profile + {{ userForm|crispy}} + {{ profileForm|crispy }} +
+
+ +
+
+
+ +{% endblock content %} diff --git a/Website/skoolos/templates/skoolos/profile_teacher.html b/Website/skoolos/templates/skoolos/profile_teacher.html new file mode 100644 index 0000000..3da2f41 --- /dev/null +++ b/Website/skoolos/templates/skoolos/profile_teacher.html @@ -0,0 +1,34 @@ +{% extends "skoolos/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+ + {{ user.first_name }} {{ user.last_name }} +

+ {{ user.email }} + GitHub +

+
+
+ Classes +
    + {% for class in classes %} +
  • {{ class.name }}
  • + {% endfor %} +
+
+ {% csrf_token %} +
+ Your profile + {{ userForm|crispy}} + {{ profileForm|crispy }} +
+
+ +
+
+
+ +{% endblock content %} diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index a8ffe34..a028497 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/", views.classDetail, name="class"), ] diff --git a/Website/skoolos/views.py b/Website/skoolos/views.py index 3a3409b..c26311a 100644 --- a/Website/skoolos/views.py +++ b/Website/skoolos/views.py @@ -1,12 +1,119 @@ -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 django.contrib import messages + +from django.contrib.auth.models import User + +from .forms import UserUpdateForm, StudentUpdateForm, TeacherUpdateForm + +from api.models import Student, Teacher, Class, Assignment # Create your views here. @login_required() def home (request): + try: + student = Student.objects.get(user=request.user) + return render(request, "skoolos/home.html", {'classes': student.confirmed.all()}) + except Student.DoesNotExist: + pass + + try: + teacher = Teacher.objects.get(user=request.user) + return render(request, "skoolos/home.html", {'classes': teacher.classes.all()}) + except Teacher.DoesNotExist: + pass + return render(request, "skoolos/home.html") @login_required() def profile (request): pass + +@login_required() +def classDetail (request, id): + classObj = Class.objects.get(id=id) + + try: + student = Student.objects.get(user=request.user) + except Student.DoesNotExist: + pass + else: + if classObj.confirmed.filter(user=student.user).count() != 1: + return redirect('/') + else: + return render(request, "skoolos/class_detail.html", {'class': classObj,'assignments': classObj.assignments.all(), 'teachers': classObj.classes.all()}) + + try: + teacher = Teacher.objects.get(user=request.user) + return render(request, "skoolos/home.html", {'classes': teacher.classes.all()}) + except Teacher.DoesNotExist: + pass + else: + if classObj.confirmed.filter(user=student.user).count() != 1: + return redirect('/') + else: + return render(request, "skoolos/class_detail.html", {'class': classObj,'assignments': classObj.assignments.all(), 'teachers': classObj.classes.all()}) + + return redirect('/') + +@login_required() +def profile (request): + try: + student = Student.objects.get(user=request.user) + return student_profile(request) + except Student.DoesNotExist: + pass + + try: + teacher = Teacher.objects.get(user=request.user) + return teacher_profile(request) + except Teacher.DoesNotExist: + pass + + return redirect("/") + +def student_profile (request): + if request.method == "POST": + userForm = UserUpdateForm(request.POST, instance=request.user) + profileForm = StudentUpdateForm(request.POST, + instance=request.user.student) + if userForm.is_valid() and profileForm.is_valid(): + userForm.save() + profileForm.save() + messages.success(request, "Your account has been updated!") + return redirect('profile') + else: + userForm = UserUpdateForm(instance=request.user) + profileForm = StudentUpdateForm(instance=request.user.student) + + context = { + 'userForm': userForm, + 'profileForm': profileForm, + 'classes': request.user.student.confirmed.all() + } + + return render(request, 'skoolos/profile_student.html', context) + +def teacher_profile (request): + if request.method == "POST": + userForm = UserUpdateForm(request.POST, instance=request.user) + profileForm = TeacherUpdateForm(request.POST, + instance=request.user.student) + if userForm.is_valid() and profileForm.is_valid(): + userForm.save() + profileForm.save() + messages.success(request, "Your account has been updated!") + return redirect('profile') + else: + userForm = UserUpdateForm(instance=request.user) + profileForm = TeacherUpdateForm(instance=request.user.student) + + context = { + 'userForm': userForm, + 'profileForm': profileForm, + 'classes': request.user.teacher.classes.all() + } + + return render(request, 'skoolos/profile_teacher.html', context) 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/views.py b/Website/users/views.py index fa848da..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(user=user, git=git, grade=grade) + profile = Student(user=user, git=git, grade=grade, ion_user=username) else: - profile = Teacher(user=user, git=git) + 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}') @@ -145,4 +149,4 @@ def create_account (request): def logout(request): auth_logout(request) messages.success(request, "You've been logged out!") - return redirect(request, "/login") + return redirect("/login") diff --git a/Website/users/migrations/__init__.py b/bgservice/__init__.py similarity index 100% rename from Website/users/migrations/__init__.py rename to bgservice/__init__.py diff --git a/bgservice/bgservice.py b/bgservice/bgservice.py new file mode 100644 index 0000000..437cdda --- /dev/null +++ b/bgservice/bgservice.py @@ -0,0 +1,122 @@ +import time +import sys +import os +import pyinotify +import checker + + +class EventHandler(pyinotify.ProcessEvent): + _methods = [ + "IN_CREATE", + "IN_CLOSE_WRITE", + "IN_DELETE", + "IN_MOVED_TO", + "IN_MOVED_FROM", + "IN_OPEN", + ] + + def process_IN_CREATE(self, event): + description = \ + "Event: Created file\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + def process_IN_CLOSE_WRITE(self, event): + description = \ + "Event: Wrote to a file\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + def process_IN_DELETE(self, event): + description = \ + "Event: Deleted file\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + def process_IN_MOVED_TO(self, event): + description = \ + "Event: Moved a file in\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + def process_IN_MOVED_FROM(self, event): + description = \ + "Event: Moved a file out\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + def process_IN_OPEN(self, event): + description = \ + "Event: Opened file\n" \ + "Event Path: {}\n" \ + "Timestamp: {}\n".format( + event.pathname, + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + ) + print(description) + + +NOTIFIER = None +STDOUT = sys.stdout +DIR = None +START_TIME = None + + +def watch_dir(watched_dir="/tmp", logdir="/tmp/skooloslogs"): + global DIR + global START_TIME + global NOTIFIER + DIR = watched_dir + if not os.path.exists(logdir): + os.makedirs(logdir) + logfile = open( + logdir + "/skoolos_" + + time.strftime("%m%d%Y-%H%M%S", time.localtime()), 'w') + sys.stdout = logfile + START_TIME = time.time() + print("Start time: " + + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + "\n\n") + wm = pyinotify.WatchManager() + mask = pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_DELETE | \ + pyinotify.IN_MOVED_TO | pyinotify.IN_MOVED_FROM | pyinotify.IN_OPEN + NOTIFIER = pyinotify.ThreadedNotifier(wm, EventHandler()) + NOTIFIER.start() + wm.add_watch(watched_dir, mask, rec=True) + + +def stop_watching(): + NOTIFIER.stop() + now = time.time() + print("End time: " + + time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime())) + print("\nTotal work time: " + + time.strftime("%H:%M:%S", time.gmtime(now - START_TIME))) + suspicious_files = checker.file_check(DIR) + if suspicious_files != []: + print( + "\n\n--------------------------------------------------\n\n\n" + + "WARNING: One or more file did not have file extensions that are acceptable.\n" + + "The paths to these files are listed below:\n") + print(*suspicious_files, sep='\n') + sys.stdout = STDOUT + print("Done watching.\n") diff --git a/bgservice/checker.py b/bgservice/checker.py new file mode 100644 index 0000000..78afdae --- /dev/null +++ b/bgservice/checker.py @@ -0,0 +1,100 @@ +import os +from glob import glob + +file_whitelist = [ + # text and document files + ".doc", + ".docx", + ".odt", + ".pdf", + ".rtf", + ".tex", + ".txt", + ".wpd", + # video files + ".3g2", + ".3gp", + ".avi", + ".flv", + ".h264", + ".m4v", + ".mkv", + ".mov", + ".mp4", + ".mpg", + ".mpeg", + ".rm", + ".swf", + ".vob", + ".wmv", + # spreadsheet files + ".ods", + ".xls", + ".xlsm", + ".xlsx", + ".csv", + # programming files + ".c", + ".class", + ".cpp", + ".cs", + ".go", + ".h", + ".java", + ".pl", + ".sh", + ".swift", + ".vb", + # presentation files + ".key", + ".odp", + ".pps", + ".ppt", + ".pptx", + # image files + ".ai", + ".bmp", + ".gif", + ".ico", + ".jpeg", + ".jpg", + ".png", + ".ps", + ".psd", + ".svg", + ".tif", + ".tiff", +] + + +def shell_check(): + bash_history = [ + line.strip() + for line in open(os.path.expanduser("~/.bash_history"), 'r') + ] + zsh_history = [ + line.strip() for line in open(os.path.expanduser("~/.histfile"), 'r') + ] + report = "Suspicios commands found:\n" + for i in bash_history + zsh_history: + if "git" in i: + report += i + "\n" + if report != "Suspicios commands found:\n": + return report + return "Nothing suspicious found in bash or zsh history." + + +def verify_file(file_): + for ext in file_whitelist: + if file_[len(file_) - len(ext):] == ext: + return True + return False + + +def file_check(dir_): + files = glob(dir_ + "/**/*", recursive=True) + suspicious_files = [] + for file_ in files: + if not verify_file(file_): + suspicious_files.append(file_) + return suspicious_files diff --git a/eharris1/APLit_eharris1/Essay1_eharris1/instruct.txt b/eharris1/APLit_eharris1/Essay1_eharris1/instruct.txt new file mode 100644 index 0000000..e69de29 diff --git a/eharris1/APLit_eharris1/README.md b/eharris1/APLit_eharris1/README.md new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index 9a6e972..b4e22a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,27 +1,63 @@ +appdirs==1.4.3 +arandr==0.1.10 asgiref==3.2.7 +astroid==2.4.2 +CacheControl==0.12.6 certifi==2020.4.5.1 chardet==3.0.4 click==7.1.2 +colorama==0.4.3 +contextlib2==0.6.0 +distlib==0.3.0 +distro==1.4.0 Django==3.0.7 django-cors-middleware==1.5.0 django-crispy-forms==1.9.1 django-oauth-toolkit==1.3.2 djangorestframework==3.11.0 +greenlet==0.4.16 +html5lib==1.0.1 idna==2.9 +isort==4.3.21 +lazy-object-proxy==1.4.3 +mccabe==0.6.1 +meson==0.53.2 +msgpack==0.6.2 +numpy==1.18.5 oauthlib==3.1.0 +ordered-set==3.1.1 +packaging==20.1 +pep517==0.8.1 +Pillow==7.1.2 +progress==1.5 prompt-toolkit==1.0.14 +pulsemixer==1.5.0 +pycairo==1.19.1 pyclipper==1.1.0.post3 Pygments==2.6.1 +PyGObject==3.34.0 pyinotify==0.9.6 PyInquirer==1.0.3 +pylint==2.5.3 +pynvim==0.4.1 +pyparsing==2.4.6 pyperclip==1.8.0 +pytoml==0.1.21 pytz==2020.1 +pywal==3.3.0 regex==2020.5.14 requests==2.23.0 requests-oauthlib==1.3.0 +retrying==1.3.3 selenium==3.141.0 six==1.15.0 sqlparse==0.3.1 +team==1.0 +toml==0.10.0 urllib3==1.25.9 wcwidth==0.2.3 +webencodings==0.5.1 Werkzeug==1.0.1 +wpgtk==6.1.3 +wrapt==1.12.1 +yapf==0.30.0 diff --git a/skoolos.py b/skoolos.py index f95da87..501429e 100644 --- a/skoolos.py +++ b/skoolos.py @@ -12,8 +12,10 @@ from werkzeug.urls import url_decode import pprint from PyInquirer import prompt, print_json import json +import datetime import os import argparse +import webbrowser client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6' client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY' @@ -36,48 +38,123 @@ def main(): if not os.path.exists(".profile"): try: URL = "http://127.0.0.1:8000/api/" - r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1')) - print("End service at http://127.0.0.1:8000/ before continuing.") - sys.exit(0) + r = requests.get(url = URL) except: - pass + 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") + #webbrowser.open("http://127.0.0.1:8000/login", new=2) authenticate() else: - try: - URL = "http://127.0.0.1:8000/api/" - r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1')) - except: - print("Start Django server first") - sys.exit(0) f = open('.profile','r') data = json.loads(f.read()) f.close() PWD = data['password'] USER = data['username'] + print(data['username']) if(data['is_student']): - studentCLI() + studentCLI(USER, PWD) else: - teacherCLI() + teacherCLI(USER, PWD) # while True: # pass -def studentCLI(): +def studentCLI(user, password): from CLI import student - data = getStudent(USER) - print(data) + data = getUser(user, password) student = student.Student(data) - print(student) + carray = student.sclass.split(",") + if(len(carray) == 1 and carray[0] == ""): + print("No classes") + return + + carray.append("Exit SkoolOS") + courses = [ + { + 'type': 'list', + 'name': 'course', + 'choices':carray, + 'message': 'Select class: ', + }, + ] + course = prompt(courses) + if course == "Exit SkoolOS": + student.exitCLI() + else: + student.viewClass(course) + student.getAssignments(course, datetime.datetime.now()) -def teacherCLI(): - from CLI.teacher import Teacher - print("fail") +def teacherCLI(user, password): + from CLI import teacher + data = getUser(user, password) + teacher = teacher.Teacher(data) + # 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': 'course', + 'choices':carray, + 'message': 'Select class: ', + }, + ] + 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.") -def getStudent(ion_user): + else: + print("Class: " + cname) + options = ['1) Add student', "2) Add assignment", "3) View student information"] + questions = [ + { + 'type': 'list', + 'name': 'course', + 'choices':options, + 'message': 'Select option: ', + }, + ] + option = prompt(questions) + +def getUser(ion_user, password): URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/" - r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1')) + r = requests.get(url = URL, auth=(ion_user,password)) if(r.status_code == 200): data = r.json() return data @@ -90,6 +167,10 @@ def getStudent(ion_user): 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')) @@ -152,82 +233,97 @@ def authenticate(): path = os.path.join(os.getcwd(), 'chromedriver-mac') browser = webdriver.Chrome(path) - web_dir = os.path.join(os.getcwd(), 'CLI', 'oauth') - print(web_dir) - os.chdir(web_dir) - if os.path.exists("index.html"): - os.remove("index.html") + # web_dir = os.path.join(os.getcwd(), 'CLI', 'oauth') + # print(web_dir) + # os.chdir(web_dir) + # if os.path.exists("index.html"): + # os.remove("index.html") - template = open("template.html", "r") - index = open("index.html", "w") - for line in template: - index.write(line.replace('AUTH_URL', authorization_url)) - template.close() - index.close() + # template = open("template.html", "r") + # index = open("index.html", "w") + # for line in template: + # index.write(line.replace('AUTH_URL', authorization_url)) + # template.close() + # index.close() - server = Thread(target=create_server) - server.daemon = True - server.start() + # server = Thread(target=create_server) + # server.daemon = True + # server.start() - browser.get("localhost:8000/") + browser.get("localhost:8000/login") - while "http://localhost:8000/callback/?code" not in browser.current_url: + # while "http://localhost:8000/callback/?code" not in browser.current_url: + # time.sleep(0.25) + + url = browser.current_url + gets = url_decode(url.replace("http://localhost:8000/login/?", "")) + while "http://localhost:8000/login/?username=" not in browser.current_url and (not browser.current_url == "http://localhost:8000/"): #http://localhost:8000/ time.sleep(0.25) url = browser.current_url - gets = url_decode(url.replace("http://localhost:8000/callback/?", "")) - while "http://localhost:8000/callback/?code" not in browser.current_url: - time.sleep(0.25) - - url = browser.current_url - gets = url_decode(url.replace("http://localhost:8000/callback/?", "")) - code = gets.get("code") - if state == gets.get("state"): - state = gets.get("state") - print("states good") + gets = url_decode(url.replace("http://localhost:8000/login/?username=", "")) + # code = gets.get("code") + # if state == gets.get("state"): + # state = gets.get("state") + # print("states good") browser.quit() + questions = [ + { + 'type': 'input', + 'name': 'username', + 'message': 'Enter SkoolOS Username (Same as ION Username): ', + }, + { + 'type': 'password', + 'name': 'pwd', + 'message': 'Enter SkoolOS Password (NOT ION PASSWORD): ', + }, + ] + data =prompt(questions) + pwd = data['pwd'] + user = data['username'] + r = requests.get(url = "http://localhost:8000/api/", auth=(user,pwd)) + while(r.status_code != 200): + print("INCORRECT LOGIN CREDENTIALS") + r = requests.get(url = "http://localhost:8000/api/", auth=(user,pwd)) + data =prompt(questions) + pwd = data['pwd'] + user = data['username'] + print(r.status_code) + r = requests.get(url = "http://localhost:8000/api/students/" + user + "/", auth=(user,pwd)) + is_student = False + if(r.status_code == 200): + is_student = True + print("Welcome, student " + user) + r = requests.get(url = "http://localhost:8000/api/students/" + user + "/", auth=(user,pwd)) + profile = r.json() + username = profile['ion_user'] + grade = profile['grade'] + profile = { + 'username':username, + 'grade':grade, + 'is_student':is_student, + 'password':pwd, + } + profileFile = open(".profile", "w") + profileFile.write(json.dumps(profile)) + profileFile.close() - #print(code) - print(state) - - payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id, - 'client_secret': client_secret, 'csrfmiddlewaretoken': state} - token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json() - #print(token) - headers = {'Authorization': f"Bearer {token['access_token']}"} - - # And finally get the user's profile! - profile = requests.get("https://ion.tjhsst.edu/api/profile", headers=headers).json() - - #pprint.pprint(profile) - username = profile['ion_username'] - email = profile['tj_email'] - first_name = profile['first_name'] - last_name = profile['last_name'] - is_student = profile['is_student'] - password = "" - #password creation - - profile = { - 'username':username, - 'email':email, - 'first_name':first_name, - 'last_name':last_name, - 'is_student':is_student, - 'password':password, - } - os.chdir(cdir) - - profileFile = open(".profile", "w") - profileFile.write(json.dumps(profile)) - profileFile.close() - - #try to make password - password = makePass() - profile['password'] = password - profileFile = open(".profile", "w") - profileFile.write(json.dumps(profile)) - profileFile.close() + else: + print("Welcome, teacher " + user) + r = requests.get(url = "http://localhost:8000/api/teachers/" + user + "/", auth=(user,pwd)) + profile = r.json() + username = profile['ion_user'] + grade = profile['grade'] + profile = { + 'username':username, + 'grade':grade, + 'is_student':is_student, + 'password':pwd, + } + profileFile = open(".profile", "w") + profileFile.write(json.dumps(profile)) + profileFile.close() sys.exit diff --git a/snew.py b/snew.py new file mode 100644 index 0000000..b6437f8 --- /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.json())) +# 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()) + +