Merge branch 'development' of github.com:Rushilwiz/SkoolOS into development

This commit is contained in:
Nathaniel Kenschaft 2020-06-16 23:25:13 -04:00
commit b2c2d8fe20
12 changed files with 118 additions and 109 deletions

View File

@ -1 +1 @@
{"username": "eharris1", "is_student": false, "password": "hackgroup1"} {"username": "sstern1", "is_student": false, "password": "Riya2011"}

View File

@ -109,7 +109,7 @@ def command(command):
process = subprocess.Popen(ar, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process = subprocess.Popen(ar, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p = process.poll() p = process.poll()
output = process.communicate()[0] output = process.communicate()[0]
print(output.decode('utf-8')) # print(output.decode('utf-8'))
return output.decode('utf-8') return output.decode('utf-8')

View File

@ -133,7 +133,7 @@ def command(command):
process = subprocess.Popen(ar, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process = subprocess.Popen(ar, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p = process.poll() p = process.poll()
output = process.communicate()[1] output = process.communicate()[1]
print(output.decode('utf-8')) # print(output.decode('utf-8'))
#################################################################################################################################### ####################################################################################################################################

View File

@ -25,7 +25,7 @@ class Student(models.Model):
class Assignment(models.Model): class Assignment(models.Model):
owner = models.ForeignKey(User, null=True, blank=True, related_name='aowner', on_delete=models.CASCADE) owner = models.ForeignKey(User, null=True, blank=True, related_name='aowner', on_delete=models.CASCADE)
name=models.CharField(max_length=100, primary_key=True) name=models.CharField(max_length=100, primary_key=True)
due_date=models.DateTimeField() due_date=models.CharField(max_length=100, default="", blank=True)
# files = models.ManyToManyField(DefFiles) # files = models.ManyToManyField(DefFiles)
files=models.CharField(max_length=100, default="", blank=True) files=models.CharField(max_length=100, default="", blank=True)
path=models.CharField(max_length=100, default="", blank=True) path=models.CharField(max_length=100, default="", blank=True)

View File

@ -41,7 +41,7 @@ class StudentSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Student model = Student
# fields = ['url','first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','Class','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'] fields = ['url','grade', 'log', 'ion_user','git','user','classes','added_to','completed', 'repo']
class TeacherSerializer(serializers.ModelSerializer): class TeacherSerializer(serializers.ModelSerializer):
#classes = ClassSerializer(many=True, read_only=True,allow_null=True) #classes = ClassSerializer(many=True, read_only=True,allow_null=True)

View File

@ -114,3 +114,6 @@ OR::
? Add Students): 2) Add list of students through path ? Add Students): 2) Add list of students through path
File must be .txt and have 1 student username per line File must be .txt and have 1 student username per line
Relative Path: students.txt Relative Path: students.txt
Adding an assignment
-------

View File

@ -3,9 +3,11 @@ from urllib.parse import urlparse
import requests import requests
from requests_oauthlib import OAuth2Session from requests_oauthlib import OAuth2Session
from selenium import webdriver from selenium import webdriver
import os
import os.path import os.path
import time import time
import http.server import http.server
import shutil
import socketserver import socketserver
from threading import Thread from threading import Thread
from werkzeug.urls import url_decode from werkzeug.urls import url_decode
@ -16,6 +18,8 @@ import datetime
import os import os
import argparse import argparse
import webbrowser import webbrowser
from bgservice import bgservice as bg
import atexit
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6' client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY' client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
@ -47,9 +51,7 @@ def main():
URL = "http://127.0.0.1:8000/api/" URL = "http://127.0.0.1:8000/api/"
r = requests.get(url=URL) r = requests.get(url=URL)
except: except:
print( print("Run Django server on http://127.0.0.1:8000/ before continuing")
"Run Django server on http://127.0.0.1:8000/ before continuing"
)
sys.exit(0) sys.exit(0)
input("Welcome to SkoolOS. Press any key to create an account") input("Welcome to SkoolOS. Press any key to create an account")
@ -86,19 +88,42 @@ def main():
USER = data['username'] USER = data['username']
print(data['username']) print(data['username'])
if data['is_student']: if data['is_student']:
empty_logs()
bg.watch_dir()
studentCLI(USER, PWD) studentCLI(USER, PWD)
atexit.register(stop_bg_service)
else: else:
teacherCLI(USER, PWD) teacherCLI(USER, PWD)
#################################################################################################### STUDENT METHODS #################################################################################################### STUDENT METHODS
def stop_bg_service():
bg.stop_watching()
cur_path = os.path.dirname(__file__)
newpath = os.path.relpath('bgservice/SkoolOS/logs')
def empty_logs():
logs_folder = os.path.dirname(__file__) + 'bgservice/SkoolOS/logs/'
for filename in os.listdir(logs_folder):
file_path = os.path.join(folder, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (file_path, e))
def studentCLI(user, password): def studentCLI(user, password):
""" """
The CLI for students to access The CLI for students to access
param user: student username :param user: student username
param password: student password :param password: student password
""" """
from CLI import student from CLI import student
data = getUser(user, password, 'student') data = getUser(user, password, 'student')
@ -116,8 +141,8 @@ def studentCLI(user, password):
def chooseClassStudent(student): def chooseClassStudent(student):
""" """
Chooses a class for a student to view and work on Chooses a class for a student to view and work on
param student: a student :param student: a student
return: a course prompt :return: a course prompt
""" """
carray = student.sclass.split(",") carray = student.sclass.split(",")
if len(carray) == 1 and carray[0] == "": if len(carray) == 1 and carray[0] == "":
@ -142,13 +167,13 @@ def classOptionsStudent(student, course):
""" """
Allows students to choose what they want to do related to a class Allows students to choose what they want to do related to a class
The student can save, exit, or go back The student can save, exit, or go back
param student: a student :param student: a student
param course: a course :param course: a course
return: True if exiting, False if going back :return: True if exiting, False if going back
""" """
student.viewClass(course) student.viewClass(course)
student.getAssignments(course, 100) student.getAssignments(course, 100)
choices = ["Save", "Submit assignment", "Back", "Exit SkoolOS"] choices = ["Save","Submit assignment","Back","Exit SkoolOS"]
options = [ options = [
{ {
'type': 'list', 'type': 'list',
@ -170,30 +195,29 @@ def classOptionsStudent(student, course):
student.exitCLI() student.exitCLI()
# exit cli # exit cli
return True return True
if (option == "Submit assignment"): if(option == "Submit assignment"):
assignments = os.listdir(student.username) assignments = os.listdir(student.username)
tlist = [] tlist = []
b = True b = True
for a in assignments: for a in assignments:
oname = a + "_" + course oname = a + "_" + course
a = student.username + "/" + a a = student.username + "/" + a
if (os.path.isdir(a) and not "." in a if(os.path.isdir(a) and not "." in a and not oname in student.completed):
and not oname in student.completed):
tlist.append(a) tlist.append(a)
assignments = tlist assignments = tlist
assignments.append("Back") assignments.append("Back")
print(assignments) print(assignments)
options = [ options = [
{ {
'type': 'list', 'type': 'list',
'name': 'submit', 'name': 'submit',
'choices': assignments, 'choices':assignments,
'message': 'Select: ', 'message': 'Select: ',
}, },
] ]
ass = prompt(options)['submit'] ass = prompt(options)['submit']
if (ass == "Back"): if(ass == "Back"):
return False return False
else: else:
student.submit(course, ass) student.submit(course, ass)
@ -204,8 +228,8 @@ def classOptionsStudent(student, course):
def teacherCLI(user, password): def teacherCLI(user, password):
""" """
The CLI for teachers to access The CLI for teachers to access
param user: teachers username :param user: teachers username
param password: teachers password :param password: teachers password
""" """
from CLI import teacher from CLI import teacher
data = getUser(user, password, 'teacher') data = getUser(user, password, 'teacher')
@ -279,10 +303,7 @@ def makeClassTeacher(teacher):
cname = prompt(questions)['cname'] cname = prompt(questions)['cname']
teacher.makeClass(cname) teacher.makeClass(cname)
soption = [ soption = ["1) Add individual student", "2) Add list of students through path", "3) Exit"]
"1) Add individual student", "2) Add list of students through path",
"3) Exit"
]
questions = [ questions = [
{ {
'type': 'list', 'type': 'list',
@ -311,15 +332,10 @@ def makeClassTeacher(teacher):
def classOptionsTeacher(teacher, course): def classOptionsTeacher(teacher, course):
print("Class: " + course) print("Class: " + course)
unconf = getDB(teacher.username, teacher.password, unconf = getDB(teacher.username, teacher.password, "http://localhost:8000/api/classes/" + course)['unconfirmed']
"http://localhost:8000/api/classes/" +
course)['unconfirmed']
for s in unconf: for s in unconf:
teacher.addStudent(s, course) teacher.addStudent(s, course)
options = [ options = ['1) Request Student', "2) Add assignment", "3) View student information", "4) Exit"]
'1) Request Student', "2) Add assignment",
"3) View student information", "4) Exit"
]
questions = [ questions = [
{ {
'type': 'list', 'type': 'list',
@ -333,10 +349,7 @@ def classOptionsTeacher(teacher, course):
def addStudentsTeacher(teacher, course): def addStudentsTeacher(teacher, course):
soption = [ soption = ["1) Add individual student", "2) Add list of students through path", "3) Exit"]
"1) Add individual student", "2) Add list of students through path",
"3) Exit"
]
questions = [ questions = [
{ {
'type': 'list', 'type': 'list',
@ -381,8 +394,7 @@ def addStudentsTeacher(teacher, course):
def addAssignmentTeacher(teacher, course): def addAssignmentTeacher(teacher, course):
nlist = os.listdir(teacher.username + "/" + course) nlist = os.listdir(teacher.username + "/" + course)
alist = getDB(teacher.username, teacher.password, alist = getDB(teacher.username, teacher.password, "http://localhost:8000/api/classes/" + course)['assignments']
"http://localhost:8000/api/classes/" + course)['assignments']
print(nlist) print(nlist)
tlist = [] tlist = []
b = True b = True
@ -401,8 +413,8 @@ def addAssignmentTeacher(teacher, course):
nlist = tlist nlist = tlist
if len(nlist) == 0: if len(nlist) == 0:
print("No new assignments found") print("No new assignments found")
print("To make an assignment: make a subdirectory in the " + course + print(
" folder. Add a file within the new folder") "To make an assignment: make a subdirectory in the " + course + " folder. Add a file within the new folder")
return False return False
questions = [ questions = [
{ {
@ -432,8 +444,7 @@ def addAssignmentTeacher(teacher, course):
def viewStudentsTeacher(teacher, course): def viewStudentsTeacher(teacher, course):
data = getDB(teacher.username, teacher.password, data = getDB(teacher.username, teacher.password, "http://127.0.0.1:8000/api/classes/" + course)
"http://127.0.0.1:8000/api/classes/" + course)
students = data["confirmed"] students = data["confirmed"]
unconf = data['unconfirmed'] unconf = data['unconfirmed']
print("Students in class: ") print("Students in class: ")
@ -443,34 +454,37 @@ def viewStudentsTeacher(teacher, course):
for s in unconf: for s in unconf:
print(s) print(s)
student = input("View student (Enter student's ion username): ") student = input("View student (Enter student's ion username): ")
while ((not student in str(data['confirmed'])) while((not student in str(data['confirmed'])) and (not student in str(data['unconfirmed']))):
and (not student in str(data['unconfirmed']))):
print("Student not affiliated with class") print("Student not affiliated with class")
student = input("View student ('N' to exit): ") student = input("View student ('N' to exit): ")
if student == 'N': if student == 'N':
return False return False
sinfo = getDB(teacher.username, teacher.password, sinfo = getDB(teacher.username, teacher.password, "http://127.0.0.1:8000/api/students/" + student + "/")
"http://127.0.0.1:8000/api/students/" + student + "/")
pprint.pprint(sinfo) pprint.pprint(sinfo)
print("Confirmed: " + str(student in str(data['confirmed']))) print("Confirmed: " + str(student in str(data['confirmed'])))
if (student in str(data['confirmed'])): if(student in str(data['confirmed'])):
path = teacher.username + "/Students/" + course + "/" + student path = teacher.username + "/Students/" + course + "/" + student
print(student + "'s work: " + path) print(student + "'s work: " + path)
fin = sinfo['completed'].split(",") fin = sinfo['completed'].split(",")
alist = [] alist = []
for f in fin: for f in fin:
if (course in f): if(course in f):
late = teacher.afterSubmit(course, f, student) late = teacher.afterSubmit(course, f, student)
if (late): if(late):
s = f.split("_")[0] + " (LATE)" s = f.split("_")[0] + " (LATE)"
else: else:
s = f.split("_")[0] s = f.split("_")[0]
alist.append(s) alist.append(s)
print("Has submitted: " + str(alist)) print("Has submitted: " + str(alist))
#Y/N answer = None
while answer not in ("yes", "no"):
#put log stuff answer = input("Would you like to view the student's logs?: ")
if answer == "yes" or answer=="y":
print (sinfo['log'])
elif answer == "no" or answer=="n":
print("OK!")
else:
print("Please enter yes or no.")
############################################################################################################################################ ############################################################################################################################################
@ -478,10 +492,10 @@ def viewStudentsTeacher(teacher, course):
def getUser(ion_user, password, utype): def getUser(ion_user, password, utype):
""" """
Returns user information Returns user information
param ion_user: user :param ion_user: user
param password: user's password :param password: user's password
param utype: type of user (student or teacher :param utype: type of user (student or teacher
return: api user information :return: api user information
""" """
if 'student' in utype: if 'student' in utype:
URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/" URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/"
@ -508,11 +522,11 @@ def getUser(ion_user, password, utype):
def patchDB(USER, PWD, url, data): def patchDB(USER, PWD, url, data):
""" """
Sends a PATCH request to url Sends a PATCH request to url
param USER: username :param USER: username
param PWD: password :param PWD: password
param url: URL for request :param url: URL for request
param data: data to request :param data: data to request
return: json request response :return: json request response
""" """
r = requests.patch(url=url, data=data, auth=(USER, PWD)) r = requests.patch(url=url, data=data, auth=(USER, PWD))
print("PATH:" + str(r.status_code)) print("PATH:" + str(r.status_code))
@ -522,10 +536,10 @@ def patchDB(USER, PWD, url, data):
def getDB(USER, PWD, url): def getDB(USER, PWD, url):
""" """
Sends a GET request to url Sends a GET request to url
param USER: username :param USER: username
param PWD: password :param PWD: password
param url: URL for request :param url: URL for request
return: json request response :return: json request response
""" """
r = requests.get(url=url, auth=(USER, PWD)) r = requests.get(url=url, auth=(USER, PWD))
print("GET:" + str(r.status_code)) print("GET:" + str(r.status_code))
@ -535,11 +549,11 @@ def getDB(USER, PWD, url):
def postDB(USER, PWD, url, data): def postDB(USER, PWD, url, data):
""" """
Sends a POST request to url Sends a POST request to url
param USER: username :param USER: username
param PWD: password :param PWD: password
param url: URL for request :param url: URL for request
param data: data to request :param data: data to request
return: json request response :return: json request response
""" """
r = requests.post(url=url, data=data, auth=(USER, PWD)) r = requests.post(url=url, data=data, auth=(USER, PWD))
print("POST:" + str(r.status_code)) print("POST:" + str(r.status_code))
@ -549,11 +563,11 @@ def postDB(USER, PWD, url, data):
def putDB(USER, PWD, url, data): def putDB(USER, PWD, url, data):
""" """
Sends a PUT request to url Sends a PUT request to url
param USER: username :param USER: username
param PWD: password :param PWD: password
param url: URL for request :param url: URL for request
param data: data to request :param data: data to request
return: json request response :return: json request response
""" """
r = requests.put(url=url, data=data, auth=(USER, PWD)) r = requests.put(url=url, data=data, auth=(USER, PWD))
print("PUT:" + str(r.status_code)) print("PUT:" + str(r.status_code))
@ -563,10 +577,10 @@ def putDB(USER, PWD, url, data):
def delDB(USER, PWD, url): def delDB(USER, PWD, url):
""" """
Sends a DELETE request to url Sends a DELETE request to url
param USER: username :param USER: username
param PWD: password :param PWD: password
param url: URL for request :param url: URL for request
return: json request response :return: json request response
""" """
r = requests.delete(url=url, auth=(USER, PWD)) r = requests.delete(url=url, auth=(USER, PWD))
print("DELETE:" + str(r.status_code)) print("DELETE:" + str(r.status_code))
@ -576,7 +590,7 @@ def delDB(USER, PWD, url):
def makePass(): def makePass():
""" """
Prompts the user to create a password Prompts the user to create a password
return: the password :return: the password
""" """
questions = [ questions = [
{ {
@ -609,11 +623,8 @@ def authenticate():
""" """
Authenticates the user via Ion OAuth Authenticates the user via Ion OAuth
""" """
oauth = OAuth2Session(client_id=client_id, oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
redirect_uri=redirect_uri, authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
scope=scope)
authorization_url, state = oauth.authorization_url(
"https://ion.tjhsst.edu/oauth/authorize/")
import os import os
cdir = os.getcwd() cdir = os.getcwd()
# Linux: chromdriver-linux # Linux: chromdriver-linux
@ -624,12 +635,12 @@ def authenticate():
print("Linux") print("Linux")
system = input("Enter OS: ") system = input("Enter OS: ")
while (system.lower() != "linux" and system.lower() != "macos"): while(system.lower() != "linux" and system.lower() != "macos"):
print("Not valid OS") print("Not valid OS")
system = input("Enter OS: ") system = input("Enter OS: ")
if (system.lower() == 'macos'): if(system.lower() == 'macos'):
path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-mac') path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-mac')
if (system.lower() == 'linux'): if(system.lower() == 'linux'):
path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-linux') path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-linux')
browser = webdriver.Chrome(path) browser = webdriver.Chrome(path)
@ -642,13 +653,11 @@ def authenticate():
url = browser.current_url url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/login/?", "")) gets = url_decode(url.replace("http://localhost:8000/login/?", ""))
while "http://localhost:8000/login/?username=" not in browser.current_url and ( while "http://localhost:8000/login/?username=" not in browser.current_url and (
not browser.current_url not browser.current_url == "http://localhost:8000/"): # http://localhost:8000/
== "http://localhost:8000/"): # http://localhost:8000/
time.sleep(0.25) time.sleep(0.25)
url = browser.current_url url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/login/?username=", gets = url_decode(url.replace("http://localhost:8000/login/?username=", ""))
""))
# code = gets.get("code") # code = gets.get("code")
# if state == gets.get("state"): # if state == gets.get("state"):
# state = gets.get("state") # state = gets.get("state")
@ -677,15 +686,12 @@ def authenticate():
pwd = data['pwd'] pwd = data['pwd']
user = data['username'] user = data['username']
print(r.status_code) print(r.status_code)
r = requests.get(url="http://localhost:8000/api/students/" + user + "/", r = requests.get(url="http://localhost:8000/api/students/" + user + "/", auth=(user, pwd))
auth=(user, pwd))
is_student = False is_student = False
if r.status_code == 200: if r.status_code == 200:
is_student = True is_student = True
print("Welcome, student " + user) print("Welcome, student " + user)
r = requests.get(url="http://localhost:8000/api/students/" + user + r = requests.get(url="http://localhost:8000/api/students/" + user + "/", auth=(user, pwd))
"/",
auth=(user, pwd))
profile = r.json() profile = r.json()
username = profile['ion_user'] username = profile['ion_user']
grade = profile['grade'] grade = profile['grade']
@ -702,9 +708,7 @@ def authenticate():
else: else:
print("Welcome, teacher " + user) print("Welcome, teacher " + user)
r = requests.get(url="http://localhost:8000/api/teachers/" + user + r = requests.get(url="http://localhost:8000/api/teachers/" + user + "/", auth=(user, pwd))
"/",
auth=(user, pwd))
profile = r.json() profile = r.json()
username = profile['ion_user'] username = profile['ion_user']
profile = { profile = {

@ -0,0 +1 @@
Subproject commit 4df0d29276f82f25d75cd03e53ca5b754a10db1f

View File

View File

@ -0,0 +1 @@
its hailstone easy