Merge pull request #19 from Rushilwiz/development

Development
This commit is contained in:
Rushil Umaretiya 2020-06-16 21:49:39 -04:00 committed by GitHub
commit ee51f3d192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 167624 additions and 769 deletions

1
.2023rumaretiprofile Normal file
View File

@ -0,0 +1 @@
{"username": "2022rkhondak", "grade": 9, "is_student": true, "password": "hackgroup1"}

1
.rushilwizprofile Normal file
View File

@ -0,0 +1 @@
{"username": "rushilwiz", "grade": 69, "is_student": true, "password": "a"}

View File

@ -1 +0,0 @@
{"username": "2022rkhondak", "grade": 10, "is_student": true, "password": "hackgroup1"}

1
2023rumareti Submodule

@ -0,0 +1 @@
Subproject commit ca356ef8532873bf52ec67a647fbb91a25ca1cb7

View File

@ -9,12 +9,13 @@ import time
import pyperclip
import datetime
# git clone student directory ==> <student-id>/classes/assignments
# get teacher info from api
def getStudent(ion_user):
def getStudent(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
@ -28,31 +29,78 @@ def getStudent(ion_user):
return None
print(r.status_code)
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
#makes a GET request to given url, returns dict
def getDB(user, pwd, url):
"""
Sends a GET request to url
:param user: username
:param pwd: password
:param url: URL for request
:return: json request response
"""
r = requests.get(url=url, auth=(user, pwd))
print("GET:" + str(r.status_code))
return(r.json())
def postDB(data, url):
r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
#makes a PATCH (updates instance) request to given url, returns dict
def patchDB(user, pwd, data, url):
"""
Sends a PATCH request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.patch(url=url, data=data, auth=(user, pwd))
print("PATCH:" + str(r.status_code))
return r.json()
#makes a POST (makes new instance) request to given url, returns dict
def postDB(user, pwd, data, url):
"""
Sends a POST request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.post(url=url, data=data, auth=(user, pwd))
print("POST:" + str(r.status_code))
return(r.json())
return r.json()
def putDB(data, url):
r = requests.put(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
#makes a PUT (overwrites instance) request to given url, returns dict
def putDB(user, pwd, data, url):
"""
Sends a PUT request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.put(url=url, data=data, auth=(user, pwd))
print("PUT:" + str(r.status_code))
return(r.json())
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'))
#makes a DELETE (delete instance) request to given url, returns dict
def delDB(user, pwd, url):
"""
Sends a DELETE request to url
:param user: username
:param pwd: password
:param url: URL for request
:return: json request response
"""
r = requests.delete(url=url, auth=(user, pwd))
print("DELETE:" + str(r.status_code))
return None
def command(command):
ar = []
command = command.split(" ")
@ -64,11 +112,12 @@ def command(command):
print(output.decode('utf-8'))
return output.decode('utf-8')
####################################################################################################################################
# public methods: deleteClass, makeClass, update
class Student:
def __init__(self, data):
def __init__(self, data, password):
# teacher info already stored in API
# intitialze fields after GET request
self.git = data['git']
@ -77,6 +126,8 @@ class Student:
self.grade = data['grade']
self.completed = data['completed']
self.user = data['user']
self.password = password
self.completed = data['completed']
# classes in id form (Example: 4,5)
# storing actual classes
cid = data['classes'].split(",")
@ -91,7 +142,7 @@ class Student:
classes = []
for c in cid:
url = "http://127.0.0.1:8000/api/classes/" + str(c) + "/"
classes.append(getDB(url))
classes.append(getDB(self.username, self.password,url))
self.classes = classes
self.sclass = str(data['classes'])
@ -109,7 +160,7 @@ class Student:
nclasses = []
for c in nid:
url = "http://127.0.0.1:8000/api/classes/" + str(c) + "/"
nclasses.append(getDB(url))
nclasses.append(getDB(self.username, self.password,url))
self.new = nclasses
self.snew = str(data['added_to'])
@ -136,7 +187,7 @@ class Student:
data = {
'repo': self.repo
}
print(patchDB(data, self.url))
print(patchDB(self.username, self.password,data, self.url))
print("Synced to " + self.username)
def getClasses(self):
@ -151,7 +202,7 @@ class Student:
print(c['name'])
alist = c['assignments']
for a in alist:
ass = getDB("http://127.0.0.1:8000/api/assignments/" + a)
ass = getDB(self.username, self.password,"http://127.0.0.1:8000/api/assignments/" + a)
now = datetime.datetime.now()
try:
due = ass['due_date'].replace("T", " ").replace("Z", "")
@ -173,7 +224,7 @@ class Student:
command("git checkout master")
for c in self.classes:
print("UPDATING CLASS: " + str(c['name']))
data = getDB("http://127.0.0.1:8000/api/classes/" + str(c['name']))
data = getDB(self.username, self.password,"http://127.0.0.1:8000/api/classes/" + str(c['name']))
# command("git checkout master")
command("git checkout " + data['name'])
command("git add .")
@ -206,7 +257,7 @@ class Student:
# add classes from 'new' field
def addClass(self, cid):
data = getDB('http://127.0.0.1:8000/api/classes/'+ str(cid))
data = getDB(self.username, self.password,'http://127.0.0.1:8000/api/classes/' + str(cid))
if ((cid in self.snew) == False or (self.username in data['confirmed'])):
print("Already enrolled in this class.")
return None
@ -217,23 +268,24 @@ class Student:
# add class teacher as cocllaborator to student repo
print(os.getcwd())
pwd = input("Enter Github password: ")
tgit = getDB("http://127.0.0.1:8000/api/teachers/" + data['teacher'] + "/")['git']
tgit = getDB(self.username, self.password,"http://127.0.0.1:8000/api/teachers/" + data['teacher'] + "/")['git']
url = "curl -i -u " + self.git + ":" + pwd + " -X PUT -d '' " + "'https://api.github.com/repos/" + self.git + "/" + self.username + "/collaborators/" + tgit + "'"
print(url)
os.system(url)
cdir = os.getcwd()
path1 = self.username + "/" + self.username
path2 = self.username
if(os.path.isdir(path1)):
os.chdir(path1)
else:
os.chdir(self.username)
command("git clone " + self.repo)
os.chdir(self.username)
# path1 = self.username + "/" + self.username
# path2 = self.username
# if(os.path.isdir(path1)):
# os.chdir(path1)
# else:
# os.chdir(self.username)
# command("git clone " + self.repo)
# os.chdir(self.username)
# push to git, start at master
os.chdir(self.username)
#os.chdir(self.username)
command("git checkout master")
command("git branch " + data['name'])
command("git commit -m initial")
@ -269,7 +321,7 @@ class Student:
# recreate sclass field, using ids
for c in self.new:
snew = snew + str(c['name']) + ","
new.append(getDB("http://127.0.0.1:8000/api/classes/" + str(cid)))
new.append(getDB(self.username, self.password,"http://127.0.0.1:8000/api/classes/" + str(cid)))
self.snew = snew
self.new = new
break
@ -281,7 +333,7 @@ class Student:
'classes': self.sclass
}
print(self.url)
print(patchDB(data, self.url))
print(patchDB(self.username, self.password,data, self.url))
return data
def submit(self, path):
@ -331,7 +383,8 @@ class Student:
if c['name'] == courses:
command("git checkout " + courses)
print(os.listdir())
break
os.chdir(cdir)
return
os.chdir(cdir)
print("Class not found")
return
@ -348,12 +401,13 @@ class Student:
command("git add .")
command("git commit -m update")
command('git checkout ' + course)
time.sleep(5)
ass = os.listdir()
oname = ''
inclass = False
for a in ass:
if a == assignment:
if a in assignment:
inclass = True
oname = a + "_" + course
break
if (inclass == False):
print(assignment + " not an assignment of " + course)
@ -367,10 +421,16 @@ class Student:
command("git tag " + assignment + "-final")
command("git push -u origin " + course + " --tags")
command('git checkout master')
self.completed = assignment + "," + self.completed
data = {
'completed': self.completed
}
patchDB(self.username, self.password, data, self.url)
os.chdir(cdir)
# data = getStudent("2022rkhondak")
# s = Student(data)
#data = getStudent("2022rkhondak", "PWD")
#s = Student(data, "PWD")
# s.viewClass("APLit_eharris1")
# #s.addClass("APLit_eharris1")
# # #s.update()
@ -379,6 +439,7 @@ class Student:
def main():
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()

View File

@ -9,6 +9,8 @@ import time
import pyperclip
from distutils.dir_util import copy_tree
from datetime import datetime
# from django.conf import settings
# import django
@ -24,47 +26,106 @@ from datetime import datetime
# git clone student directory ==> <student-id>/classes/assignments
# get teacher info from api
def getTeacher(ion_user):
def getTeacher(ion_user, password):
"""
Gets information about a teacher from the api
:param ion_user: a teacher
:param password: the teacher's password
:return: teacher information or error
"""
URL = "http://127.0.0.1:8000/api/teachers/" + ion_user + "/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
if(r.status_code == 200):
r = requests.get(url=URL, auth=(ion_user,password))
print(r.json())
if r.status_code == 200:
data = r.json()
return data
elif(r.status_code == 404):
elif r.status_code == 404:
return None
print("Make new account!")
elif(r.status_code == 403):
elif r.status_code == 403:
return None
print("Invalid username/password")
else:
return None
print(r.status_code)
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
#makes a GET request to given url, returns dict
def getDB(user, pwd, url):
"""
Sends a GET request to url
:param user: username
:param pwd: password
:param url: URL for request
:return: json request response
"""
r = requests.get(url=url, auth=(user, pwd))
print("GET:" + str(r.status_code))
return(r.json())
def patchDB(data, url):
r = requests.patch(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
#makes a PATCH (updates instance) request to given url, returns dict
def patchDB(user, pwd, data, url):
"""
Sends a PATCH request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.patch(url=url, data=data, auth=(user, pwd))
print("PATCH:" + str(r.status_code))
return(r.json())
return r.json()
def postDB(data, url):
r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
#makes a POST (makes new instance) request to given url, returns dict
def postDB(user, pwd, data, url):
"""
Sends a POST request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.post(url=url, data=data, auth=(user, pwd))
print("POST:" + str(r.status_code))
return(r.json())
return r.json()
def putDB(data, url):
r = requests.put(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
#makes a PUT (overwrites instance) request to given url, returns dict
def putDB(user, pwd, data, url):
"""
Sends a PUT request to url
:param user: username
:param pwd: password
:param url: URL for request
:param data: data to request
:return: json request response
"""
r = requests.put(url=url, data=data, auth=(user, pwd))
print("PUT:" + str(r.status_code))
return(r.json())
return r.json()
def delDB(url):
r = requests.delete(url = url, auth=('raffukhondaker','hackgroup1'))
#makes a DELETE (delete instance) request to given url, returns dict
def delDB(user, pwd, url):
"""
Sends a DELETE request to url
:param user: username
:param pwd: password
:param url: URL for request
:return: json request response
"""
r = requests.delete(url=url, auth=(user, pwd))
print("DELETE:" + str(r.status_code))
return None
def command(command):
"""
Runs a shell command
:param command: shell command
"""
ar = []
command = command.split(" ")
for c in command:
@ -74,42 +135,59 @@ def command(command):
output = process.communicate()[1]
print(output.decode('utf-8'))
####################################################################################################################################
# public methods: deleteClass, makeClass, update
class Teacher:
def __init__(self, data):
def __init__(self, data, password):
# teacher info already stored in API
# intitialze fields after GET request
"""
Initializes a Teacher with the data from the api
:param data: api data
"""
self.git = data['git']
self.username = data['ion_user']
self.url = "http://127.0.0.1:8000/api/teachers/" + self.username + "/"
self.id = data['user']
self.password = password
# classes in id form (Example: 4,5)
# array
self.classes = data['classes']
if(os.path.isdir(self.username + "/Students")):
if os.path.isdir(self.username + "/Students"):
print("Synced to " + self.username)
existing_classes = os.listdir(self.username)
for c in self.classes:
if not c in str(existing_classes):
os.mkdir(self.username + "/" + c)
print("Updated: " + c)
command("touch " + self.username + "/" + c + "/README.md")
os.makedirs(self.username + "/Students/" + c)
else:
os.makedirs(self.username + "/Students")
# 2020-05-11 12:25:00
# class name format: <course-name>_<ion_user>
# turn existing directory into class, Pre-condition: directory exists
# relative path to class: 2022rkhondak/Math4
def checkClass(self, path):
"""
Checks if a directory is valid for creating a class
:param path: path to the new class directory
"""
cname = path.split("/")
cname = cname[len(cname) - 1]
if(os.path.isfile(path)):
if os.path.isfile(path):
print(path + " must be in a Class directory.")
return False
if(("_" + self.username) in cname) == False:
print("Incorrect class name: Must be in the format: " + self.username+ "/<course-name>_<ion_user>, not " + path)
if not (("_" + self.username) in cname):
print(
"Incorrect class name: Must be in the format: " + self.username + "/<course-name>_<ion_user>, not " + path)
return False
dirs = os.listdir(path)
# checks if there is a file (not within Assignments) in class, need at least 1
@ -119,88 +197,109 @@ class Teacher:
as_bad = ""
for d in dirs:
if(os.path.isfile(d)):
if os.path.isfile(d):
deffile = True
else:
# checks if there is a file in an Assignment, need at least 1
as_file = False
asdir = os.listdir(path + "/" + d)
for a in asdir:
if(os.path.isfile(path + "/" + d + "/" +a)):
if os.path.isfile(path + "/" + d + "/" + a):
as_file = True
if(as_file==False):
if not as_file:
as_bad = d
break
if(as_file==False):
if not as_file:
print("Assignment '" + as_bad + "' does not have a default file!")
return False
if(deffile==False):
if not deffile:
print("Need a default file in the " + path + " Directory!")
return False
return True
def checkInDB(self, path):
"""
Checks if "path" is in the database
:param path: path to directory
"""
n = path.split("/")
n = n[len(n) - 1]
for c in self.classes:
if(n == c['name']):
if n == c['name']:
return True
return False
# make class from existing directory, add to git and api
def addClass(self, path):
"""
Creates a class from an existing directory, adding it to the proper git repository and the api
:param 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)):
if self.checkClass(path):
cpath = self.username + "/" + cname
subject = cname.split("_")[0]
period = int(input("Enter period: "))
while(not (type(period) is int and period >= 0)):
print("Incorrect format")
period = int(input("Enter period: "))
data = {
"name": cname,
"repo": "",
"path": cpath,
"subject": subject,
"period":period,
"teacher": self.username,
"owner": self.id
}
# make class instance in db
postDB(data, 'http://127.0.0.1:8000/api/classes/')
postDB(self.username, self.password, data, 'http://127.0.0.1:8000/api/classes/')
time.sleep(1)
self.classes.append(cname)
# add to instance
#upate self.classes
# update self.classes
data = {
'classes': self.classes
}
print(self.username)
print(patchDB(data, 'http://127.0.0.1:8000/api/teachers/' + self.username + "/"))
print(self.classes)
print(patchDB(self.username, self.password, data, 'http://127.0.0.1:8000/api/teachers/' + self.username + "/"))
# make a new class from scratch
# subject: string, assignments: list
# class name must be: <subject>_<ion_user>
def makeClass(self, cname):
"""
Makes a class with its own new directory
:param cname: name of class
"""
# check if class exists
path = self.username + "/" + cname
isclass = False
acourses = getDB("http://127.0.0.1:8000/api/classes/")['results']
acourses = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/")['results']
for c in acourses:
if c['name'] == cname:
isclass = True
break
if(os.path.exists(path) or isclass):
if os.path.exists(path) or isclass:
print("Class already exists: " + cname)
if(isclass):
if isclass:
print("Class already exists in Database")
return
else:
if((("_" + self.username) in cname) == False):
if not (("_" + self.username) in cname):
print("class name must be: " + cname + "_" + self.username)
return
cdir = os.getcwd()
os.mkdir(path)
f = open(path + "/README.md", "w")
f.close()
os.makedirs(self.username + "/Students/" + cname)
# push to remote repo
# os.chdir(path)
# for a in assignments:
@ -213,10 +312,14 @@ class Teacher:
self.addClass(path)
def deleteClass(self, path):
if(os.path.exists(path) == False):
"""
Deletes an existing class
:param path: class directory path
"""
if not os.path.exists(path):
print(path + " does not exist locally.")
resp = input("Do you want to delete " + path + " from the SkoolOS system? (y/N) ")
if(resp != 'y'):
if resp != 'y':
return
cname = path.split("/")
@ -225,13 +328,13 @@ class Teacher:
print("DELETE: " + self.classes[i]['name'])
for i in range(len(self.classes)):
c = self.classes[i]
if(c == cname):
if c == cname:
del self.classes[i]
# data={
# 'classes':self.classes,
# }
# print(patchDB(data, self.url))
delDB("http://127.0.0.1:8000/api/classes/" + cname + "/")
delDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + cname + "/")
break
# remove locally
@ -242,28 +345,39 @@ class Teacher:
# remove from student directories
def isStudent(self, student):
r = requests.get(url = "http://127.0.0.1:8000/api/students/" + student + "/", auth=('raffukhondaker','hackgroup1'))
if(r.status_code != 200):
"""
Checks if the student exists
:param student: a student
:return: True if student exists, False otherwise
"""
r = requests.get(url="http://127.0.0.1:8000/api/students/" + student + "/",
auth=(self.username, self.password))
if r.status_code != 200:
return False
return True
def reqStudent(self, sname, cname):
if(self.isStudent(sname) == False):
"""
Request student informatiion from the api
:param sname: student's name
:param cname: class name
:return: True if successful
"""
if not self.isStudent(sname):
print(sname + " does not exist.")
return False
course = getDB("http://127.0.0.1:8000/api/classes/" + cname)
if(sname in str(course['unconfirmed'])):
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + cname)
if sname in str(course['unconfirmed']):
print(sname + " already requested.")
return True
if(sname in str(course['confirmed'])):
print (sname + " alredy enrolled.")
if sname in str(course['confirmed']):
print(sname + " already enrolled.")
return False
student = getDB("http://127.0.0.1:8000/api/students/" + sname)
student = getDB(self.username, self.password, "http://127.0.0.1:8000/api/students/" + sname)
try:
if(student['added_to']==""):
if student['added_to'] == "":
student['added_to'] = course['name']
else:
student['added_to'] = student['added_to'] + "," + course['name']
@ -274,9 +388,9 @@ class Teacher:
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']==[]):
student = patchDB(self.username, self.password, data, "http://localhost:8000/api/students/" + student['ion_user'] + "/")
student = getDB(self.username, self.password, "http://localhost:8000/api/students/" + sname + "/")
if not course['unconfirmed']:
course['unconfirmed'] = student['ion_user']
else:
course['unconfirmed'] = course['unconfirmed'].append(student['ion_user'])
@ -284,26 +398,33 @@ class Teacher:
"unconfirmed": course['unconfirmed']
}
print(cinfo)
patchDB(cinfo, "http://localhost:8000/api/classes/" + course['name'] + "/")
patchDB(self.username, self.password, cinfo, "http://localhost:8000/api/classes/" + course['name'] + "/")
return True
# Student should have confirmed on their endd, but class had not been updated yet
# git clone confirmed student repo, copy files into repo and push branch
def addStudent(self, sname, cname):
if(self.isStudent(sname) == False):
"""
Adds a student to a class
:param sname: student name
:param cname: class name
:return:
"""
if not self.isStudent(sname):
print(sname + " does not exist.")
return False
student = getDB("http://127.0.0.1:8000/api/students/" + sname)
course = getDB("http://127.0.0.1:8000/api/classes/" + cname)
student = getDB(self.username, self.password, "http://127.0.0.1:8000/api/students/" + sname)
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + cname)
if(os.path.exists(self.username + "/Students/" + cname + "/" + student['ion_user']) or (student['ion_user'] in course['confirmed']) == True):
if (os.path.exists(self.username + "/Students/" + cname + "/" + student['ion_user']) or (
student['ion_user'] in course['confirmed']) == True):
print(student['ion_user'] + " already added to class")
return True
if((cname in student['added_to']) == True or (cname in student['classes']) == False):
if (cname in student['added_to']) or not (cname in student['classes']):
print(student['ion_user'] + " has not confirmed class yet")
return False
if((student['ion_user'] in course['unconfirmed']) == False):
if not (student['ion_user'] in course['unconfirmed']):
print(course['unconfirmed'])
print(student['ion_user'] + " has not been requested to join yet.")
return False
@ -313,9 +434,9 @@ class Teacher:
cpath = self.username + "/" + cname
path = self.username + "/Students/" + cname
spath = self.username + "/Students/" + cname + "/" + student['ion_user']
if(os.path.isdir(path) == False):
if not os.path.isdir(path):
os.makedirs(path)
if(os.path.isdir(spath) == False):
if not os.path.isdir(spath):
os.chdir(path)
command("git clone " + student['repo'])
os.chdir(cdir)
@ -332,13 +453,13 @@ class Teacher:
command('git push -u origin ' + cname)
os.chdir(cdir)
if(course['confirmed']==[]):
if not course['confirmed']:
course['confirmed'] = student['ion_user']
else:
course['confirmed'].append(student['ion_user'])
# only 1 pereson on confirmeed
if(len(course['unconfirmed']) == 1):
if len(course['unconfirmed']) == 1:
course['unconfirmed'] = []
# mutiple
else:
@ -348,21 +469,34 @@ class Teacher:
"confirmed": course["confirmed"],
"unconfirmed": course['unconfirmed']
}
print(putDB(course, "http://localhost:8000/api/classes/" + course['name'] + "/"))
print(putDB(self.username, self.password, course, "http://localhost:8000/api/classes/" + course['name'] + "/"))
return True
# goes through list of studennts, tries to add, then request, return unconfirmed students
def reqAddStudentList(self, array, cname):
"""
Runs addStudent() on all students in array
:param array: an array of students
:param cname: class name
:return: students that have not confirmed the request
"""
unconf = []
for i in range(len(array)):
a = array[i]
if(self.addStudent(a, cname) == False):
if not self.addStudent(a, cname):
self.reqStudent(a, cname)
unconf.append(a)
return unconf
# add local path to student directory, make new instance in api
def addAssignment(self, path, course, due):
"""
Creates an assignment for "course" that is due on "due"
:param path: directory of assignment
:param course: course name
:param due: due date
:return: False if unsuccessful
"""
parts = path.split("/")
aname = parts[len(parts) - 1]
oname = aname + "_" + course
@ -370,7 +504,7 @@ class Teacher:
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 str(self.classes)) == False):
if not (parts[1] in str(self.classes)):
print("Not in valid class directory")
return False
# parts of assignment name (Essay1, APLit)
@ -394,15 +528,15 @@ class Teacher:
print("Due-date format is incorrect")
return False
course = getDB("http://127.0.0.1:8000/api/classes/" + course)
if(aname in str(course['assignments'])):
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + course)
if aname in str(course['assignments']):
print("Assignment name already taken.")
return False
print(course['assignments'])
print(aname)
#################### FINISH VERIFYING
if(os.path.exists(os.getcwd() + "/" + self.username + "/Students/" + course['name']) == False):
if not os.path.exists(os.getcwd() + "/" + self.username + "/Students/" + course['name']):
print("No students in this class yet")
return True
slist = os.listdir(os.getcwd() + "/" + self.username + "/Students/" + course['name'])
@ -410,7 +544,7 @@ class Teacher:
for st in slist:
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):
if not os.path.exists(spath + "/" + aname):
os.mkdir(spath + "/" + aname)
print(st)
print(copy_tree(path, spath + "/" + aname))
@ -425,22 +559,23 @@ class Teacher:
print(st + " already has assignment")
# check if assignment already exists
r = requests.get(url = 'http://127.0.0.1:8000/api/assignments/' + aname, auth=('raffukhondaker','hackgroup1'))
if(r.status_code != 200):
r = requests.get(url='http://127.0.0.1:8000/api/assignments/' + aname, auth=(self.username, self.password))
if r.status_code != 200:
ass = {
'name': oname,
'path': path,
'classes': course['name'],
'teacher': self.username,
'due_date':due
'due_date': due,
'owner':self.id
}
postDB(ass, 'http://127.0.0.1:8000/api/assignments/')
postDB(self.username, self.password, ass, 'http://127.0.0.1:8000/api/assignments/')
course['assignments'].append(oname)
cinfo = {
"assignments": course['assignments'],
}
print(patchDB(cinfo, "http://127.0.0.1:8000/api/classes/" + course['name'] + "/"))
print(patchDB(self.username, self.password, cinfo, "http://127.0.0.1:8000/api/classes/" + course['name'] + "/"))
return True
else:
print("Assignment already addedd")
@ -452,21 +587,21 @@ class Teacher:
parts = path.split("/")
aname = parts[len(parts) - 1]
oname = aname + "_" + course
if(os.path.isdir(path) == False):
if not os.path.isdir(path):
print(path + " is not an assignment.")
return
try:
if(due != None or due == ""):
if due != None or due == "":
datetime.strptime(due, '%Y-%m-%d %H:%M:%S.%f')
d = {
'due_date': due,
}
print(patchDB(d, 'http://localhost:8000/api/assignments/' + oname + "/"))
print(patchDB(self.username, self.password, d, 'http://localhost:8000/api/assignments/' + oname + "/"))
print("Due-date changed " + due)
except:
print("Due-date is the same")
input()
course = getDB("http://127.0.0.1:8000/api/classes/" + course)
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + course)
slist = os.listdir(os.getcwd() + "/" + self.username + "/Students/" + course['name'])
cdir = os.getcwd()
for st in slist:
@ -484,7 +619,7 @@ class Teacher:
# pull student's work, no modifications
def getStudents(self, course):
if((course in self.sclass) == False):
if not (course in str(self.classes)):
print(course + " not a class.")
return
path = self.username + "/Students/" + course
@ -497,9 +632,9 @@ class Teacher:
os.chdir(cdir)
def getCommits(self, student, course, commits):
course = getDB("http://127.0.0.1:8000/api/classes/" + course)
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + course)
try:
if((student in course['confirmed']) == False):
if not (student in course['confirmed']):
print("Student not in class")
return
except:
@ -508,19 +643,20 @@ class Teacher:
cdir = os.getcwd()
os.chdir(self.username + "/Students/" + course['name'] + "/" + student)
process = subprocess.Popen(['git', 'log', '-' + str(commits), course['name']], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process = subprocess.Popen(['git', 'log', '-' + str(commits), course['name']], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p = process.poll()
output = process.communicate()[0].decode('utf-8').split('\n\n')
months = ['Jan', 'Feb', 'Mar', "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"]
fout = []
for i in range(len(output)):
if("Date" in output[i]):
if "Date" in output[i]:
c = output[i].split("\n")
for k in range(len(c)):
temp = []
if('commit' in c[k]):
if 'commit' in c[k]:
c[k] = c[k].replace('commit', '').strip()
elif('Date:' in c[k]):
elif 'Date:' in c[k]:
c[k] = c[k].replace('Date:', '').strip()
date = c[2].split(" ")
times = date[3].split(":")
@ -538,7 +674,13 @@ class Teacher:
return fout
def getChanges(self, student, course, commits):
course = getDB("http://127.0.0.1:8000/api/classes/" + course + "/")
"""
Checks for new submissions by a student
:param student: the student
:param course: the course
:param commits: commits the CLI has made for the assignment
"""
course = getDB(self.username, self.password, "http://127.0.0.1:8000/api/classes/" + course + "/")
ar = self.getCommits(student, course['name'], commits)
commit = ar[len(ar) - 1][0]
start = ""
@ -546,7 +688,8 @@ class Teacher:
print("START: " + start)
cdir = os.getcwd()
os.chdir(self.username + "/Students/" + course['name'] + "/" + student)
process = subprocess.Popen(['git', 'diff', commit, '--name-status'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process = subprocess.Popen(['git', 'diff', commit, '--name-status'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p = process.poll()
output = process.communicate()[0].decode('utf-8')
print(output)
@ -559,16 +702,17 @@ class Teacher:
}
'''
# check if assignment changed after due date
def afterSubmit(self, course, assignment, student):
assignment = getDB("http://127.0.0.1:8000/api/assignments/" + assignment)
assignment = getDB(self.username, self.password, "http://127.0.0.1:8000/api/assignments/" + assignment)
# assignment = {
# 'name': assignment,
# 'due_date': "2020-04-11 16:58:33.383124",
# 'classes':course
# }
log = self.getCommits(student, course, 30)
assignment['due_date'] = datetime.strptime(assignment['due_date'], '%Y-%m-%d %H:%M:%S.%f')
assignment['due_date'] = datetime.strptime(assignment['due_date'], '%Y-%m-%dT%H:%M:%S.%fZ')
late = False
cdir = os.getcwd()
os.chdir(self.username + "/Students/" + course + "/" + student)
@ -576,11 +720,11 @@ class Teacher:
process = subprocess.Popen(['git', 'show', l[0]], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p = process.poll()
output = process.communicate()[0].decode('utf-8')
if(assignment['name'] in output):
if assignment['name'] in output:
print(l[1])
print(assignment['due_date'])
print("--------------")
if(l[1] > assignment['due_date']):
if l[1] > assignment['due_date']:
print("LATE")
os.chdir(cdir)
return True
@ -589,11 +733,16 @@ class Teacher:
return False
def comment(self):
"""
The ultimate form of laughter
:return: pure joy
"""
print("heheheh")
# data = getTeacher("eharris1")
# t = Teacher(data)
# data = getTeacher("eharris1","PWD")
# print(data)
#t = Teacher(data, "PWD")
# t.makeClass("APLit_eharris1")
# t.updateAssignment("eharris1/APLit_eharris1/BookReport", "APLit_eharris1", '2020-08-11 16:58:33.383124')
# ar = ['2022rkhondak','2022inafi','2023rumareti']
@ -614,4 +763,3 @@ TO-DO
- check differences between commits
- check if student changes file after submissionn deadline
'''

View File

@ -8,6 +8,7 @@ class Student(models.Model):
user = models.OneToOneField(User, blank=True, on_delete=models.CASCADE)
ion_user = models.CharField(max_length=100, primary_key=True)
grade = models.IntegerField(default=0, blank=True)
log = models.TextField(default="", 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)
@ -18,31 +19,32 @@ class Student(models.Model):
super(Student, self).save(*args, **kwargs)
def __str__(self):
return f"{self.user.username}'s Profile"
return f"{self.user.first_name} {self.user.last_name} ({self.user.username})"
class Assignment(models.Model):
owner = models.ForeignKey(User, null=True, blank=True, related_name='aowner', on_delete=models.CASCADE)
name=models.CharField(max_length=100, primary_key=True)
due_date=models.DateTimeField()
# files = models.ManyToManyField(DefFiles)
files=models.CharField(max_length=100, default="", blank=True)
path=models.CharField(max_length=100)
classes=models.CharField(max_length=100)
teacher=models.CharField(max_length=100)
path=models.CharField(max_length=100, default="", blank=True)
classes=models.CharField(max_length=100, default="", blank=True)
teacher=models.CharField(max_length=100, default="", blank=True)
def __str__(self):
return '%s' % (self.name)
return f'{self.name}'
class Class(models.Model):
owner = models.ForeignKey(User, null=True, blank=True, related_name='cowner', on_delete=models.CASCADE)
teacher = models.CharField(max_length=100)
teacher = models.CharField(max_length=100, blank=True)
subject = models.CharField(max_length=50, blank=True)
period = models.PositiveIntegerField(null=True, blank=True, default=0)
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)
description = models.CharField(default="Class Description", max_length=500, blank=True)
repo=models.URLField(default="", blank=True)
path=models.CharField(max_length=100, default="")
path=models.CharField(max_length=100, default="", blank=True)
assignments=models.ManyToManyField(Assignment, blank=True)
default_file=models.CharField(max_length=100, default="", blank=True)
confirmed=models.ManyToManyField(Student, blank=True, related_name='confirmed')
@ -60,7 +62,7 @@ class Class(models.Model):
return super(Class, self).save(*args, **kwargs)
def __str__(self):
return self.name
return f"{self.name}"
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
@ -69,7 +71,7 @@ class Teacher(models.Model):
ion_user=models.CharField(primary_key=True, max_length=100)
def __str__(self):
return f"{self.user.username}'s Profile"
return f"{self.user.first_name} {self.user.last_name} ({self.user.username})"
def save(self, *args, **kwargs):
super(Teacher, self).save(*args, **kwargs)

View File

@ -34,7 +34,7 @@ class ClassSerializer(serializers.ModelSerializer):
class Meta:
model = Class
# fields = ['url','name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner']
fields = ['name', 'repo','path','assignments',"teacher","default_file", 'confirmed', 'unconfirmed','owner']
fields = ['name', 'repo','path','subject','period','assignments',"teacher","default_file", 'confirmed', 'unconfirmed','owner']
class StudentSerializer(serializers.ModelSerializer):
# Class = ClassSerializer(many=True, read_only=True,allow_null=True)

View File

@ -1,6 +1,6 @@
from django import forms
from django.contrib.auth.models import User
from api.models import Student, Teacher
from api.models import Student, Teacher, Class, Assignment
import re
class UserUpdateForm(forms.ModelForm):
@ -26,3 +26,33 @@ class TeacherUpdateForm(forms.ModelForm):
class Meta:
model = Teacher
fields = ['git']
class ClassCreationForm (forms.ModelForm):
subject = forms.CharField(max_length=50)
period = forms.IntegerField(min_value=0, max_value=9)
description = forms.CharField(widget=forms.Textarea)
unconfirmed = forms.ModelMultipleChoiceField(queryset=Student.objects.all(), label="Invite students")
def clean_period(self):
pd = self.cleaned_data['period']
if pd < 1 or pd > 9:
raise forms.ValidationError("Invalid period")
return pd;
def __init__(self, *args, **kwargs):
super(ClassCreationForm, self).__init__(*args, **kwargs)
self.fields['period'].widget.attrs['min'] = 0
# Only in case we build the form from an instance
# (otherwise, 'unconfirmed' list should be empty)
if kwargs.get('instance'):
# We get the 'initial' keyword argument or initialize it
# as a dict if it didn't exist.
initial = kwargs.setdefault('initial', {})
# The widget for a ModelMultipleChoiceField expects
# a list of primary key for the selected data.
initial['unconfirmed'] = [t.pk for t in kwargs['instance'].unconfirmed.all()]
class Meta:
model = Class
fields = ['subject', 'period', 'description', 'unconfirmed']

View File

@ -92,3 +92,13 @@ a.article-title:hover {
.account-heading {
font-size: 2.5rem;
}
.class-card {
text-decoration: none;
color: gray;
}
.class-card:hover {
text-decoration: none;
color: black;
}

View File

@ -34,6 +34,11 @@
<!-- Navbar Right Side -->
<div class="navbar-nav">
{% if user.is_authenticated %}
{% if isTeacher %}
<a class="nav-item nav-link" href="{% url 'create-class' %}">Create Class</a>
{% else %}
{% endif %}
<a class="nav-item nav-link" href="{% url 'profile' %}">{{ user.username }}</a>
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% endif %}

View File

@ -11,6 +11,12 @@
<small class="text-muted">Due: {{ assignment.due_date|date:"F d, Y" }}</small>
</div>
</article>
{% empty %}
{% if isTeacher %}
<p class="mr-2">Looks like you haven't made any assignments yet, hit the button in the top right to get started</p>
{% else %}
<p class="mr-2">Looks like there aren't any assignments at the moment, you got lucky this time!</p>
{% endif %}
{% endfor %}
</div>
@ -20,6 +26,8 @@
<ul>
{% for teacher in teachers %}
<li>{{ teacher.user.first_name }} {{ teacher.user.last_name }} ({{teacher.ion_user}})</li>
{% empty %}
<li>No Teachers, weird...</li>
{% endfor %}
</ul>
</div>

View File

@ -0,0 +1,26 @@
{% extends "skoolos/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<legend class="border-bottom mb-4">Classes</legend>
<ul>
{% for class in classes %}
<li>{{ class.name }}</li>
{% empty %}
<li>Not teaching any classes</li>
{% endfor %}
</ul>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Create a new class </legend>
{{ classForm|crispy }}
<!-- mmmm crispy yummm -->
<small class="text-secondary">Use ctrl to select multiple students</small>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-info">Create</button>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -3,13 +3,25 @@
<div class="content-section">
{% for class in classes %}
<div class="card-columns">
<a class="card" href="/class/{{ class.id }}" style="text-decoration: none;">
<a class="card class-card" href="/class/{{ class.id }}" style="">
<div class="card-body">
<h5 class="card-title">{{ class.name }}</h5>
<h5 class="card-title">{{ class.subject }}</h5>
{% if class.period != 0 %}
<small>Period: {{ class.period }}<br></small>
{% endif %}
{% if class.name %}
<small style="font-size:.75em"><i>{{ class.name }}</i></small>
{% endif %}
<p class="card-text">{{ class.description }}</p>
</div>
</a>
</div>
{% empty %}
{% if isTeacher %}
<p>Looks like you haven't created any classes yet, hit the button in the top right to get started.</p>
{% else %}
<p>Looks like you're not enrolled in any classes at the moment! Ask your teacher if you think this is wrong.</p>
{% endif %}
{% endfor %}
</div>
{% endblock content %}

View File

@ -5,6 +5,7 @@
<div class="media">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">Student</p>
<large>{{ user.first_name }} {{ user.last_name }}</large>
<p class="text-secondary">
{{ user.email }}
@ -16,6 +17,8 @@
<ul>
{% for class in classes %}
<li>{{ class.name }}</li>
{% empty %}
<li>No classes</li>
{% endfor %}
</ul>
<form method="post" enctype="multipart/form-data">

View File

@ -5,6 +5,7 @@
<div class="media">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">Teacher</p>
<large>{{ user.first_name }} {{ user.last_name }}</large>
<p class="text-secondary">
{{ user.email }}
@ -16,6 +17,8 @@
<ul>
{% for class in classes %}
<li>{{ class.name }}</li>
{% empty %}
<li>Not teaching any classes</li>
{% endfor %}
</ul>
<form method="post" enctype="multipart/form-data">

View File

@ -7,4 +7,5 @@ urlpatterns = [
path('', views.home, name='home'),
path('profile/', views.profile, name='profile'),
path("class/<str:id>", views.classDetail, name="class"),
path("create-class/", views.createClass, name="create-class"),
]

View File

@ -5,7 +5,12 @@ from django.contrib import messages
from django.contrib.auth.models import User
from .forms import UserUpdateForm, StudentUpdateForm, TeacherUpdateForm
from .forms import (
UserUpdateForm,
StudentUpdateForm,
TeacherUpdateForm,
ClassCreationForm,
)
from api.models import Student, Teacher, Class, Assignment
@ -14,14 +19,14 @@ from api.models import Student, Teacher, Class, Assignment
@login_required()
def home (request):
try:
student = Student.objects.get(user=request.user)
return render(request, "skoolos/home.html", {'classes': student.confirmed.all()})
student = request.user.student
return render(request, "skoolos/home.html", {'classes': student.confirmed.all(), 'isTeacher': False})
except Student.DoesNotExist:
pass
try:
teacher = Teacher.objects.get(user=request.user)
return render(request, "skoolos/home.html", {'classes': teacher.classes.all()})
teacher = request.user.teacher
return render(request, "skoolos/home.html", {'classes': teacher.classes.all(), 'isTeacher': True})
except Teacher.DoesNotExist:
pass
@ -36,38 +41,37 @@ def classDetail (request, id):
classObj = Class.objects.get(id=id)
try:
student = Student.objects.get(user=request.user)
student = request.user.student
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()})
return render(request, "skoolos/class_detail.html", {'class': classObj,'assignments': classObj.assignments.all(), 'teachers': classObj.classes.all(), 'isTeacher': False})
try:
teacher = Teacher.objects.get(user=request.user)
return render(request, "skoolos/home.html", {'classes': teacher.classes.all()})
teacher = request.user.teacher
except Teacher.DoesNotExist:
pass
else:
if classObj.confirmed.filter(user=student.user).count() != 1:
if teacher.classes.filter(id=classObj.id).count() != 1:
return redirect('/')
else:
return render(request, "skoolos/class_detail.html", {'class': classObj,'assignments': classObj.assignments.all(), 'teachers': classObj.classes.all()})
return render(request, "skoolos/class_detail.html", {'class': classObj,'assignments': classObj.assignments.all(), 'teachers': classObj.classes.all(), 'isTeacher': True})
return redirect('/')
@login_required()
def profile (request):
try:
student = Student.objects.get(user=request.user)
student = request.user.student
return student_profile(request)
except Student.DoesNotExist:
pass
try:
teacher = Teacher.objects.get(user=request.user)
teacher = request.user.teacher
return teacher_profile(request)
except Teacher.DoesNotExist:
pass
@ -91,7 +95,8 @@ def student_profile (request):
context = {
'userForm': userForm,
'profileForm': profileForm,
'classes': request.user.student.confirmed.all()
'classes': request.user.student.confirmed.all(),
'isTeacher': False,
}
return render(request, 'skoolos/profile_student.html', context)
@ -113,7 +118,55 @@ def teacher_profile (request):
context = {
'userForm': userForm,
'profileForm': profileForm,
'classes': request.user.teacher.classes.all()
'classes': request.user.teacher.classes.all(),
'isTeacher': True,
}
return render(request, 'skoolos/profile_teacher.html', context)
@login_required()
def createClass (request):
try:
teacher = request.user.teacher
except Teacher.DoesNotExist:
pass
else:
return createClassHelper(request)
return redirect('/')
def createClassHelper(request):
teacher = request.user.teacher
if request.method == "POST":
classForm = ClassCreationForm(request.POST)
if classForm.is_valid():
cleaned_data = classForm.clean()
print(cleaned_data)
newClass = classForm.save(commit=False)
newClass.owner = request.user
newClass.teacher = request.user.username
newClass.name = cleaned_data['subject'].replace(' ', '')[:8].lower() + str(cleaned_data['period']) + "_" + teacher.user.username.lower()
newClass.save()
classObj = classForm.save_m2m()
messages.success(request, cleaned_data['subject'].capitalize() + " has been created!")
print (newClass)
teacher.classes.add(newClass)
for student in newClass.unconfirmed.all():
if student.added_to == "":
student.added_to = newClass.name
else:
student.added_to = student.added_to + "," + newClass.name
student.save()
return redirect('home')
else:
classForm = ClassCreationForm()
context = {
'teacher': teacher,
'classes': teacher.classes.all(),
'classForm': classForm
}
return render(request, "skoolos/createClass.html", context)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,14 @@
"""
A simple background service to log events in a directory,
check for git commands in bash/zsh history,
and check for non-whitelisted files in the watched directory.
"""
import time
import sys
import os
import pyinotify
import checker
from pathlib import Path
class EventHandler(pyinotify.ProcessEvent):
@ -112,7 +118,7 @@ DIR = None
START_TIME = None
def watch_dir(watched_dir="/tmp", log_dir="/tmp/skooloslogs"):
def watch_dir(watched_dir=str(Path.home()), log_dir="SkoolOS/logs"):
"""
Watches the specified directory for changes and outputs it in
human readable format to a log file in the specified log directory.
@ -137,6 +143,7 @@ def watch_dir(watched_dir="/tmp", log_dir="/tmp/skooloslogs"):
NOTIFIER.start()
sys.stdout = open("/dev/null", 'w')
wm.add_watch(watched_dir, mask, rec=True)
time.sleep(1)
sys.stdout = logfile
print("Start time: " +
time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime()) + "\n")
@ -162,4 +169,3 @@ def stop_watching():
+ "The paths to these files are listed below:\n")
print(*suspicious_files, sep='\n')
sys.stdout = STDOUT
print("Done watching.\n")

3
bgservice/bgservice.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
python3 bgservice.py

2
bgservice/run.py Normal file
View File

@ -0,0 +1,2 @@
import bgservice as bg
bg.watch_dir()

View File

@ -1,2 +1,71 @@
Command Line Interface
=====================
1. Making a user:
-------
python skoolos.py
You will be redirected to a login page for the SkoolOS website. If you have already created an account on the website, enter login informatiton. If not, select
the registration button bellow and create an account. Once you create an account via Ion OAuth and SkoolOS, login. The window should close, prompting:
Enter SkoolOS Username:
Enter SkoolOS Password:
Enter the valid SkoolOS username and password. Congratialations, you have successfully logged in.
1. CLI as a teacher:
============
Start the CLI and select your username. For instance, teacher 'eharris1'
python skoolos.py
? Select User: (Use arrow keys)
1) 2022rkhondak
2) eharris1
3) Make new user
You will then be given the choice to select an existing class, Make a new class, or exit the CLI:
? Select class: (Use arrow keys)
Art12_eharris1
English12_eharris1
History12_eharris1
Make New Class
Exit SkoolOS
1. Making a new class:
-------
Select 'Make a New Class'. You will then be prompted to enter a class name. The format for every class must be <subject>_<teacher_username> (Example: Art12_eharris1).
Enter Period (must be a positive integer). You will then be prompted to add students. If you have a list of students, enter the relative path of a text file with the student usernames.
The file must be a .txt file and have one student username per line. If you add an individual student, simply enter their ion username.
one username per line.
? Select class: (Use arrow keys)
Art12_eharris1
English12_eharris1
History12_eharris1
Make New Class
Exit SkoolOS
? Add Students): (Use arrow keys)
1) Add individual student
2) Add list of students through path
3) Exit
? Add Students): 2) Add list of students through path
File must be .txt and have 1 student username per line
Relative Path: students.txt

View File

@ -1,7 +1,3 @@
.. SkoolOS documentation master file, created by
sphinx-quickstart on Tue Jun 16 11:22:02 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to SkoolOS's documentation!
===================================

View File

@ -1,2 +1,16 @@
Installation
============
Git clone repository:
-------
https://gitlab.tjhsst.edu/understudyathon-2020/group-1/schoolos.git
Install repository and create env
-------
cd SkoolOS
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt

View File

@ -1,7 +0,0 @@
kskskksks
kskskksks
kskskksks
kskskksks
kskskksks
kskskksks
kskskksks

View File

View File

@ -1,5 +1,6 @@
appdirs==1.4.3
cachecontrol==0.12.6
chromedriver==2.24.1
click==7.1.2
colorama==0.4.3
contextlib2==0.6.0
@ -52,20 +53,20 @@ yapf==0.30.0
# lazy-object-proxy==1.4.3 # Installed as dependency for astroid
# markupsafe==1.1.1 # Installed as dependency for jinja2
# mccabe==0.6.1 # Installed as dependency for pylint
# msgpack==0.6.2 # Installed as dependency for pynvim, cachecontrol
# oauthlib==3.1.0 # Installed as dependency for requests-oauthlib, django-oauth-toolkit
# msgpack==0.6.2 # Installed as dependency for cachecontrol, pynvim
# oauthlib==3.1.0 # Installed as dependency for django-oauth-toolkit, requests-oauthlib
# packaging==20.1 # Installed as dependency for sphinx
# pillow==7.1.2 # Installed as dependency for wpgtk
# prompt-toolkit==1.0.14 # Installed as dependency for pyinquirer
# psycopg2-binary==2.8.5 # Installed as dependency for django-request-token
# pygments==2.6.1 # Installed as dependency for sphinx, pyinquirer
# pygments==2.6.1 # Installed as dependency for pyinquirer, sphinx
# pyjwt==1.7.1 # Installed as dependency for django-request-token
# pyparsing==2.4.6 # Installed as dependency for packaging
# pytz==2020.1 # Installed as dependency for django, babel
# pytz==2020.1 # Installed as dependency for babel, django
# pywal==3.3.0 # Installed as dependency for wpgtk
# regex==2020.5.14 # Installed as dependency for pyinquirer
# requests==2.23.0 # Installed as dependency for cachecontrol, requests-oauth, django-oauth-toolkit, sphinx, requests-oauthlib
# six==1.15.0 # Installed as dependency for astroid, prompt-toolkit, html5lib, retrying, packaging
# requests==2.23.0 # Installed as dependency for cachecontrol, requests-oauthlib, django-oauth-toolkit, sphinx, requests-oauth
# six==1.15.0 # Installed as dependency for prompt-toolkit, astroid, retrying, html5lib, packaging
# snowballstemmer==2.0.0 # Installed as dependency for sphinx
# sphinxcontrib-applehelp==1.0.2 # Installed as dependency for sphinx
# sphinxcontrib-devhelp==1.0.2 # Installed as dependency for sphinx
@ -73,9 +74,9 @@ yapf==0.30.0
# sphinxcontrib-jsmath==1.0.1 # Installed as dependency for sphinx
# sphinxcontrib-qthelp==1.0.3 # Installed as dependency for sphinx
# sphinxcontrib-serializinghtml==1.1.4 # Installed as dependency for sphinx
# sqlparse==0.3.1 # Installed as dependency for django, django-request-token
# sqlparse==0.3.1 # Installed as dependency for django-request-token, django
# toml==0.10.0 # Installed as dependency for pylint, pep517
# urllib3==1.25.9 # Installed as dependency for selenium, requests
# urllib3==1.25.9 # Installed as dependency for requests, selenium
# wcwidth==0.2.3 # Installed as dependency for prompt-toolkit
# webencodings==0.5.1 # Installed as dependency for html5lib
# wrapt==1.12.1 # Installed as dependency for astroid

1
rushilwiz Submodule

@ -0,0 +1 @@
Subproject commit b80d7ed56b7d649a74be4e7f906d26e7be43702d

View File

@ -1,3 +1,6 @@
"""
The main program file for SkoolOS
"""
import sys
from urllib.parse import urlparse
import requests
@ -25,7 +28,12 @@ scope = ["read"]
USER = ""
PWD = ""
def main():
"""
The Command Line Interface (CLI) for SkoolOS
Serves to allow both teachers and students to access the majority of the features of SkoolOS
"""
print("")
print("░██████╗██╗░░██╗░█████╗░░█████╗░██╗░░░░░  ░█████╗░░██████╗")
print("██╔════╝██║░██╔╝██╔══██╗██╔══██╗██║░░░░░  ██╔══██╗██╔════╝")
@ -35,7 +43,9 @@ def main():
print("╚═════╝░╚═╝░░╚═╝░╚════╝░░╚════╝░╚══════╝  ░╚════╝░╚═════╝░")
print("")
if not (os.path.exists(".sprofile") or os.path.exists(".tprofile")):
profiles = os.listdir()
if not ("profile" in str(profiles)):
try:
URL = "http://127.0.0.1:8000/api/"
r = requests.get(url=URL)
@ -46,32 +56,73 @@ def main():
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:
f = open('.tprofile','r')
except:
f = open('.sprofile','r')
data = json.loads(f.read())
profiles = os.listdir()
users = []
info = []
count = 1
for i in range(len(profiles)):
p = profiles[i]
if 'profile' in p:
f = open(p, 'r')
d = json.loads(f.read())
f.close()
info.append(d)
users.append(str(count) + ") " + d['username'])
count = count + 1
users.append(str(count) + ") Make new user")
user = [
{
'type': 'list',
'name': 'user',
'choices': users,
'message': 'Select User: ',
},
]
u = int(prompt(user)['user'].split(")")[0]) - 1
if u + 1 == count:
authenticate()
return
data = info[u]
PWD = data['password']
USER = data['username']
print(data['username'])
if(data['is_student']):
if data['is_student']:
studentCLI(USER, PWD)
else:
teacherCLI(USER, PWD)
# while True:
# pass
#################################################################################################### STUDENT METHODS
def studentCLI(user, password):
"""
The CLI for students to access
@param user: student username
@param password: student password
"""
from CLI import student
data = getUser(user, password, 'student')
student = student.Student(data)
carray = student.sclass.split(",")
if(len(carray) == 1 and carray[0] == ""):
print("No classes")
student = student.Student(data, password)
student.update()
EXIT = False
while not EXIT:
course = chooseClassStudent(student)
if course == "Exit SkoolOS":
return
EXIT = classOptionsStudent(student, course)
# return class
def chooseClassStudent(student):
"""
Chooses a class for a student to view and work on
@param student: a student
:return: a course prompt
"""
carray = student.sclass.split(",")
if len(carray) == 1 and carray[0] == "":
carray.remove("")
print("No classes")
carray.append("Exit SkoolOS")
courses = [
@ -84,25 +135,115 @@ def studentCLI(user, password):
]
course = prompt(courses)['course']
print(course)
if course == "Exit SkoolOS":
student.exitCLI()
else:
return course
def classOptionsStudent(student, course):
"""
Allows students to choose what they want to do related to a class
The student can save, exit, or go back
@param student: a student
@param course: a course
:return: True if exiting, False if going back
"""
student.viewClass(course)
student.getAssignments(course, 100)
choices = ["Save","Submit assignment","Back","Exit SkoolOS"]
options = [
{
'type': 'list',
'name': 'option',
'choices': choices,
'message': 'Select: ',
},
]
option = prompt(options)['option']
if option == "Save":
student.update()
print("Saved!")
classOptionsStudent(student, course)
if option == "Back":
student.exitCLI()
# dont exit cli
return False
if option == "Exit SkoolOS":
student.exitCLI()
# exit cli
return True
if(option == "Submit assignment"):
assignments = os.listdir(student.username)
tlist = []
b = True
for a in assignments:
oname = a + "_" + course
a = student.username + "/" + a
if(os.path.isdir(a) and not "." in a and not oname in student.completed):
tlist.append(a)
assignments = tlist
assignments.append("Back")
print(assignments)
options = [
{
'type': 'list',
'name': 'submit',
'choices':assignments,
'message': 'Select: ',
},
]
ass = prompt(options)['submit']
if(ass == "Back"):
return False
else:
student.submit(course, ass)
return False
#################################################################################################### TEACHER METHODS
def teacherCLI(user, password):
"""
The CLI for teachers to access
@param user: teachers username
@param password: teachers password
"""
from CLI import teacher
data = getUser(user, password, 'teacher')
print(data)
teacher = teacher.Teacher(data)
teacher = teacher.Teacher(data, password)
EXIT = False
# 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.classes
carray.append("Exit SkoolOS")
while not EXIT:
# Options: '1) Request Student', "2) Add assignment", "3) View student information", "4) Exit"
course = chooseGeneralTeacher(teacher)
if course == "Exit SkoolOS":
EXIT = True
elif course == "Make New Class":
EXIT = makeClassTeacher(teacher)
# selected a class
else:
#Pull confirmed students directory
teacher.getStudents(course)
option = classOptionsTeacher(teacher, course)
if option == '1':
EXIT = addStudentsTeacher(teacher, course)
elif option == '2':
EXIT = addAssignmentTeacher(teacher, course)
elif option == '3':
EXIT = viewStudentsTeacher(teacher, course)
else:
EXIT = True
def chooseGeneralTeacher(teacher):
carray = []
for c in teacher.classes:
carray.append(c)
carray.append("Make New Class")
carray.append("Exit SkoolOS")
courses = [
{
'type': 'list',
@ -112,17 +253,30 @@ def teacherCLI(user, password):
},
]
course = prompt(courses)['course']
if course == "Exit SkoolOS":
teacher.exitCLI()
if course == "Make New Class":
return course
def makeClassTeacher(teacher):
questions = [
{
'type': 'input',
'name': 'cname',
'message': 'Class Name: ',
'message': 'Class Name (Must be: <subject>_<ion_user>): ',
},
]
cname = prompt(questions)['cname']
print(cname)
while not ("_" + teacher.username) in cname:
print("Incorrect naming format")
questions = [
{
'type': 'input',
'name': 'cname',
'message': 'Class Name (Must be: <subject>_<ion_user>): ',
},
]
cname = prompt(questions)['cname']
teacher.makeClass(cname)
soption = ["1) Add individual student", "2) Add list of students through path", "3) Exit"]
questions = [
@ -130,24 +284,33 @@ def teacherCLI(user, password):
'type': 'list',
'choices': soption,
'name': 'students',
'message': 'Add list of students (input path): ',
'message': 'Add Students): ',
},
]
choice = prompt(questions)['students'].split(")")[0]
if("1" == choice):
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.")
if "2" == choice:
print("File must be .txt and have 1 student username per line")
path = input("Relative Path: ")
while not os.path.exists(path):
if path == 'N':
return True
print(path + " is not a valid path")
path = input("Enter file path ('N' to exit): ")
f = open(path, 'r')
students = f.read().splitlines()
teacher.reqAddStudentList(students, cname)
return False
else:
def classOptionsTeacher(teacher, course):
print("Class: " + course)
unconf = getDB("http://localhost:8000/api/classes/" + course)['unconfirmed']
unconf = getDB(teacher.username, teacher.password, "http://localhost:8000/api/classes/" + course)['unconfirmed']
for s in unconf:
teacher.addStudent()
options = ['1) Request Student', "2) Add assignment", "3) View student information"]
teacher.addStudent(s, course)
options = ['1) Request Student', "2) Add assignment", "3) View student information", "4) Exit"]
questions = [
{
'type': 'list',
@ -157,7 +320,10 @@ def teacherCLI(user, password):
},
]
option = prompt(questions)['course'].split(")")[0]
if(option == '1'):
return option
def addStudentsTeacher(teacher, course):
soption = ["1) Add individual student", "2) Add list of students through path", "3) Exit"]
questions = [
{
@ -168,7 +334,7 @@ def teacherCLI(user, password):
},
]
schoice = prompt(questions)['students'].split(")")[0]
if(schoice == '1'):
if schoice == '1':
questions = [
{
'type': 'input',
@ -178,7 +344,8 @@ def teacherCLI(user, password):
]
s = prompt(questions)['student']
teacher.reqStudent(s, course)
if(schoice == '2'):
return False
if schoice == '2':
questions = [
{
'type': 'input',
@ -187,19 +354,22 @@ def teacherCLI(user, password):
},
]
path = prompt(questions)['path']
while(not os.path.exists(path)):
if(path == 'N'):
while not os.path.exists(path):
if path == 'N':
sys.exit(0)
print(path + " is not a valid path")
path = input("Enter file path ('N' to exit): ")
f = open(path, 'r')
students = f.read().splitlines()
teacher.reqAddStudentList(students, course)
return False
else:
sys.exit()
if(option == '2'):
return True
def addAssignmentTeacher(teacher, course):
nlist = os.listdir(teacher.username + "/" + course)
alist = getDB("http://localhost:8000/api/classes/" + course)['assignments']
alist = getDB(teacher.username, teacher.password, "http://localhost:8000/api/classes/" + course)['assignments']
print(nlist)
tlist = []
b = True
@ -207,19 +377,20 @@ def teacherCLI(user, password):
b = True
print(teacher.username + "/" + course + "/" + n)
for a in alist:
if(n in a or n == a):
if n in a or n == a:
# print("Assignments: " + n)
b = False
if(not os.path.isdir(teacher.username + "/" + course + "/" + n)):
if not os.path.isdir(teacher.username + "/" + course + "/" + n):
b = False
if(b):
if b:
tlist.append(n)
nlist = tlist
if(len(nlist) == 0):
if len(nlist) == 0:
print("No new assignments found")
sys.exit(0)
print(
"To make an assignment: make a subdirectory in the " + course + " folder. Add a file within the new folder")
return False
questions = [
{
'type': 'list',
@ -231,57 +402,164 @@ def teacherCLI(user, password):
ass = prompt(questions)['assignment']
apath = teacher.username + "/" + course + "/" + ass
due = input("Enter due date (Example: 2020-08-11 16:58): ")
due = due + ":00.000000"
due = due + ":33.383124"
due = due.strip()
f = False
while not f:
try:
datetime.datetime.strptime(due, '%Y-%m-%d %H:%M:%S.%f')
f = True
except:
print("Due-date format is incorrect.")
print(due)
due = input("Enter due date (Example: 2020-08-11 16:58): ")
due = due + ":33.383124"
teacher.addAssignment(apath, course, due)
return False
def viewStudentsTeacher(teacher, course):
data = getDB(teacher.username, teacher.password, "http://127.0.0.1:8000/api/classes/" + course)
students = data["confirmed"]
unconf = data['unconfirmed']
print("Studented in class: ")
for s in students:
print(s)
print("Requsted Students: ")
for s in unconf:
print(s)
student = input("View student (Enter student's ion username): ")
while((not student in str(data['confirmed'])) and (not student in str(data['unconfirmed']))):
print("Student not affiliated with class")
student = input("View student ('N' to exit): ")
if student == 'N':
return False
sinfo = getDB(teacher.username, teacher.password, "http://127.0.0.1:8000/api/students/" + student + "/")
pprint.pprint(sinfo)
print("Confirmed: " + str(student in str(data['confirmed'])))
if(student in str(data['confirmed'])):
path = teacher.username + "/Students/" + course + "/" + student
print(student + "'s work: " + path)
fin = sinfo['completed'].split(",")
alist = []
for f in fin:
if(course in f):
late = teacher.afterSubmit(course, f, student)
if(late):
s = f.split("_")[0] + " (LATE)"
else:
s = f.split("_")[0]
alist.append(s)
print("Has submitted: " + str(alist))
#put log stuff
############################################################################################################################################
def getUser(ion_user, password, utype):
if('student' in utype):
"""
Returns user information
@param ion_user: user
@param password: user's password
@param utype: type of user (student or teacher
:return: api user information
"""
if 'student' in utype:
URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/"
else:
URL = "http://127.0.0.1:8000/api/teachers/" + ion_user + "/"
print(URL)
r = requests.get(url=URL, auth=(ion_user, password))
print(r.json())
if(r.status_code == 200):
if r.status_code == 200:
data = r.json()
print(200)
return data
elif(r.status_code == 404):
elif r.status_code == 404:
print("Make new account!")
return None
elif(r.status_code == 403):
elif r.status_code == 403:
print("Invalid username/password")
return None
else:
print(r.status_code)
return None
def patchDB(data, url):
r = requests.patch(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
def patchDB(USER, PWD, url, data):
"""
Sends a PATCH request to url
@param USER: username
@param PWD: password
@param url: URL for request
@param data: data to request
:return: json request response
"""
r = requests.patch(url=url, data=data, auth=(USER, PWD))
print("PATH:" + str(r.status_code))
return(r.json())
return r.json()
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
def getDB(USER, PWD, url):
"""
Sends a GET request to url
@param USER: username
@param PWD: password
@param url: URL for request
:return: json request response
"""
r = requests.get(url=url, auth=(USER, PWD))
print("GET:" + str(r.status_code))
return(r.json())
return r.json()
def postDB(data, url):
r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
def postDB(USER, PWD, url, data):
"""
Sends a POST request to url
@param USER: username
@param PWD: password
@param url: URL for request
@param data: data to request
:return: json request response
"""
r = requests.post(url=url, data=data, auth=(USER, PWD))
print("POST:" + str(r.status_code))
return(r.json())
return r.json()
def putDB(data, url):
r = requests.put(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
def putDB(USER, PWD, url, data):
"""
Sends a PUT request to url
@param USER: username
@param PWD: password
@param url: URL for request
@param data: data to request
:return: json request response
"""
r = requests.put(url=url, data=data, auth=(USER, PWD))
print("PUT:" + str(r.status_code))
return(r.json())
return r.json()
def delDB(url):
r = requests.delete(url = url, auth=('raffukhondaker','hackgroup1'))
def delDB(USER, PWD, url):
"""
Sends a DELETE request to url
@param USER: username
@param PWD: password
@param url: URL for request
:return: json request response
"""
r = requests.delete(url=url, auth=(USER, PWD))
print("DELETE:" + str(r.status_code))
return None
def makePass():
"""
Prompts the user to create a password
:return: the password
"""
questions = [
{
'type': 'password',
@ -290,7 +568,7 @@ def makePass():
},
]
pwd = prompt(questions)['pwd']
while(len(pwd) < 7):
while len(pwd) < 7:
print("Password too short (Must be over 6 characters)")
pwd = prompt(questions)['pwd']
conf = [
@ -301,25 +579,37 @@ def makePass():
},
]
pwd2 = prompt(conf)['pwd']
while(not pwd == pwd2):
while not pwd == pwd2:
print("Passwords do not match.")
pwd2 = prompt(conf)['pwd']
else:
print("PASSWORD SAVED")
return pwd
def authenticate():
"""
Authenticates the user via Ion OAuth
"""
oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
import os
cdir = os.getcwd()
# Linux: chromdriver-linux
# Macos: chromdriver-mac
# Windows: chromdriver.exe
if('CLI' in os.getcwd()):
path = os.path.join(os.getcwd(), '../','chromedriver-mac')
else:
path = os.path.join(os.getcwd(), 'chromedriver-mac')
print("OS: ")
print("MacOS")
print("Linux")
system = input("Enter OS: ")
while(system.lower() != "linux" and system.lower() != "macos"):
print("Not valid OS")
system = input("Enter OS: ")
if(system.lower() == 'macos'):
path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-mac')
if(system.lower() == 'linux'):
path = os.path.join(os.getcwd(), 'chromedriver', 'chromedriver-linux')
browser = webdriver.Chrome(path)
@ -330,7 +620,8 @@ def authenticate():
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/
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
@ -356,7 +647,7 @@ def authenticate():
pwd = data['pwd']
user = data['username']
r = requests.get(url="http://localhost:8000/api/", auth=(user, pwd))
while(r.status_code != 200):
while r.status_code != 200:
print("INCORRECT LOGIN CREDENTIALS")
r = requests.get(url="http://localhost:8000/api/", auth=(user, pwd))
data = prompt(questions)
@ -365,7 +656,7 @@ def authenticate():
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):
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))
@ -378,7 +669,8 @@ def authenticate():
'is_student': is_student,
'password': pwd,
}
profileFile = open(".sprofile", "w")
fname = "." + username + "profile"
profileFile = open(fname, "w")
profileFile.write(json.dumps(profile))
profileFile.close()
@ -392,18 +684,24 @@ def authenticate():
'is_student': is_student,
'password': pwd,
}
profileFile = open(".tprofile", "w")
fname = "." + username + "profile"
profileFile = open(fname, "w")
profileFile.write(json.dumps(profile))
profileFile.close()
sys.exit
sys.exit(0)
def create_server():
"""
Creates a simple HTTP server for creating api requests from the CLI
"""
port = 8000
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
print("serving at port:" + str(port))
httpd.serve_forever()
if __name__ == "__main__":
main()

105
snew.py
View File

@ -1,105 +0,0 @@
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())
import bgservice.bgservice as bg
bg.watch_dir('2022rkhondak', 'eharris1')
time.sleep(60)
bg.stop_watching()

View File

@ -0,0 +1 @@
Subproject commit ca356ef8532873bf52ec67a647fbb91a25ca1cb7

View File

View File

@ -1 +1,2 @@
2022rkhondak
2023rmama